]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blob - net/core/devlink.c
devlink: Rework devlink health reporter destructor
[mirror_ubuntu-hirsute-kernel.git] / net / core / devlink.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * net/core/devlink.c - Network physical/parent device Netlink interface
4 *
5 * Heavily inspired by net/wireless/
6 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
7 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
8 */
9
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/types.h>
13 #include <linux/slab.h>
14 #include <linux/gfp.h>
15 #include <linux/device.h>
16 #include <linux/list.h>
17 #include <linux/netdevice.h>
18 #include <linux/spinlock.h>
19 #include <linux/refcount.h>
20 #include <linux/workqueue.h>
21 #include <linux/u64_stats_sync.h>
22 #include <linux/timekeeping.h>
23 #include <rdma/ib_verbs.h>
24 #include <net/netlink.h>
25 #include <net/genetlink.h>
26 #include <net/rtnetlink.h>
27 #include <net/net_namespace.h>
28 #include <net/sock.h>
29 #include <net/devlink.h>
30 #include <net/drop_monitor.h>
31 #define CREATE_TRACE_POINTS
32 #include <trace/events/devlink.h>
33
34 static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
35 {
36 .name = "destination mac",
37 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
38 .bitwidth = 48,
39 },
40 };
41
42 struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
43 .name = "ethernet",
44 .id = DEVLINK_DPIPE_HEADER_ETHERNET,
45 .fields = devlink_dpipe_fields_ethernet,
46 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
47 .global = true,
48 };
49 EXPORT_SYMBOL(devlink_dpipe_header_ethernet);
50
51 static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
52 {
53 .name = "destination ip",
54 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
55 .bitwidth = 32,
56 },
57 };
58
59 struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
60 .name = "ipv4",
61 .id = DEVLINK_DPIPE_HEADER_IPV4,
62 .fields = devlink_dpipe_fields_ipv4,
63 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
64 .global = true,
65 };
66 EXPORT_SYMBOL(devlink_dpipe_header_ipv4);
67
68 static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
69 {
70 .name = "destination ip",
71 .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
72 .bitwidth = 128,
73 },
74 };
75
76 struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
77 .name = "ipv6",
78 .id = DEVLINK_DPIPE_HEADER_IPV6,
79 .fields = devlink_dpipe_fields_ipv6,
80 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
81 .global = true,
82 };
83 EXPORT_SYMBOL(devlink_dpipe_header_ipv6);
84
85 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
86 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
87
88 static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = {
89 [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY },
90 };
91
92 static LIST_HEAD(devlink_list);
93
94 /* devlink_mutex
95 *
96 * An overall lock guarding every operation coming from userspace.
97 * It also guards devlink devices list and it is taken when
98 * driver registers/unregisters it.
99 */
100 static DEFINE_MUTEX(devlink_mutex);
101
102 struct net *devlink_net(const struct devlink *devlink)
103 {
104 return read_pnet(&devlink->_net);
105 }
106 EXPORT_SYMBOL_GPL(devlink_net);
107
108 static void __devlink_net_set(struct devlink *devlink, struct net *net)
109 {
110 write_pnet(&devlink->_net, net);
111 }
112
113 void devlink_net_set(struct devlink *devlink, struct net *net)
114 {
115 if (WARN_ON(devlink->registered))
116 return;
117 __devlink_net_set(devlink, net);
118 }
119 EXPORT_SYMBOL_GPL(devlink_net_set);
120
121 static struct devlink *devlink_get_from_attrs(struct net *net,
122 struct nlattr **attrs)
123 {
124 struct devlink *devlink;
125 char *busname;
126 char *devname;
127
128 if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
129 return ERR_PTR(-EINVAL);
130
131 busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
132 devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
133
134 lockdep_assert_held(&devlink_mutex);
135
136 list_for_each_entry(devlink, &devlink_list, list) {
137 if (strcmp(devlink->dev->bus->name, busname) == 0 &&
138 strcmp(dev_name(devlink->dev), devname) == 0 &&
139 net_eq(devlink_net(devlink), net))
140 return devlink;
141 }
142
143 return ERR_PTR(-ENODEV);
144 }
145
146 static struct devlink *devlink_get_from_info(struct genl_info *info)
147 {
148 return devlink_get_from_attrs(genl_info_net(info), info->attrs);
149 }
150
151 static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
152 unsigned int port_index)
153 {
154 struct devlink_port *devlink_port;
155
156 list_for_each_entry(devlink_port, &devlink->port_list, list) {
157 if (devlink_port->index == port_index)
158 return devlink_port;
159 }
160 return NULL;
161 }
162
163 static bool devlink_port_index_exists(struct devlink *devlink,
164 unsigned int port_index)
165 {
166 return devlink_port_get_by_index(devlink, port_index);
167 }
168
169 static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
170 struct nlattr **attrs)
171 {
172 if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
173 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
174 struct devlink_port *devlink_port;
175
176 devlink_port = devlink_port_get_by_index(devlink, port_index);
177 if (!devlink_port)
178 return ERR_PTR(-ENODEV);
179 return devlink_port;
180 }
181 return ERR_PTR(-EINVAL);
182 }
183
184 static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
185 struct genl_info *info)
186 {
187 return devlink_port_get_from_attrs(devlink, info->attrs);
188 }
189
190 struct devlink_sb {
191 struct list_head list;
192 unsigned int index;
193 u32 size;
194 u16 ingress_pools_count;
195 u16 egress_pools_count;
196 u16 ingress_tc_count;
197 u16 egress_tc_count;
198 };
199
200 static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
201 {
202 return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
203 }
204
205 static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
206 unsigned int sb_index)
207 {
208 struct devlink_sb *devlink_sb;
209
210 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
211 if (devlink_sb->index == sb_index)
212 return devlink_sb;
213 }
214 return NULL;
215 }
216
217 static bool devlink_sb_index_exists(struct devlink *devlink,
218 unsigned int sb_index)
219 {
220 return devlink_sb_get_by_index(devlink, sb_index);
221 }
222
223 static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
224 struct nlattr **attrs)
225 {
226 if (attrs[DEVLINK_ATTR_SB_INDEX]) {
227 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
228 struct devlink_sb *devlink_sb;
229
230 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
231 if (!devlink_sb)
232 return ERR_PTR(-ENODEV);
233 return devlink_sb;
234 }
235 return ERR_PTR(-EINVAL);
236 }
237
238 static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
239 struct genl_info *info)
240 {
241 return devlink_sb_get_from_attrs(devlink, info->attrs);
242 }
243
244 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
245 struct nlattr **attrs,
246 u16 *p_pool_index)
247 {
248 u16 val;
249
250 if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
251 return -EINVAL;
252
253 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
254 if (val >= devlink_sb_pool_count(devlink_sb))
255 return -EINVAL;
256 *p_pool_index = val;
257 return 0;
258 }
259
260 static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
261 struct genl_info *info,
262 u16 *p_pool_index)
263 {
264 return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
265 p_pool_index);
266 }
267
268 static int
269 devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
270 enum devlink_sb_pool_type *p_pool_type)
271 {
272 u8 val;
273
274 if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
275 return -EINVAL;
276
277 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
278 if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
279 val != DEVLINK_SB_POOL_TYPE_EGRESS)
280 return -EINVAL;
281 *p_pool_type = val;
282 return 0;
283 }
284
285 static int
286 devlink_sb_pool_type_get_from_info(struct genl_info *info,
287 enum devlink_sb_pool_type *p_pool_type)
288 {
289 return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
290 }
291
292 static int
293 devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
294 enum devlink_sb_threshold_type *p_th_type)
295 {
296 u8 val;
297
298 if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
299 return -EINVAL;
300
301 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
302 if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
303 val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
304 return -EINVAL;
305 *p_th_type = val;
306 return 0;
307 }
308
309 static int
310 devlink_sb_th_type_get_from_info(struct genl_info *info,
311 enum devlink_sb_threshold_type *p_th_type)
312 {
313 return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
314 }
315
316 static int
317 devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
318 struct nlattr **attrs,
319 enum devlink_sb_pool_type pool_type,
320 u16 *p_tc_index)
321 {
322 u16 val;
323
324 if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
325 return -EINVAL;
326
327 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
328 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
329 val >= devlink_sb->ingress_tc_count)
330 return -EINVAL;
331 if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
332 val >= devlink_sb->egress_tc_count)
333 return -EINVAL;
334 *p_tc_index = val;
335 return 0;
336 }
337
338 static int
339 devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
340 struct genl_info *info,
341 enum devlink_sb_pool_type pool_type,
342 u16 *p_tc_index)
343 {
344 return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
345 pool_type, p_tc_index);
346 }
347
348 struct devlink_region {
349 struct devlink *devlink;
350 struct list_head list;
351 const struct devlink_region_ops *ops;
352 struct list_head snapshot_list;
353 u32 max_snapshots;
354 u32 cur_snapshots;
355 u64 size;
356 };
357
358 struct devlink_snapshot {
359 struct list_head list;
360 struct devlink_region *region;
361 u8 *data;
362 u32 id;
363 };
364
365 static struct devlink_region *
366 devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
367 {
368 struct devlink_region *region;
369
370 list_for_each_entry(region, &devlink->region_list, list)
371 if (!strcmp(region->ops->name, region_name))
372 return region;
373
374 return NULL;
375 }
376
377 static struct devlink_snapshot *
378 devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
379 {
380 struct devlink_snapshot *snapshot;
381
382 list_for_each_entry(snapshot, &region->snapshot_list, list)
383 if (snapshot->id == id)
384 return snapshot;
385
386 return NULL;
387 }
388
389 #define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0)
390 #define DEVLINK_NL_FLAG_NEED_PORT BIT(1)
391 #define DEVLINK_NL_FLAG_NEED_SB BIT(2)
392
393 /* The per devlink instance lock is taken by default in the pre-doit
394 * operation, yet several commands do not require this. The global
395 * devlink lock is taken and protects from disruption by user-calls.
396 */
397 #define DEVLINK_NL_FLAG_NO_LOCK BIT(3)
398
399 static int devlink_nl_pre_doit(const struct genl_ops *ops,
400 struct sk_buff *skb, struct genl_info *info)
401 {
402 struct devlink *devlink;
403 int err;
404
405 mutex_lock(&devlink_mutex);
406 devlink = devlink_get_from_info(info);
407 if (IS_ERR(devlink)) {
408 mutex_unlock(&devlink_mutex);
409 return PTR_ERR(devlink);
410 }
411 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
412 mutex_lock(&devlink->lock);
413 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) {
414 info->user_ptr[0] = devlink;
415 } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
416 struct devlink_port *devlink_port;
417
418 devlink_port = devlink_port_get_from_info(devlink, info);
419 if (IS_ERR(devlink_port)) {
420 err = PTR_ERR(devlink_port);
421 goto unlock;
422 }
423 info->user_ptr[0] = devlink_port;
424 }
425 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) {
426 struct devlink_sb *devlink_sb;
427
428 devlink_sb = devlink_sb_get_from_info(devlink, info);
429 if (IS_ERR(devlink_sb)) {
430 err = PTR_ERR(devlink_sb);
431 goto unlock;
432 }
433 info->user_ptr[1] = devlink_sb;
434 }
435 return 0;
436
437 unlock:
438 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
439 mutex_unlock(&devlink->lock);
440 mutex_unlock(&devlink_mutex);
441 return err;
442 }
443
444 static void devlink_nl_post_doit(const struct genl_ops *ops,
445 struct sk_buff *skb, struct genl_info *info)
446 {
447 struct devlink *devlink;
448
449 /* When devlink changes netns, it would not be found
450 * by devlink_get_from_info(). So try if it is stored first.
451 */
452 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) {
453 devlink = info->user_ptr[0];
454 } else {
455 devlink = devlink_get_from_info(info);
456 WARN_ON(IS_ERR(devlink));
457 }
458 if (!IS_ERR(devlink) && ~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
459 mutex_unlock(&devlink->lock);
460 mutex_unlock(&devlink_mutex);
461 }
462
463 static struct genl_family devlink_nl_family;
464
465 enum devlink_multicast_groups {
466 DEVLINK_MCGRP_CONFIG,
467 };
468
469 static const struct genl_multicast_group devlink_nl_mcgrps[] = {
470 [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
471 };
472
473 static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
474 {
475 if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
476 return -EMSGSIZE;
477 if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
478 return -EMSGSIZE;
479 return 0;
480 }
481
482 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
483 enum devlink_command cmd, u32 portid,
484 u32 seq, int flags)
485 {
486 void *hdr;
487
488 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
489 if (!hdr)
490 return -EMSGSIZE;
491
492 if (devlink_nl_put_handle(msg, devlink))
493 goto nla_put_failure;
494 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed))
495 goto nla_put_failure;
496
497 genlmsg_end(msg, hdr);
498 return 0;
499
500 nla_put_failure:
501 genlmsg_cancel(msg, hdr);
502 return -EMSGSIZE;
503 }
504
505 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
506 {
507 struct sk_buff *msg;
508 int err;
509
510 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
511
512 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
513 if (!msg)
514 return;
515
516 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
517 if (err) {
518 nlmsg_free(msg);
519 return;
520 }
521
522 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
523 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
524 }
525
526 static int devlink_nl_port_attrs_put(struct sk_buff *msg,
527 struct devlink_port *devlink_port)
528 {
529 struct devlink_port_attrs *attrs = &devlink_port->attrs;
530
531 if (!devlink_port->attrs_set)
532 return 0;
533 if (attrs->lanes) {
534 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes))
535 return -EMSGSIZE;
536 }
537 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable))
538 return -EMSGSIZE;
539 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
540 return -EMSGSIZE;
541 switch (devlink_port->attrs.flavour) {
542 case DEVLINK_PORT_FLAVOUR_PCI_PF:
543 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
544 attrs->pci_pf.pf))
545 return -EMSGSIZE;
546 break;
547 case DEVLINK_PORT_FLAVOUR_PCI_VF:
548 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
549 attrs->pci_vf.pf) ||
550 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER,
551 attrs->pci_vf.vf))
552 return -EMSGSIZE;
553 break;
554 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
555 case DEVLINK_PORT_FLAVOUR_CPU:
556 case DEVLINK_PORT_FLAVOUR_DSA:
557 case DEVLINK_PORT_FLAVOUR_VIRTUAL:
558 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
559 attrs->phys.port_number))
560 return -EMSGSIZE;
561 if (!attrs->split)
562 return 0;
563 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
564 attrs->phys.port_number))
565 return -EMSGSIZE;
566 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
567 attrs->phys.split_subport_number))
568 return -EMSGSIZE;
569 break;
570 default:
571 break;
572 }
573 return 0;
574 }
575
576 static int
577 devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port,
578 struct netlink_ext_ack *extack)
579 {
580 struct devlink *devlink = port->devlink;
581 const struct devlink_ops *ops;
582 struct nlattr *function_attr;
583 bool empty_nest = true;
584 int err = 0;
585
586 function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION);
587 if (!function_attr)
588 return -EMSGSIZE;
589
590 ops = devlink->ops;
591 if (ops->port_function_hw_addr_get) {
592 int hw_addr_len;
593 u8 hw_addr[MAX_ADDR_LEN];
594
595 err = ops->port_function_hw_addr_get(devlink, port, hw_addr, &hw_addr_len, extack);
596 if (err == -EOPNOTSUPP) {
597 /* Port function attributes are optional for a port. If port doesn't
598 * support function attribute, returning -EOPNOTSUPP is not an error.
599 */
600 err = 0;
601 goto out;
602 } else if (err) {
603 goto out;
604 }
605 err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr);
606 if (err)
607 goto out;
608 empty_nest = false;
609 }
610
611 out:
612 if (err || empty_nest)
613 nla_nest_cancel(msg, function_attr);
614 else
615 nla_nest_end(msg, function_attr);
616 return err;
617 }
618
619 static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
620 struct devlink_port *devlink_port,
621 enum devlink_command cmd, u32 portid,
622 u32 seq, int flags,
623 struct netlink_ext_ack *extack)
624 {
625 void *hdr;
626
627 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
628 if (!hdr)
629 return -EMSGSIZE;
630
631 if (devlink_nl_put_handle(msg, devlink))
632 goto nla_put_failure;
633 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
634 goto nla_put_failure;
635
636 spin_lock_bh(&devlink_port->type_lock);
637 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
638 goto nla_put_failure_type_locked;
639 if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
640 nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
641 devlink_port->desired_type))
642 goto nla_put_failure_type_locked;
643 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
644 struct net_device *netdev = devlink_port->type_dev;
645
646 if (netdev &&
647 (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
648 netdev->ifindex) ||
649 nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
650 netdev->name)))
651 goto nla_put_failure_type_locked;
652 }
653 if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
654 struct ib_device *ibdev = devlink_port->type_dev;
655
656 if (ibdev &&
657 nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
658 ibdev->name))
659 goto nla_put_failure_type_locked;
660 }
661 spin_unlock_bh(&devlink_port->type_lock);
662 if (devlink_nl_port_attrs_put(msg, devlink_port))
663 goto nla_put_failure;
664 if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack))
665 goto nla_put_failure;
666
667 genlmsg_end(msg, hdr);
668 return 0;
669
670 nla_put_failure_type_locked:
671 spin_unlock_bh(&devlink_port->type_lock);
672 nla_put_failure:
673 genlmsg_cancel(msg, hdr);
674 return -EMSGSIZE;
675 }
676
677 static void devlink_port_notify(struct devlink_port *devlink_port,
678 enum devlink_command cmd)
679 {
680 struct devlink *devlink = devlink_port->devlink;
681 struct sk_buff *msg;
682 int err;
683
684 if (!devlink_port->registered)
685 return;
686
687 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
688
689 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
690 if (!msg)
691 return;
692
693 err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0,
694 NULL);
695 if (err) {
696 nlmsg_free(msg);
697 return;
698 }
699
700 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
701 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
702 }
703
704 static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
705 {
706 struct devlink *devlink = info->user_ptr[0];
707 struct sk_buff *msg;
708 int err;
709
710 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
711 if (!msg)
712 return -ENOMEM;
713
714 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
715 info->snd_portid, info->snd_seq, 0);
716 if (err) {
717 nlmsg_free(msg);
718 return err;
719 }
720
721 return genlmsg_reply(msg, info);
722 }
723
724 static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
725 struct netlink_callback *cb)
726 {
727 struct devlink *devlink;
728 int start = cb->args[0];
729 int idx = 0;
730 int err;
731
732 mutex_lock(&devlink_mutex);
733 list_for_each_entry(devlink, &devlink_list, list) {
734 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
735 continue;
736 if (idx < start) {
737 idx++;
738 continue;
739 }
740 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
741 NETLINK_CB(cb->skb).portid,
742 cb->nlh->nlmsg_seq, NLM_F_MULTI);
743 if (err)
744 goto out;
745 idx++;
746 }
747 out:
748 mutex_unlock(&devlink_mutex);
749
750 cb->args[0] = idx;
751 return msg->len;
752 }
753
754 static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
755 struct genl_info *info)
756 {
757 struct devlink_port *devlink_port = info->user_ptr[0];
758 struct devlink *devlink = devlink_port->devlink;
759 struct sk_buff *msg;
760 int err;
761
762 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
763 if (!msg)
764 return -ENOMEM;
765
766 err = devlink_nl_port_fill(msg, devlink, devlink_port,
767 DEVLINK_CMD_PORT_NEW,
768 info->snd_portid, info->snd_seq, 0,
769 info->extack);
770 if (err) {
771 nlmsg_free(msg);
772 return err;
773 }
774
775 return genlmsg_reply(msg, info);
776 }
777
778 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
779 struct netlink_callback *cb)
780 {
781 struct devlink *devlink;
782 struct devlink_port *devlink_port;
783 int start = cb->args[0];
784 int idx = 0;
785 int err;
786
787 mutex_lock(&devlink_mutex);
788 list_for_each_entry(devlink, &devlink_list, list) {
789 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
790 continue;
791 mutex_lock(&devlink->lock);
792 list_for_each_entry(devlink_port, &devlink->port_list, list) {
793 if (idx < start) {
794 idx++;
795 continue;
796 }
797 err = devlink_nl_port_fill(msg, devlink, devlink_port,
798 DEVLINK_CMD_NEW,
799 NETLINK_CB(cb->skb).portid,
800 cb->nlh->nlmsg_seq,
801 NLM_F_MULTI,
802 cb->extack);
803 if (err) {
804 mutex_unlock(&devlink->lock);
805 goto out;
806 }
807 idx++;
808 }
809 mutex_unlock(&devlink->lock);
810 }
811 out:
812 mutex_unlock(&devlink_mutex);
813
814 cb->args[0] = idx;
815 return msg->len;
816 }
817
818 static int devlink_port_type_set(struct devlink *devlink,
819 struct devlink_port *devlink_port,
820 enum devlink_port_type port_type)
821
822 {
823 int err;
824
825 if (devlink->ops->port_type_set) {
826 if (port_type == DEVLINK_PORT_TYPE_NOTSET)
827 return -EINVAL;
828 if (port_type == devlink_port->type)
829 return 0;
830 err = devlink->ops->port_type_set(devlink_port, port_type);
831 if (err)
832 return err;
833 devlink_port->desired_type = port_type;
834 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
835 return 0;
836 }
837 return -EOPNOTSUPP;
838 }
839
840 static int
841 devlink_port_function_hw_addr_set(struct devlink *devlink, struct devlink_port *port,
842 const struct nlattr *attr, struct netlink_ext_ack *extack)
843 {
844 const struct devlink_ops *ops;
845 const u8 *hw_addr;
846 int hw_addr_len;
847 int err;
848
849 hw_addr = nla_data(attr);
850 hw_addr_len = nla_len(attr);
851 if (hw_addr_len > MAX_ADDR_LEN) {
852 NL_SET_ERR_MSG_MOD(extack, "Port function hardware address too long");
853 return -EINVAL;
854 }
855 if (port->type == DEVLINK_PORT_TYPE_ETH) {
856 if (hw_addr_len != ETH_ALEN) {
857 NL_SET_ERR_MSG_MOD(extack, "Address must be 6 bytes for Ethernet device");
858 return -EINVAL;
859 }
860 if (!is_unicast_ether_addr(hw_addr)) {
861 NL_SET_ERR_MSG_MOD(extack, "Non-unicast hardware address unsupported");
862 return -EINVAL;
863 }
864 }
865
866 ops = devlink->ops;
867 if (!ops->port_function_hw_addr_set) {
868 NL_SET_ERR_MSG_MOD(extack, "Port doesn't support function attributes");
869 return -EOPNOTSUPP;
870 }
871
872 err = ops->port_function_hw_addr_set(devlink, port, hw_addr, hw_addr_len, extack);
873 if (err)
874 return err;
875
876 devlink_port_notify(port, DEVLINK_CMD_PORT_NEW);
877 return 0;
878 }
879
880 static int
881 devlink_port_function_set(struct devlink *devlink, struct devlink_port *port,
882 const struct nlattr *attr, struct netlink_ext_ack *extack)
883 {
884 struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1];
885 int err;
886
887 err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr,
888 devlink_function_nl_policy, extack);
889 if (err < 0) {
890 NL_SET_ERR_MSG_MOD(extack, "Fail to parse port function attributes");
891 return err;
892 }
893
894 attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR];
895 if (attr)
896 err = devlink_port_function_hw_addr_set(devlink, port, attr, extack);
897
898 return err;
899 }
900
901 static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
902 struct genl_info *info)
903 {
904 struct devlink_port *devlink_port = info->user_ptr[0];
905 struct devlink *devlink = devlink_port->devlink;
906 int err;
907
908 if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
909 enum devlink_port_type port_type;
910
911 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
912 err = devlink_port_type_set(devlink, devlink_port, port_type);
913 if (err)
914 return err;
915 }
916
917 if (info->attrs[DEVLINK_ATTR_PORT_FUNCTION]) {
918 struct nlattr *attr = info->attrs[DEVLINK_ATTR_PORT_FUNCTION];
919 struct netlink_ext_ack *extack = info->extack;
920
921 err = devlink_port_function_set(devlink, devlink_port, attr, extack);
922 if (err)
923 return err;
924 }
925
926 return 0;
927 }
928
929 static int devlink_port_split(struct devlink *devlink, u32 port_index,
930 u32 count, struct netlink_ext_ack *extack)
931
932 {
933 if (devlink->ops->port_split)
934 return devlink->ops->port_split(devlink, port_index, count,
935 extack);
936 return -EOPNOTSUPP;
937 }
938
939 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
940 struct genl_info *info)
941 {
942 struct devlink *devlink = info->user_ptr[0];
943 struct devlink_port *devlink_port;
944 u32 port_index;
945 u32 count;
946
947 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
948 !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
949 return -EINVAL;
950
951 devlink_port = devlink_port_get_from_info(devlink, info);
952 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
953 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
954
955 if (IS_ERR(devlink_port))
956 return -EINVAL;
957
958 if (!devlink_port->attrs.splittable) {
959 /* Split ports cannot be split. */
960 if (devlink_port->attrs.split)
961 NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split further");
962 else
963 NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split");
964 return -EINVAL;
965 }
966
967 if (count < 2 || !is_power_of_2(count) || count > devlink_port->attrs.lanes) {
968 NL_SET_ERR_MSG_MOD(info->extack, "Invalid split count");
969 return -EINVAL;
970 }
971
972 return devlink_port_split(devlink, port_index, count, info->extack);
973 }
974
975 static int devlink_port_unsplit(struct devlink *devlink, u32 port_index,
976 struct netlink_ext_ack *extack)
977
978 {
979 if (devlink->ops->port_unsplit)
980 return devlink->ops->port_unsplit(devlink, port_index, extack);
981 return -EOPNOTSUPP;
982 }
983
984 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
985 struct genl_info *info)
986 {
987 struct devlink *devlink = info->user_ptr[0];
988 u32 port_index;
989
990 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
991 return -EINVAL;
992
993 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
994 return devlink_port_unsplit(devlink, port_index, info->extack);
995 }
996
997 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
998 struct devlink_sb *devlink_sb,
999 enum devlink_command cmd, u32 portid,
1000 u32 seq, int flags)
1001 {
1002 void *hdr;
1003
1004 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1005 if (!hdr)
1006 return -EMSGSIZE;
1007
1008 if (devlink_nl_put_handle(msg, devlink))
1009 goto nla_put_failure;
1010 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1011 goto nla_put_failure;
1012 if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
1013 goto nla_put_failure;
1014 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
1015 devlink_sb->ingress_pools_count))
1016 goto nla_put_failure;
1017 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
1018 devlink_sb->egress_pools_count))
1019 goto nla_put_failure;
1020 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
1021 devlink_sb->ingress_tc_count))
1022 goto nla_put_failure;
1023 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
1024 devlink_sb->egress_tc_count))
1025 goto nla_put_failure;
1026
1027 genlmsg_end(msg, hdr);
1028 return 0;
1029
1030 nla_put_failure:
1031 genlmsg_cancel(msg, hdr);
1032 return -EMSGSIZE;
1033 }
1034
1035 static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
1036 struct genl_info *info)
1037 {
1038 struct devlink *devlink = info->user_ptr[0];
1039 struct devlink_sb *devlink_sb = info->user_ptr[1];
1040 struct sk_buff *msg;
1041 int err;
1042
1043 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1044 if (!msg)
1045 return -ENOMEM;
1046
1047 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
1048 DEVLINK_CMD_SB_NEW,
1049 info->snd_portid, info->snd_seq, 0);
1050 if (err) {
1051 nlmsg_free(msg);
1052 return err;
1053 }
1054
1055 return genlmsg_reply(msg, info);
1056 }
1057
1058 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
1059 struct netlink_callback *cb)
1060 {
1061 struct devlink *devlink;
1062 struct devlink_sb *devlink_sb;
1063 int start = cb->args[0];
1064 int idx = 0;
1065 int err;
1066
1067 mutex_lock(&devlink_mutex);
1068 list_for_each_entry(devlink, &devlink_list, list) {
1069 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
1070 continue;
1071 mutex_lock(&devlink->lock);
1072 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1073 if (idx < start) {
1074 idx++;
1075 continue;
1076 }
1077 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
1078 DEVLINK_CMD_SB_NEW,
1079 NETLINK_CB(cb->skb).portid,
1080 cb->nlh->nlmsg_seq,
1081 NLM_F_MULTI);
1082 if (err) {
1083 mutex_unlock(&devlink->lock);
1084 goto out;
1085 }
1086 idx++;
1087 }
1088 mutex_unlock(&devlink->lock);
1089 }
1090 out:
1091 mutex_unlock(&devlink_mutex);
1092
1093 cb->args[0] = idx;
1094 return msg->len;
1095 }
1096
1097 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
1098 struct devlink_sb *devlink_sb,
1099 u16 pool_index, enum devlink_command cmd,
1100 u32 portid, u32 seq, int flags)
1101 {
1102 struct devlink_sb_pool_info pool_info;
1103 void *hdr;
1104 int err;
1105
1106 err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
1107 pool_index, &pool_info);
1108 if (err)
1109 return err;
1110
1111 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1112 if (!hdr)
1113 return -EMSGSIZE;
1114
1115 if (devlink_nl_put_handle(msg, devlink))
1116 goto nla_put_failure;
1117 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1118 goto nla_put_failure;
1119 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1120 goto nla_put_failure;
1121 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
1122 goto nla_put_failure;
1123 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
1124 goto nla_put_failure;
1125 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
1126 pool_info.threshold_type))
1127 goto nla_put_failure;
1128 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE,
1129 pool_info.cell_size))
1130 goto nla_put_failure;
1131
1132 genlmsg_end(msg, hdr);
1133 return 0;
1134
1135 nla_put_failure:
1136 genlmsg_cancel(msg, hdr);
1137 return -EMSGSIZE;
1138 }
1139
1140 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
1141 struct genl_info *info)
1142 {
1143 struct devlink *devlink = info->user_ptr[0];
1144 struct devlink_sb *devlink_sb = info->user_ptr[1];
1145 struct sk_buff *msg;
1146 u16 pool_index;
1147 int err;
1148
1149 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1150 &pool_index);
1151 if (err)
1152 return err;
1153
1154 if (!devlink->ops->sb_pool_get)
1155 return -EOPNOTSUPP;
1156
1157 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1158 if (!msg)
1159 return -ENOMEM;
1160
1161 err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
1162 DEVLINK_CMD_SB_POOL_NEW,
1163 info->snd_portid, info->snd_seq, 0);
1164 if (err) {
1165 nlmsg_free(msg);
1166 return err;
1167 }
1168
1169 return genlmsg_reply(msg, info);
1170 }
1171
1172 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1173 struct devlink *devlink,
1174 struct devlink_sb *devlink_sb,
1175 u32 portid, u32 seq)
1176 {
1177 u16 pool_count = devlink_sb_pool_count(devlink_sb);
1178 u16 pool_index;
1179 int err;
1180
1181 for (pool_index = 0; pool_index < pool_count; pool_index++) {
1182 if (*p_idx < start) {
1183 (*p_idx)++;
1184 continue;
1185 }
1186 err = devlink_nl_sb_pool_fill(msg, devlink,
1187 devlink_sb,
1188 pool_index,
1189 DEVLINK_CMD_SB_POOL_NEW,
1190 portid, seq, NLM_F_MULTI);
1191 if (err)
1192 return err;
1193 (*p_idx)++;
1194 }
1195 return 0;
1196 }
1197
1198 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
1199 struct netlink_callback *cb)
1200 {
1201 struct devlink *devlink;
1202 struct devlink_sb *devlink_sb;
1203 int start = cb->args[0];
1204 int idx = 0;
1205 int err = 0;
1206
1207 mutex_lock(&devlink_mutex);
1208 list_for_each_entry(devlink, &devlink_list, list) {
1209 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1210 !devlink->ops->sb_pool_get)
1211 continue;
1212 mutex_lock(&devlink->lock);
1213 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1214 err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
1215 devlink_sb,
1216 NETLINK_CB(cb->skb).portid,
1217 cb->nlh->nlmsg_seq);
1218 if (err && err != -EOPNOTSUPP) {
1219 mutex_unlock(&devlink->lock);
1220 goto out;
1221 }
1222 }
1223 mutex_unlock(&devlink->lock);
1224 }
1225 out:
1226 mutex_unlock(&devlink_mutex);
1227
1228 if (err != -EMSGSIZE)
1229 return err;
1230
1231 cb->args[0] = idx;
1232 return msg->len;
1233 }
1234
1235 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
1236 u16 pool_index, u32 size,
1237 enum devlink_sb_threshold_type threshold_type,
1238 struct netlink_ext_ack *extack)
1239
1240 {
1241 const struct devlink_ops *ops = devlink->ops;
1242
1243 if (ops->sb_pool_set)
1244 return ops->sb_pool_set(devlink, sb_index, pool_index,
1245 size, threshold_type, extack);
1246 return -EOPNOTSUPP;
1247 }
1248
1249 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
1250 struct genl_info *info)
1251 {
1252 struct devlink *devlink = info->user_ptr[0];
1253 struct devlink_sb *devlink_sb = info->user_ptr[1];
1254 enum devlink_sb_threshold_type threshold_type;
1255 u16 pool_index;
1256 u32 size;
1257 int err;
1258
1259 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1260 &pool_index);
1261 if (err)
1262 return err;
1263
1264 err = devlink_sb_th_type_get_from_info(info, &threshold_type);
1265 if (err)
1266 return err;
1267
1268 if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
1269 return -EINVAL;
1270
1271 size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
1272 return devlink_sb_pool_set(devlink, devlink_sb->index,
1273 pool_index, size, threshold_type,
1274 info->extack);
1275 }
1276
1277 static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
1278 struct devlink *devlink,
1279 struct devlink_port *devlink_port,
1280 struct devlink_sb *devlink_sb,
1281 u16 pool_index,
1282 enum devlink_command cmd,
1283 u32 portid, u32 seq, int flags)
1284 {
1285 const struct devlink_ops *ops = devlink->ops;
1286 u32 threshold;
1287 void *hdr;
1288 int err;
1289
1290 err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
1291 pool_index, &threshold);
1292 if (err)
1293 return err;
1294
1295 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1296 if (!hdr)
1297 return -EMSGSIZE;
1298
1299 if (devlink_nl_put_handle(msg, devlink))
1300 goto nla_put_failure;
1301 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1302 goto nla_put_failure;
1303 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1304 goto nla_put_failure;
1305 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1306 goto nla_put_failure;
1307 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1308 goto nla_put_failure;
1309
1310 if (ops->sb_occ_port_pool_get) {
1311 u32 cur;
1312 u32 max;
1313
1314 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
1315 pool_index, &cur, &max);
1316 if (err && err != -EOPNOTSUPP)
1317 return err;
1318 if (!err) {
1319 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1320 goto nla_put_failure;
1321 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1322 goto nla_put_failure;
1323 }
1324 }
1325
1326 genlmsg_end(msg, hdr);
1327 return 0;
1328
1329 nla_put_failure:
1330 genlmsg_cancel(msg, hdr);
1331 return -EMSGSIZE;
1332 }
1333
1334 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
1335 struct genl_info *info)
1336 {
1337 struct devlink_port *devlink_port = info->user_ptr[0];
1338 struct devlink *devlink = devlink_port->devlink;
1339 struct devlink_sb *devlink_sb = info->user_ptr[1];
1340 struct sk_buff *msg;
1341 u16 pool_index;
1342 int err;
1343
1344 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1345 &pool_index);
1346 if (err)
1347 return err;
1348
1349 if (!devlink->ops->sb_port_pool_get)
1350 return -EOPNOTSUPP;
1351
1352 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1353 if (!msg)
1354 return -ENOMEM;
1355
1356 err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
1357 devlink_sb, pool_index,
1358 DEVLINK_CMD_SB_PORT_POOL_NEW,
1359 info->snd_portid, info->snd_seq, 0);
1360 if (err) {
1361 nlmsg_free(msg);
1362 return err;
1363 }
1364
1365 return genlmsg_reply(msg, info);
1366 }
1367
1368 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1369 struct devlink *devlink,
1370 struct devlink_sb *devlink_sb,
1371 u32 portid, u32 seq)
1372 {
1373 struct devlink_port *devlink_port;
1374 u16 pool_count = devlink_sb_pool_count(devlink_sb);
1375 u16 pool_index;
1376 int err;
1377
1378 list_for_each_entry(devlink_port, &devlink->port_list, list) {
1379 for (pool_index = 0; pool_index < pool_count; pool_index++) {
1380 if (*p_idx < start) {
1381 (*p_idx)++;
1382 continue;
1383 }
1384 err = devlink_nl_sb_port_pool_fill(msg, devlink,
1385 devlink_port,
1386 devlink_sb,
1387 pool_index,
1388 DEVLINK_CMD_SB_PORT_POOL_NEW,
1389 portid, seq,
1390 NLM_F_MULTI);
1391 if (err)
1392 return err;
1393 (*p_idx)++;
1394 }
1395 }
1396 return 0;
1397 }
1398
1399 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
1400 struct netlink_callback *cb)
1401 {
1402 struct devlink *devlink;
1403 struct devlink_sb *devlink_sb;
1404 int start = cb->args[0];
1405 int idx = 0;
1406 int err = 0;
1407
1408 mutex_lock(&devlink_mutex);
1409 list_for_each_entry(devlink, &devlink_list, list) {
1410 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1411 !devlink->ops->sb_port_pool_get)
1412 continue;
1413 mutex_lock(&devlink->lock);
1414 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1415 err = __sb_port_pool_get_dumpit(msg, start, &idx,
1416 devlink, devlink_sb,
1417 NETLINK_CB(cb->skb).portid,
1418 cb->nlh->nlmsg_seq);
1419 if (err && err != -EOPNOTSUPP) {
1420 mutex_unlock(&devlink->lock);
1421 goto out;
1422 }
1423 }
1424 mutex_unlock(&devlink->lock);
1425 }
1426 out:
1427 mutex_unlock(&devlink_mutex);
1428
1429 if (err != -EMSGSIZE)
1430 return err;
1431
1432 cb->args[0] = idx;
1433 return msg->len;
1434 }
1435
1436 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
1437 unsigned int sb_index, u16 pool_index,
1438 u32 threshold,
1439 struct netlink_ext_ack *extack)
1440
1441 {
1442 const struct devlink_ops *ops = devlink_port->devlink->ops;
1443
1444 if (ops->sb_port_pool_set)
1445 return ops->sb_port_pool_set(devlink_port, sb_index,
1446 pool_index, threshold, extack);
1447 return -EOPNOTSUPP;
1448 }
1449
1450 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
1451 struct genl_info *info)
1452 {
1453 struct devlink_port *devlink_port = info->user_ptr[0];
1454 struct devlink_sb *devlink_sb = info->user_ptr[1];
1455 u16 pool_index;
1456 u32 threshold;
1457 int err;
1458
1459 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1460 &pool_index);
1461 if (err)
1462 return err;
1463
1464 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1465 return -EINVAL;
1466
1467 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1468 return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
1469 pool_index, threshold, info->extack);
1470 }
1471
1472 static int
1473 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
1474 struct devlink_port *devlink_port,
1475 struct devlink_sb *devlink_sb, u16 tc_index,
1476 enum devlink_sb_pool_type pool_type,
1477 enum devlink_command cmd,
1478 u32 portid, u32 seq, int flags)
1479 {
1480 const struct devlink_ops *ops = devlink->ops;
1481 u16 pool_index;
1482 u32 threshold;
1483 void *hdr;
1484 int err;
1485
1486 err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
1487 tc_index, pool_type,
1488 &pool_index, &threshold);
1489 if (err)
1490 return err;
1491
1492 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1493 if (!hdr)
1494 return -EMSGSIZE;
1495
1496 if (devlink_nl_put_handle(msg, devlink))
1497 goto nla_put_failure;
1498 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1499 goto nla_put_failure;
1500 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1501 goto nla_put_failure;
1502 if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
1503 goto nla_put_failure;
1504 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
1505 goto nla_put_failure;
1506 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1507 goto nla_put_failure;
1508 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1509 goto nla_put_failure;
1510
1511 if (ops->sb_occ_tc_port_bind_get) {
1512 u32 cur;
1513 u32 max;
1514
1515 err = ops->sb_occ_tc_port_bind_get(devlink_port,
1516 devlink_sb->index,
1517 tc_index, pool_type,
1518 &cur, &max);
1519 if (err && err != -EOPNOTSUPP)
1520 return err;
1521 if (!err) {
1522 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1523 goto nla_put_failure;
1524 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1525 goto nla_put_failure;
1526 }
1527 }
1528
1529 genlmsg_end(msg, hdr);
1530 return 0;
1531
1532 nla_put_failure:
1533 genlmsg_cancel(msg, hdr);
1534 return -EMSGSIZE;
1535 }
1536
1537 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
1538 struct genl_info *info)
1539 {
1540 struct devlink_port *devlink_port = info->user_ptr[0];
1541 struct devlink *devlink = devlink_port->devlink;
1542 struct devlink_sb *devlink_sb = info->user_ptr[1];
1543 struct sk_buff *msg;
1544 enum devlink_sb_pool_type pool_type;
1545 u16 tc_index;
1546 int err;
1547
1548 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1549 if (err)
1550 return err;
1551
1552 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1553 pool_type, &tc_index);
1554 if (err)
1555 return err;
1556
1557 if (!devlink->ops->sb_tc_pool_bind_get)
1558 return -EOPNOTSUPP;
1559
1560 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1561 if (!msg)
1562 return -ENOMEM;
1563
1564 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
1565 devlink_sb, tc_index, pool_type,
1566 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1567 info->snd_portid,
1568 info->snd_seq, 0);
1569 if (err) {
1570 nlmsg_free(msg);
1571 return err;
1572 }
1573
1574 return genlmsg_reply(msg, info);
1575 }
1576
1577 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1578 int start, int *p_idx,
1579 struct devlink *devlink,
1580 struct devlink_sb *devlink_sb,
1581 u32 portid, u32 seq)
1582 {
1583 struct devlink_port *devlink_port;
1584 u16 tc_index;
1585 int err;
1586
1587 list_for_each_entry(devlink_port, &devlink->port_list, list) {
1588 for (tc_index = 0;
1589 tc_index < devlink_sb->ingress_tc_count; tc_index++) {
1590 if (*p_idx < start) {
1591 (*p_idx)++;
1592 continue;
1593 }
1594 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1595 devlink_port,
1596 devlink_sb,
1597 tc_index,
1598 DEVLINK_SB_POOL_TYPE_INGRESS,
1599 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1600 portid, seq,
1601 NLM_F_MULTI);
1602 if (err)
1603 return err;
1604 (*p_idx)++;
1605 }
1606 for (tc_index = 0;
1607 tc_index < devlink_sb->egress_tc_count; tc_index++) {
1608 if (*p_idx < start) {
1609 (*p_idx)++;
1610 continue;
1611 }
1612 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1613 devlink_port,
1614 devlink_sb,
1615 tc_index,
1616 DEVLINK_SB_POOL_TYPE_EGRESS,
1617 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1618 portid, seq,
1619 NLM_F_MULTI);
1620 if (err)
1621 return err;
1622 (*p_idx)++;
1623 }
1624 }
1625 return 0;
1626 }
1627
1628 static int
1629 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1630 struct netlink_callback *cb)
1631 {
1632 struct devlink *devlink;
1633 struct devlink_sb *devlink_sb;
1634 int start = cb->args[0];
1635 int idx = 0;
1636 int err = 0;
1637
1638 mutex_lock(&devlink_mutex);
1639 list_for_each_entry(devlink, &devlink_list, list) {
1640 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1641 !devlink->ops->sb_tc_pool_bind_get)
1642 continue;
1643
1644 mutex_lock(&devlink->lock);
1645 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1646 err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
1647 devlink,
1648 devlink_sb,
1649 NETLINK_CB(cb->skb).portid,
1650 cb->nlh->nlmsg_seq);
1651 if (err && err != -EOPNOTSUPP) {
1652 mutex_unlock(&devlink->lock);
1653 goto out;
1654 }
1655 }
1656 mutex_unlock(&devlink->lock);
1657 }
1658 out:
1659 mutex_unlock(&devlink_mutex);
1660
1661 if (err != -EMSGSIZE)
1662 return err;
1663
1664 cb->args[0] = idx;
1665 return msg->len;
1666 }
1667
1668 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
1669 unsigned int sb_index, u16 tc_index,
1670 enum devlink_sb_pool_type pool_type,
1671 u16 pool_index, u32 threshold,
1672 struct netlink_ext_ack *extack)
1673
1674 {
1675 const struct devlink_ops *ops = devlink_port->devlink->ops;
1676
1677 if (ops->sb_tc_pool_bind_set)
1678 return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
1679 tc_index, pool_type,
1680 pool_index, threshold, extack);
1681 return -EOPNOTSUPP;
1682 }
1683
1684 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
1685 struct genl_info *info)
1686 {
1687 struct devlink_port *devlink_port = info->user_ptr[0];
1688 struct devlink_sb *devlink_sb = info->user_ptr[1];
1689 enum devlink_sb_pool_type pool_type;
1690 u16 tc_index;
1691 u16 pool_index;
1692 u32 threshold;
1693 int err;
1694
1695 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1696 if (err)
1697 return err;
1698
1699 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1700 pool_type, &tc_index);
1701 if (err)
1702 return err;
1703
1704 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1705 &pool_index);
1706 if (err)
1707 return err;
1708
1709 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1710 return -EINVAL;
1711
1712 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1713 return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
1714 tc_index, pool_type,
1715 pool_index, threshold, info->extack);
1716 }
1717
1718 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
1719 struct genl_info *info)
1720 {
1721 struct devlink *devlink = info->user_ptr[0];
1722 struct devlink_sb *devlink_sb = info->user_ptr[1];
1723 const struct devlink_ops *ops = devlink->ops;
1724
1725 if (ops->sb_occ_snapshot)
1726 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
1727 return -EOPNOTSUPP;
1728 }
1729
1730 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
1731 struct genl_info *info)
1732 {
1733 struct devlink *devlink = info->user_ptr[0];
1734 struct devlink_sb *devlink_sb = info->user_ptr[1];
1735 const struct devlink_ops *ops = devlink->ops;
1736
1737 if (ops->sb_occ_max_clear)
1738 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
1739 return -EOPNOTSUPP;
1740 }
1741
1742 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
1743 enum devlink_command cmd, u32 portid,
1744 u32 seq, int flags)
1745 {
1746 const struct devlink_ops *ops = devlink->ops;
1747 enum devlink_eswitch_encap_mode encap_mode;
1748 u8 inline_mode;
1749 void *hdr;
1750 int err = 0;
1751 u16 mode;
1752
1753 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1754 if (!hdr)
1755 return -EMSGSIZE;
1756
1757 err = devlink_nl_put_handle(msg, devlink);
1758 if (err)
1759 goto nla_put_failure;
1760
1761 if (ops->eswitch_mode_get) {
1762 err = ops->eswitch_mode_get(devlink, &mode);
1763 if (err)
1764 goto nla_put_failure;
1765 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
1766 if (err)
1767 goto nla_put_failure;
1768 }
1769
1770 if (ops->eswitch_inline_mode_get) {
1771 err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
1772 if (err)
1773 goto nla_put_failure;
1774 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
1775 inline_mode);
1776 if (err)
1777 goto nla_put_failure;
1778 }
1779
1780 if (ops->eswitch_encap_mode_get) {
1781 err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
1782 if (err)
1783 goto nla_put_failure;
1784 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
1785 if (err)
1786 goto nla_put_failure;
1787 }
1788
1789 genlmsg_end(msg, hdr);
1790 return 0;
1791
1792 nla_put_failure:
1793 genlmsg_cancel(msg, hdr);
1794 return err;
1795 }
1796
1797 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
1798 struct genl_info *info)
1799 {
1800 struct devlink *devlink = info->user_ptr[0];
1801 struct sk_buff *msg;
1802 int err;
1803
1804 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1805 if (!msg)
1806 return -ENOMEM;
1807
1808 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
1809 info->snd_portid, info->snd_seq, 0);
1810
1811 if (err) {
1812 nlmsg_free(msg);
1813 return err;
1814 }
1815
1816 return genlmsg_reply(msg, info);
1817 }
1818
1819 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
1820 struct genl_info *info)
1821 {
1822 struct devlink *devlink = info->user_ptr[0];
1823 const struct devlink_ops *ops = devlink->ops;
1824 enum devlink_eswitch_encap_mode encap_mode;
1825 u8 inline_mode;
1826 int err = 0;
1827 u16 mode;
1828
1829 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
1830 if (!ops->eswitch_mode_set)
1831 return -EOPNOTSUPP;
1832 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1833 err = ops->eswitch_mode_set(devlink, mode, info->extack);
1834 if (err)
1835 return err;
1836 }
1837
1838 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
1839 if (!ops->eswitch_inline_mode_set)
1840 return -EOPNOTSUPP;
1841 inline_mode = nla_get_u8(
1842 info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
1843 err = ops->eswitch_inline_mode_set(devlink, inline_mode,
1844 info->extack);
1845 if (err)
1846 return err;
1847 }
1848
1849 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
1850 if (!ops->eswitch_encap_mode_set)
1851 return -EOPNOTSUPP;
1852 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
1853 err = ops->eswitch_encap_mode_set(devlink, encap_mode,
1854 info->extack);
1855 if (err)
1856 return err;
1857 }
1858
1859 return 0;
1860 }
1861
1862 int devlink_dpipe_match_put(struct sk_buff *skb,
1863 struct devlink_dpipe_match *match)
1864 {
1865 struct devlink_dpipe_header *header = match->header;
1866 struct devlink_dpipe_field *field = &header->fields[match->field_id];
1867 struct nlattr *match_attr;
1868
1869 match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
1870 if (!match_attr)
1871 return -EMSGSIZE;
1872
1873 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
1874 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
1875 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1876 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1877 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1878 goto nla_put_failure;
1879
1880 nla_nest_end(skb, match_attr);
1881 return 0;
1882
1883 nla_put_failure:
1884 nla_nest_cancel(skb, match_attr);
1885 return -EMSGSIZE;
1886 }
1887 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
1888
1889 static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
1890 struct sk_buff *skb)
1891 {
1892 struct nlattr *matches_attr;
1893
1894 matches_attr = nla_nest_start_noflag(skb,
1895 DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
1896 if (!matches_attr)
1897 return -EMSGSIZE;
1898
1899 if (table->table_ops->matches_dump(table->priv, skb))
1900 goto nla_put_failure;
1901
1902 nla_nest_end(skb, matches_attr);
1903 return 0;
1904
1905 nla_put_failure:
1906 nla_nest_cancel(skb, matches_attr);
1907 return -EMSGSIZE;
1908 }
1909
1910 int devlink_dpipe_action_put(struct sk_buff *skb,
1911 struct devlink_dpipe_action *action)
1912 {
1913 struct devlink_dpipe_header *header = action->header;
1914 struct devlink_dpipe_field *field = &header->fields[action->field_id];
1915 struct nlattr *action_attr;
1916
1917 action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
1918 if (!action_attr)
1919 return -EMSGSIZE;
1920
1921 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
1922 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
1923 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1924 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1925 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1926 goto nla_put_failure;
1927
1928 nla_nest_end(skb, action_attr);
1929 return 0;
1930
1931 nla_put_failure:
1932 nla_nest_cancel(skb, action_attr);
1933 return -EMSGSIZE;
1934 }
1935 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
1936
1937 static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
1938 struct sk_buff *skb)
1939 {
1940 struct nlattr *actions_attr;
1941
1942 actions_attr = nla_nest_start_noflag(skb,
1943 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
1944 if (!actions_attr)
1945 return -EMSGSIZE;
1946
1947 if (table->table_ops->actions_dump(table->priv, skb))
1948 goto nla_put_failure;
1949
1950 nla_nest_end(skb, actions_attr);
1951 return 0;
1952
1953 nla_put_failure:
1954 nla_nest_cancel(skb, actions_attr);
1955 return -EMSGSIZE;
1956 }
1957
1958 static int devlink_dpipe_table_put(struct sk_buff *skb,
1959 struct devlink_dpipe_table *table)
1960 {
1961 struct nlattr *table_attr;
1962 u64 table_size;
1963
1964 table_size = table->table_ops->size_get(table->priv);
1965 table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
1966 if (!table_attr)
1967 return -EMSGSIZE;
1968
1969 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
1970 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
1971 DEVLINK_ATTR_PAD))
1972 goto nla_put_failure;
1973 if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
1974 table->counters_enabled))
1975 goto nla_put_failure;
1976
1977 if (table->resource_valid) {
1978 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
1979 table->resource_id, DEVLINK_ATTR_PAD) ||
1980 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
1981 table->resource_units, DEVLINK_ATTR_PAD))
1982 goto nla_put_failure;
1983 }
1984 if (devlink_dpipe_matches_put(table, skb))
1985 goto nla_put_failure;
1986
1987 if (devlink_dpipe_actions_put(table, skb))
1988 goto nla_put_failure;
1989
1990 nla_nest_end(skb, table_attr);
1991 return 0;
1992
1993 nla_put_failure:
1994 nla_nest_cancel(skb, table_attr);
1995 return -EMSGSIZE;
1996 }
1997
1998 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
1999 struct genl_info *info)
2000 {
2001 int err;
2002
2003 if (*pskb) {
2004 err = genlmsg_reply(*pskb, info);
2005 if (err)
2006 return err;
2007 }
2008 *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
2009 if (!*pskb)
2010 return -ENOMEM;
2011 return 0;
2012 }
2013
2014 static int devlink_dpipe_tables_fill(struct genl_info *info,
2015 enum devlink_command cmd, int flags,
2016 struct list_head *dpipe_tables,
2017 const char *table_name)
2018 {
2019 struct devlink *devlink = info->user_ptr[0];
2020 struct devlink_dpipe_table *table;
2021 struct nlattr *tables_attr;
2022 struct sk_buff *skb = NULL;
2023 struct nlmsghdr *nlh;
2024 bool incomplete;
2025 void *hdr;
2026 int i;
2027 int err;
2028
2029 table = list_first_entry(dpipe_tables,
2030 struct devlink_dpipe_table, list);
2031 start_again:
2032 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2033 if (err)
2034 return err;
2035
2036 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2037 &devlink_nl_family, NLM_F_MULTI, cmd);
2038 if (!hdr) {
2039 nlmsg_free(skb);
2040 return -EMSGSIZE;
2041 }
2042
2043 if (devlink_nl_put_handle(skb, devlink))
2044 goto nla_put_failure;
2045 tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES);
2046 if (!tables_attr)
2047 goto nla_put_failure;
2048
2049 i = 0;
2050 incomplete = false;
2051 list_for_each_entry_from(table, dpipe_tables, list) {
2052 if (!table_name) {
2053 err = devlink_dpipe_table_put(skb, table);
2054 if (err) {
2055 if (!i)
2056 goto err_table_put;
2057 incomplete = true;
2058 break;
2059 }
2060 } else {
2061 if (!strcmp(table->name, table_name)) {
2062 err = devlink_dpipe_table_put(skb, table);
2063 if (err)
2064 break;
2065 }
2066 }
2067 i++;
2068 }
2069
2070 nla_nest_end(skb, tables_attr);
2071 genlmsg_end(skb, hdr);
2072 if (incomplete)
2073 goto start_again;
2074
2075 send_done:
2076 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2077 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2078 if (!nlh) {
2079 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2080 if (err)
2081 return err;
2082 goto send_done;
2083 }
2084
2085 return genlmsg_reply(skb, info);
2086
2087 nla_put_failure:
2088 err = -EMSGSIZE;
2089 err_table_put:
2090 nlmsg_free(skb);
2091 return err;
2092 }
2093
2094 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
2095 struct genl_info *info)
2096 {
2097 struct devlink *devlink = info->user_ptr[0];
2098 const char *table_name = NULL;
2099
2100 if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
2101 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2102
2103 return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
2104 &devlink->dpipe_table_list,
2105 table_name);
2106 }
2107
2108 static int devlink_dpipe_value_put(struct sk_buff *skb,
2109 struct devlink_dpipe_value *value)
2110 {
2111 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
2112 value->value_size, value->value))
2113 return -EMSGSIZE;
2114 if (value->mask)
2115 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
2116 value->value_size, value->mask))
2117 return -EMSGSIZE;
2118 if (value->mapping_valid)
2119 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
2120 value->mapping_value))
2121 return -EMSGSIZE;
2122 return 0;
2123 }
2124
2125 static int devlink_dpipe_action_value_put(struct sk_buff *skb,
2126 struct devlink_dpipe_value *value)
2127 {
2128 if (!value->action)
2129 return -EINVAL;
2130 if (devlink_dpipe_action_put(skb, value->action))
2131 return -EMSGSIZE;
2132 if (devlink_dpipe_value_put(skb, value))
2133 return -EMSGSIZE;
2134 return 0;
2135 }
2136
2137 static int devlink_dpipe_action_values_put(struct sk_buff *skb,
2138 struct devlink_dpipe_value *values,
2139 unsigned int values_count)
2140 {
2141 struct nlattr *action_attr;
2142 int i;
2143 int err;
2144
2145 for (i = 0; i < values_count; i++) {
2146 action_attr = nla_nest_start_noflag(skb,
2147 DEVLINK_ATTR_DPIPE_ACTION_VALUE);
2148 if (!action_attr)
2149 return -EMSGSIZE;
2150 err = devlink_dpipe_action_value_put(skb, &values[i]);
2151 if (err)
2152 goto err_action_value_put;
2153 nla_nest_end(skb, action_attr);
2154 }
2155 return 0;
2156
2157 err_action_value_put:
2158 nla_nest_cancel(skb, action_attr);
2159 return err;
2160 }
2161
2162 static int devlink_dpipe_match_value_put(struct sk_buff *skb,
2163 struct devlink_dpipe_value *value)
2164 {
2165 if (!value->match)
2166 return -EINVAL;
2167 if (devlink_dpipe_match_put(skb, value->match))
2168 return -EMSGSIZE;
2169 if (devlink_dpipe_value_put(skb, value))
2170 return -EMSGSIZE;
2171 return 0;
2172 }
2173
2174 static int devlink_dpipe_match_values_put(struct sk_buff *skb,
2175 struct devlink_dpipe_value *values,
2176 unsigned int values_count)
2177 {
2178 struct nlattr *match_attr;
2179 int i;
2180 int err;
2181
2182 for (i = 0; i < values_count; i++) {
2183 match_attr = nla_nest_start_noflag(skb,
2184 DEVLINK_ATTR_DPIPE_MATCH_VALUE);
2185 if (!match_attr)
2186 return -EMSGSIZE;
2187 err = devlink_dpipe_match_value_put(skb, &values[i]);
2188 if (err)
2189 goto err_match_value_put;
2190 nla_nest_end(skb, match_attr);
2191 }
2192 return 0;
2193
2194 err_match_value_put:
2195 nla_nest_cancel(skb, match_attr);
2196 return err;
2197 }
2198
2199 static int devlink_dpipe_entry_put(struct sk_buff *skb,
2200 struct devlink_dpipe_entry *entry)
2201 {
2202 struct nlattr *entry_attr, *matches_attr, *actions_attr;
2203 int err;
2204
2205 entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
2206 if (!entry_attr)
2207 return -EMSGSIZE;
2208
2209 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
2210 DEVLINK_ATTR_PAD))
2211 goto nla_put_failure;
2212 if (entry->counter_valid)
2213 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
2214 entry->counter, DEVLINK_ATTR_PAD))
2215 goto nla_put_failure;
2216
2217 matches_attr = nla_nest_start_noflag(skb,
2218 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
2219 if (!matches_attr)
2220 goto nla_put_failure;
2221
2222 err = devlink_dpipe_match_values_put(skb, entry->match_values,
2223 entry->match_values_count);
2224 if (err) {
2225 nla_nest_cancel(skb, matches_attr);
2226 goto err_match_values_put;
2227 }
2228 nla_nest_end(skb, matches_attr);
2229
2230 actions_attr = nla_nest_start_noflag(skb,
2231 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
2232 if (!actions_attr)
2233 goto nla_put_failure;
2234
2235 err = devlink_dpipe_action_values_put(skb, entry->action_values,
2236 entry->action_values_count);
2237 if (err) {
2238 nla_nest_cancel(skb, actions_attr);
2239 goto err_action_values_put;
2240 }
2241 nla_nest_end(skb, actions_attr);
2242
2243 nla_nest_end(skb, entry_attr);
2244 return 0;
2245
2246 nla_put_failure:
2247 err = -EMSGSIZE;
2248 err_match_values_put:
2249 err_action_values_put:
2250 nla_nest_cancel(skb, entry_attr);
2251 return err;
2252 }
2253
2254 static struct devlink_dpipe_table *
2255 devlink_dpipe_table_find(struct list_head *dpipe_tables,
2256 const char *table_name, struct devlink *devlink)
2257 {
2258 struct devlink_dpipe_table *table;
2259 list_for_each_entry_rcu(table, dpipe_tables, list,
2260 lockdep_is_held(&devlink->lock)) {
2261 if (!strcmp(table->name, table_name))
2262 return table;
2263 }
2264 return NULL;
2265 }
2266
2267 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
2268 {
2269 struct devlink *devlink;
2270 int err;
2271
2272 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
2273 dump_ctx->info);
2274 if (err)
2275 return err;
2276
2277 dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
2278 dump_ctx->info->snd_portid,
2279 dump_ctx->info->snd_seq,
2280 &devlink_nl_family, NLM_F_MULTI,
2281 dump_ctx->cmd);
2282 if (!dump_ctx->hdr)
2283 goto nla_put_failure;
2284
2285 devlink = dump_ctx->info->user_ptr[0];
2286 if (devlink_nl_put_handle(dump_ctx->skb, devlink))
2287 goto nla_put_failure;
2288 dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb,
2289 DEVLINK_ATTR_DPIPE_ENTRIES);
2290 if (!dump_ctx->nest)
2291 goto nla_put_failure;
2292 return 0;
2293
2294 nla_put_failure:
2295 nlmsg_free(dump_ctx->skb);
2296 return -EMSGSIZE;
2297 }
2298 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
2299
2300 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
2301 struct devlink_dpipe_entry *entry)
2302 {
2303 return devlink_dpipe_entry_put(dump_ctx->skb, entry);
2304 }
2305 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
2306
2307 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
2308 {
2309 nla_nest_end(dump_ctx->skb, dump_ctx->nest);
2310 genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
2311 return 0;
2312 }
2313 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
2314
2315 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
2316
2317 {
2318 unsigned int value_count, value_index;
2319 struct devlink_dpipe_value *value;
2320
2321 value = entry->action_values;
2322 value_count = entry->action_values_count;
2323 for (value_index = 0; value_index < value_count; value_index++) {
2324 kfree(value[value_index].value);
2325 kfree(value[value_index].mask);
2326 }
2327
2328 value = entry->match_values;
2329 value_count = entry->match_values_count;
2330 for (value_index = 0; value_index < value_count; value_index++) {
2331 kfree(value[value_index].value);
2332 kfree(value[value_index].mask);
2333 }
2334 }
2335 EXPORT_SYMBOL(devlink_dpipe_entry_clear);
2336
2337 static int devlink_dpipe_entries_fill(struct genl_info *info,
2338 enum devlink_command cmd, int flags,
2339 struct devlink_dpipe_table *table)
2340 {
2341 struct devlink_dpipe_dump_ctx dump_ctx;
2342 struct nlmsghdr *nlh;
2343 int err;
2344
2345 dump_ctx.skb = NULL;
2346 dump_ctx.cmd = cmd;
2347 dump_ctx.info = info;
2348
2349 err = table->table_ops->entries_dump(table->priv,
2350 table->counters_enabled,
2351 &dump_ctx);
2352 if (err)
2353 return err;
2354
2355 send_done:
2356 nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
2357 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2358 if (!nlh) {
2359 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
2360 if (err)
2361 return err;
2362 goto send_done;
2363 }
2364 return genlmsg_reply(dump_ctx.skb, info);
2365 }
2366
2367 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
2368 struct genl_info *info)
2369 {
2370 struct devlink *devlink = info->user_ptr[0];
2371 struct devlink_dpipe_table *table;
2372 const char *table_name;
2373
2374 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
2375 return -EINVAL;
2376
2377 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2378 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2379 table_name, devlink);
2380 if (!table)
2381 return -EINVAL;
2382
2383 if (!table->table_ops->entries_dump)
2384 return -EINVAL;
2385
2386 return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
2387 0, table);
2388 }
2389
2390 static int devlink_dpipe_fields_put(struct sk_buff *skb,
2391 const struct devlink_dpipe_header *header)
2392 {
2393 struct devlink_dpipe_field *field;
2394 struct nlattr *field_attr;
2395 int i;
2396
2397 for (i = 0; i < header->fields_count; i++) {
2398 field = &header->fields[i];
2399 field_attr = nla_nest_start_noflag(skb,
2400 DEVLINK_ATTR_DPIPE_FIELD);
2401 if (!field_attr)
2402 return -EMSGSIZE;
2403 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
2404 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
2405 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
2406 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
2407 goto nla_put_failure;
2408 nla_nest_end(skb, field_attr);
2409 }
2410 return 0;
2411
2412 nla_put_failure:
2413 nla_nest_cancel(skb, field_attr);
2414 return -EMSGSIZE;
2415 }
2416
2417 static int devlink_dpipe_header_put(struct sk_buff *skb,
2418 struct devlink_dpipe_header *header)
2419 {
2420 struct nlattr *fields_attr, *header_attr;
2421 int err;
2422
2423 header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
2424 if (!header_attr)
2425 return -EMSGSIZE;
2426
2427 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
2428 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
2429 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
2430 goto nla_put_failure;
2431
2432 fields_attr = nla_nest_start_noflag(skb,
2433 DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
2434 if (!fields_attr)
2435 goto nla_put_failure;
2436
2437 err = devlink_dpipe_fields_put(skb, header);
2438 if (err) {
2439 nla_nest_cancel(skb, fields_attr);
2440 goto nla_put_failure;
2441 }
2442 nla_nest_end(skb, fields_attr);
2443 nla_nest_end(skb, header_attr);
2444 return 0;
2445
2446 nla_put_failure:
2447 err = -EMSGSIZE;
2448 nla_nest_cancel(skb, header_attr);
2449 return err;
2450 }
2451
2452 static int devlink_dpipe_headers_fill(struct genl_info *info,
2453 enum devlink_command cmd, int flags,
2454 struct devlink_dpipe_headers *
2455 dpipe_headers)
2456 {
2457 struct devlink *devlink = info->user_ptr[0];
2458 struct nlattr *headers_attr;
2459 struct sk_buff *skb = NULL;
2460 struct nlmsghdr *nlh;
2461 void *hdr;
2462 int i, j;
2463 int err;
2464
2465 i = 0;
2466 start_again:
2467 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2468 if (err)
2469 return err;
2470
2471 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2472 &devlink_nl_family, NLM_F_MULTI, cmd);
2473 if (!hdr) {
2474 nlmsg_free(skb);
2475 return -EMSGSIZE;
2476 }
2477
2478 if (devlink_nl_put_handle(skb, devlink))
2479 goto nla_put_failure;
2480 headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS);
2481 if (!headers_attr)
2482 goto nla_put_failure;
2483
2484 j = 0;
2485 for (; i < dpipe_headers->headers_count; i++) {
2486 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
2487 if (err) {
2488 if (!j)
2489 goto err_table_put;
2490 break;
2491 }
2492 j++;
2493 }
2494 nla_nest_end(skb, headers_attr);
2495 genlmsg_end(skb, hdr);
2496 if (i != dpipe_headers->headers_count)
2497 goto start_again;
2498
2499 send_done:
2500 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2501 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2502 if (!nlh) {
2503 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2504 if (err)
2505 return err;
2506 goto send_done;
2507 }
2508 return genlmsg_reply(skb, info);
2509
2510 nla_put_failure:
2511 err = -EMSGSIZE;
2512 err_table_put:
2513 nlmsg_free(skb);
2514 return err;
2515 }
2516
2517 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
2518 struct genl_info *info)
2519 {
2520 struct devlink *devlink = info->user_ptr[0];
2521
2522 if (!devlink->dpipe_headers)
2523 return -EOPNOTSUPP;
2524 return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
2525 0, devlink->dpipe_headers);
2526 }
2527
2528 static int devlink_dpipe_table_counters_set(struct devlink *devlink,
2529 const char *table_name,
2530 bool enable)
2531 {
2532 struct devlink_dpipe_table *table;
2533
2534 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2535 table_name, devlink);
2536 if (!table)
2537 return -EINVAL;
2538
2539 if (table->counter_control_extern)
2540 return -EOPNOTSUPP;
2541
2542 if (!(table->counters_enabled ^ enable))
2543 return 0;
2544
2545 table->counters_enabled = enable;
2546 if (table->table_ops->counters_set_update)
2547 table->table_ops->counters_set_update(table->priv, enable);
2548 return 0;
2549 }
2550
2551 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
2552 struct genl_info *info)
2553 {
2554 struct devlink *devlink = info->user_ptr[0];
2555 const char *table_name;
2556 bool counters_enable;
2557
2558 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] ||
2559 !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED])
2560 return -EINVAL;
2561
2562 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2563 counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
2564
2565 return devlink_dpipe_table_counters_set(devlink, table_name,
2566 counters_enable);
2567 }
2568
2569 static struct devlink_resource *
2570 devlink_resource_find(struct devlink *devlink,
2571 struct devlink_resource *resource, u64 resource_id)
2572 {
2573 struct list_head *resource_list;
2574
2575 if (resource)
2576 resource_list = &resource->resource_list;
2577 else
2578 resource_list = &devlink->resource_list;
2579
2580 list_for_each_entry(resource, resource_list, list) {
2581 struct devlink_resource *child_resource;
2582
2583 if (resource->id == resource_id)
2584 return resource;
2585
2586 child_resource = devlink_resource_find(devlink, resource,
2587 resource_id);
2588 if (child_resource)
2589 return child_resource;
2590 }
2591 return NULL;
2592 }
2593
2594 static void
2595 devlink_resource_validate_children(struct devlink_resource *resource)
2596 {
2597 struct devlink_resource *child_resource;
2598 bool size_valid = true;
2599 u64 parts_size = 0;
2600
2601 if (list_empty(&resource->resource_list))
2602 goto out;
2603
2604 list_for_each_entry(child_resource, &resource->resource_list, list)
2605 parts_size += child_resource->size_new;
2606
2607 if (parts_size > resource->size_new)
2608 size_valid = false;
2609 out:
2610 resource->size_valid = size_valid;
2611 }
2612
2613 static int
2614 devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
2615 struct netlink_ext_ack *extack)
2616 {
2617 u64 reminder;
2618 int err = 0;
2619
2620 if (size > resource->size_params.size_max) {
2621 NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
2622 err = -EINVAL;
2623 }
2624
2625 if (size < resource->size_params.size_min) {
2626 NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
2627 err = -EINVAL;
2628 }
2629
2630 div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
2631 if (reminder) {
2632 NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
2633 err = -EINVAL;
2634 }
2635
2636 return err;
2637 }
2638
2639 static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
2640 struct genl_info *info)
2641 {
2642 struct devlink *devlink = info->user_ptr[0];
2643 struct devlink_resource *resource;
2644 u64 resource_id;
2645 u64 size;
2646 int err;
2647
2648 if (!info->attrs[DEVLINK_ATTR_RESOURCE_ID] ||
2649 !info->attrs[DEVLINK_ATTR_RESOURCE_SIZE])
2650 return -EINVAL;
2651 resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
2652
2653 resource = devlink_resource_find(devlink, NULL, resource_id);
2654 if (!resource)
2655 return -EINVAL;
2656
2657 size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
2658 err = devlink_resource_validate_size(resource, size, info->extack);
2659 if (err)
2660 return err;
2661
2662 resource->size_new = size;
2663 devlink_resource_validate_children(resource);
2664 if (resource->parent)
2665 devlink_resource_validate_children(resource->parent);
2666 return 0;
2667 }
2668
2669 static int
2670 devlink_resource_size_params_put(struct devlink_resource *resource,
2671 struct sk_buff *skb)
2672 {
2673 struct devlink_resource_size_params *size_params;
2674
2675 size_params = &resource->size_params;
2676 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
2677 size_params->size_granularity, DEVLINK_ATTR_PAD) ||
2678 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
2679 size_params->size_max, DEVLINK_ATTR_PAD) ||
2680 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
2681 size_params->size_min, DEVLINK_ATTR_PAD) ||
2682 nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
2683 return -EMSGSIZE;
2684 return 0;
2685 }
2686
2687 static int devlink_resource_occ_put(struct devlink_resource *resource,
2688 struct sk_buff *skb)
2689 {
2690 if (!resource->occ_get)
2691 return 0;
2692 return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
2693 resource->occ_get(resource->occ_get_priv),
2694 DEVLINK_ATTR_PAD);
2695 }
2696
2697 static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
2698 struct devlink_resource *resource)
2699 {
2700 struct devlink_resource *child_resource;
2701 struct nlattr *child_resource_attr;
2702 struct nlattr *resource_attr;
2703
2704 resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE);
2705 if (!resource_attr)
2706 return -EMSGSIZE;
2707
2708 if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
2709 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
2710 DEVLINK_ATTR_PAD) ||
2711 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
2712 DEVLINK_ATTR_PAD))
2713 goto nla_put_failure;
2714 if (resource->size != resource->size_new)
2715 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
2716 resource->size_new, DEVLINK_ATTR_PAD);
2717 if (devlink_resource_occ_put(resource, skb))
2718 goto nla_put_failure;
2719 if (devlink_resource_size_params_put(resource, skb))
2720 goto nla_put_failure;
2721 if (list_empty(&resource->resource_list))
2722 goto out;
2723
2724 if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
2725 resource->size_valid))
2726 goto nla_put_failure;
2727
2728 child_resource_attr = nla_nest_start_noflag(skb,
2729 DEVLINK_ATTR_RESOURCE_LIST);
2730 if (!child_resource_attr)
2731 goto nla_put_failure;
2732
2733 list_for_each_entry(child_resource, &resource->resource_list, list) {
2734 if (devlink_resource_put(devlink, skb, child_resource))
2735 goto resource_put_failure;
2736 }
2737
2738 nla_nest_end(skb, child_resource_attr);
2739 out:
2740 nla_nest_end(skb, resource_attr);
2741 return 0;
2742
2743 resource_put_failure:
2744 nla_nest_cancel(skb, child_resource_attr);
2745 nla_put_failure:
2746 nla_nest_cancel(skb, resource_attr);
2747 return -EMSGSIZE;
2748 }
2749
2750 static int devlink_resource_fill(struct genl_info *info,
2751 enum devlink_command cmd, int flags)
2752 {
2753 struct devlink *devlink = info->user_ptr[0];
2754 struct devlink_resource *resource;
2755 struct nlattr *resources_attr;
2756 struct sk_buff *skb = NULL;
2757 struct nlmsghdr *nlh;
2758 bool incomplete;
2759 void *hdr;
2760 int i;
2761 int err;
2762
2763 resource = list_first_entry(&devlink->resource_list,
2764 struct devlink_resource, list);
2765 start_again:
2766 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2767 if (err)
2768 return err;
2769
2770 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2771 &devlink_nl_family, NLM_F_MULTI, cmd);
2772 if (!hdr) {
2773 nlmsg_free(skb);
2774 return -EMSGSIZE;
2775 }
2776
2777 if (devlink_nl_put_handle(skb, devlink))
2778 goto nla_put_failure;
2779
2780 resources_attr = nla_nest_start_noflag(skb,
2781 DEVLINK_ATTR_RESOURCE_LIST);
2782 if (!resources_attr)
2783 goto nla_put_failure;
2784
2785 incomplete = false;
2786 i = 0;
2787 list_for_each_entry_from(resource, &devlink->resource_list, list) {
2788 err = devlink_resource_put(devlink, skb, resource);
2789 if (err) {
2790 if (!i)
2791 goto err_resource_put;
2792 incomplete = true;
2793 break;
2794 }
2795 i++;
2796 }
2797 nla_nest_end(skb, resources_attr);
2798 genlmsg_end(skb, hdr);
2799 if (incomplete)
2800 goto start_again;
2801 send_done:
2802 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2803 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2804 if (!nlh) {
2805 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2806 if (err)
2807 return err;
2808 goto send_done;
2809 }
2810 return genlmsg_reply(skb, info);
2811
2812 nla_put_failure:
2813 err = -EMSGSIZE;
2814 err_resource_put:
2815 nlmsg_free(skb);
2816 return err;
2817 }
2818
2819 static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
2820 struct genl_info *info)
2821 {
2822 struct devlink *devlink = info->user_ptr[0];
2823
2824 if (list_empty(&devlink->resource_list))
2825 return -EOPNOTSUPP;
2826
2827 return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
2828 }
2829
2830 static int
2831 devlink_resources_validate(struct devlink *devlink,
2832 struct devlink_resource *resource,
2833 struct genl_info *info)
2834 {
2835 struct list_head *resource_list;
2836 int err = 0;
2837
2838 if (resource)
2839 resource_list = &resource->resource_list;
2840 else
2841 resource_list = &devlink->resource_list;
2842
2843 list_for_each_entry(resource, resource_list, list) {
2844 if (!resource->size_valid)
2845 return -EINVAL;
2846 err = devlink_resources_validate(devlink, resource, info);
2847 if (err)
2848 return err;
2849 }
2850 return err;
2851 }
2852
2853 static struct net *devlink_netns_get(struct sk_buff *skb,
2854 struct genl_info *info)
2855 {
2856 struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID];
2857 struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD];
2858 struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID];
2859 struct net *net;
2860
2861 if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) {
2862 NL_SET_ERR_MSG_MOD(info->extack, "multiple netns identifying attributes specified");
2863 return ERR_PTR(-EINVAL);
2864 }
2865
2866 if (netns_pid_attr) {
2867 net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr));
2868 } else if (netns_fd_attr) {
2869 net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr));
2870 } else if (netns_id_attr) {
2871 net = get_net_ns_by_id(sock_net(skb->sk),
2872 nla_get_u32(netns_id_attr));
2873 if (!net)
2874 net = ERR_PTR(-EINVAL);
2875 } else {
2876 WARN_ON(1);
2877 net = ERR_PTR(-EINVAL);
2878 }
2879 if (IS_ERR(net)) {
2880 NL_SET_ERR_MSG_MOD(info->extack, "Unknown network namespace");
2881 return ERR_PTR(-EINVAL);
2882 }
2883 if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
2884 put_net(net);
2885 return ERR_PTR(-EPERM);
2886 }
2887 return net;
2888 }
2889
2890 static void devlink_param_notify(struct devlink *devlink,
2891 unsigned int port_index,
2892 struct devlink_param_item *param_item,
2893 enum devlink_command cmd);
2894
2895 static void devlink_reload_netns_change(struct devlink *devlink,
2896 struct net *dest_net)
2897 {
2898 struct devlink_param_item *param_item;
2899
2900 /* Userspace needs to be notified about devlink objects
2901 * removed from original and entering new network namespace.
2902 * The rest of the devlink objects are re-created during
2903 * reload process so the notifications are generated separatelly.
2904 */
2905
2906 list_for_each_entry(param_item, &devlink->param_list, list)
2907 devlink_param_notify(devlink, 0, param_item,
2908 DEVLINK_CMD_PARAM_DEL);
2909 devlink_notify(devlink, DEVLINK_CMD_DEL);
2910
2911 __devlink_net_set(devlink, dest_net);
2912
2913 devlink_notify(devlink, DEVLINK_CMD_NEW);
2914 list_for_each_entry(param_item, &devlink->param_list, list)
2915 devlink_param_notify(devlink, 0, param_item,
2916 DEVLINK_CMD_PARAM_NEW);
2917 }
2918
2919 static bool devlink_reload_supported(struct devlink *devlink)
2920 {
2921 return devlink->ops->reload_down && devlink->ops->reload_up;
2922 }
2923
2924 static void devlink_reload_failed_set(struct devlink *devlink,
2925 bool reload_failed)
2926 {
2927 if (devlink->reload_failed == reload_failed)
2928 return;
2929 devlink->reload_failed = reload_failed;
2930 devlink_notify(devlink, DEVLINK_CMD_NEW);
2931 }
2932
2933 bool devlink_is_reload_failed(const struct devlink *devlink)
2934 {
2935 return devlink->reload_failed;
2936 }
2937 EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
2938
2939 static int devlink_reload(struct devlink *devlink, struct net *dest_net,
2940 struct netlink_ext_ack *extack)
2941 {
2942 int err;
2943
2944 if (!devlink->reload_enabled)
2945 return -EOPNOTSUPP;
2946
2947 err = devlink->ops->reload_down(devlink, !!dest_net, extack);
2948 if (err)
2949 return err;
2950
2951 if (dest_net && !net_eq(dest_net, devlink_net(devlink)))
2952 devlink_reload_netns_change(devlink, dest_net);
2953
2954 err = devlink->ops->reload_up(devlink, extack);
2955 devlink_reload_failed_set(devlink, !!err);
2956 return err;
2957 }
2958
2959 static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
2960 {
2961 struct devlink *devlink = info->user_ptr[0];
2962 struct net *dest_net = NULL;
2963 int err;
2964
2965 if (!devlink_reload_supported(devlink) || !devlink->reload_enabled)
2966 return -EOPNOTSUPP;
2967
2968 err = devlink_resources_validate(devlink, NULL, info);
2969 if (err) {
2970 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
2971 return err;
2972 }
2973
2974 if (info->attrs[DEVLINK_ATTR_NETNS_PID] ||
2975 info->attrs[DEVLINK_ATTR_NETNS_FD] ||
2976 info->attrs[DEVLINK_ATTR_NETNS_ID]) {
2977 dest_net = devlink_netns_get(skb, info);
2978 if (IS_ERR(dest_net))
2979 return PTR_ERR(dest_net);
2980 }
2981
2982 err = devlink_reload(devlink, dest_net, info->extack);
2983
2984 if (dest_net)
2985 put_net(dest_net);
2986
2987 return err;
2988 }
2989
2990 static int devlink_nl_flash_update_fill(struct sk_buff *msg,
2991 struct devlink *devlink,
2992 enum devlink_command cmd,
2993 const char *status_msg,
2994 const char *component,
2995 unsigned long done, unsigned long total)
2996 {
2997 void *hdr;
2998
2999 hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
3000 if (!hdr)
3001 return -EMSGSIZE;
3002
3003 if (devlink_nl_put_handle(msg, devlink))
3004 goto nla_put_failure;
3005
3006 if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS)
3007 goto out;
3008
3009 if (status_msg &&
3010 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG,
3011 status_msg))
3012 goto nla_put_failure;
3013 if (component &&
3014 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,
3015 component))
3016 goto nla_put_failure;
3017 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,
3018 done, DEVLINK_ATTR_PAD))
3019 goto nla_put_failure;
3020 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,
3021 total, DEVLINK_ATTR_PAD))
3022 goto nla_put_failure;
3023
3024 out:
3025 genlmsg_end(msg, hdr);
3026 return 0;
3027
3028 nla_put_failure:
3029 genlmsg_cancel(msg, hdr);
3030 return -EMSGSIZE;
3031 }
3032
3033 static void __devlink_flash_update_notify(struct devlink *devlink,
3034 enum devlink_command cmd,
3035 const char *status_msg,
3036 const char *component,
3037 unsigned long done,
3038 unsigned long total)
3039 {
3040 struct sk_buff *msg;
3041 int err;
3042
3043 WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE &&
3044 cmd != DEVLINK_CMD_FLASH_UPDATE_END &&
3045 cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS);
3046
3047 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3048 if (!msg)
3049 return;
3050
3051 err = devlink_nl_flash_update_fill(msg, devlink, cmd, status_msg,
3052 component, done, total);
3053 if (err)
3054 goto out_free_msg;
3055
3056 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
3057 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
3058 return;
3059
3060 out_free_msg:
3061 nlmsg_free(msg);
3062 }
3063
3064 void devlink_flash_update_begin_notify(struct devlink *devlink)
3065 {
3066 __devlink_flash_update_notify(devlink,
3067 DEVLINK_CMD_FLASH_UPDATE,
3068 NULL, NULL, 0, 0);
3069 }
3070 EXPORT_SYMBOL_GPL(devlink_flash_update_begin_notify);
3071
3072 void devlink_flash_update_end_notify(struct devlink *devlink)
3073 {
3074 __devlink_flash_update_notify(devlink,
3075 DEVLINK_CMD_FLASH_UPDATE_END,
3076 NULL, NULL, 0, 0);
3077 }
3078 EXPORT_SYMBOL_GPL(devlink_flash_update_end_notify);
3079
3080 void devlink_flash_update_status_notify(struct devlink *devlink,
3081 const char *status_msg,
3082 const char *component,
3083 unsigned long done,
3084 unsigned long total)
3085 {
3086 __devlink_flash_update_notify(devlink,
3087 DEVLINK_CMD_FLASH_UPDATE_STATUS,
3088 status_msg, component, done, total);
3089 }
3090 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify);
3091
3092 static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
3093 struct genl_info *info)
3094 {
3095 struct devlink *devlink = info->user_ptr[0];
3096 const char *file_name, *component;
3097 struct nlattr *nla_component;
3098
3099 if (!devlink->ops->flash_update)
3100 return -EOPNOTSUPP;
3101
3102 if (!info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME])
3103 return -EINVAL;
3104 file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]);
3105
3106 nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT];
3107 component = nla_component ? nla_data(nla_component) : NULL;
3108
3109 return devlink->ops->flash_update(devlink, file_name, component,
3110 info->extack);
3111 }
3112
3113 static const struct devlink_param devlink_param_generic[] = {
3114 {
3115 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
3116 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
3117 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
3118 },
3119 {
3120 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
3121 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
3122 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
3123 },
3124 {
3125 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
3126 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
3127 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
3128 },
3129 {
3130 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
3131 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
3132 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
3133 },
3134 {
3135 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
3136 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
3137 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
3138 },
3139 {
3140 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
3141 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
3142 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
3143 },
3144 {
3145 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
3146 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
3147 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
3148 },
3149 {
3150 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
3151 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
3152 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
3153 },
3154 {
3155 .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
3156 .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME,
3157 .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE,
3158 },
3159 {
3160 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
3161 .name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME,
3162 .type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE,
3163 },
3164 };
3165
3166 static int devlink_param_generic_verify(const struct devlink_param *param)
3167 {
3168 /* verify it match generic parameter by id and name */
3169 if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
3170 return -EINVAL;
3171 if (strcmp(param->name, devlink_param_generic[param->id].name))
3172 return -ENOENT;
3173
3174 WARN_ON(param->type != devlink_param_generic[param->id].type);
3175
3176 return 0;
3177 }
3178
3179 static int devlink_param_driver_verify(const struct devlink_param *param)
3180 {
3181 int i;
3182
3183 if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
3184 return -EINVAL;
3185 /* verify no such name in generic params */
3186 for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
3187 if (!strcmp(param->name, devlink_param_generic[i].name))
3188 return -EEXIST;
3189
3190 return 0;
3191 }
3192
3193 static struct devlink_param_item *
3194 devlink_param_find_by_name(struct list_head *param_list,
3195 const char *param_name)
3196 {
3197 struct devlink_param_item *param_item;
3198
3199 list_for_each_entry(param_item, param_list, list)
3200 if (!strcmp(param_item->param->name, param_name))
3201 return param_item;
3202 return NULL;
3203 }
3204
3205 static struct devlink_param_item *
3206 devlink_param_find_by_id(struct list_head *param_list, u32 param_id)
3207 {
3208 struct devlink_param_item *param_item;
3209
3210 list_for_each_entry(param_item, param_list, list)
3211 if (param_item->param->id == param_id)
3212 return param_item;
3213 return NULL;
3214 }
3215
3216 static bool
3217 devlink_param_cmode_is_supported(const struct devlink_param *param,
3218 enum devlink_param_cmode cmode)
3219 {
3220 return test_bit(cmode, &param->supported_cmodes);
3221 }
3222
3223 static int devlink_param_get(struct devlink *devlink,
3224 const struct devlink_param *param,
3225 struct devlink_param_gset_ctx *ctx)
3226 {
3227 if (!param->get)
3228 return -EOPNOTSUPP;
3229 return param->get(devlink, param->id, ctx);
3230 }
3231
3232 static int devlink_param_set(struct devlink *devlink,
3233 const struct devlink_param *param,
3234 struct devlink_param_gset_ctx *ctx)
3235 {
3236 if (!param->set)
3237 return -EOPNOTSUPP;
3238 return param->set(devlink, param->id, ctx);
3239 }
3240
3241 static int
3242 devlink_param_type_to_nla_type(enum devlink_param_type param_type)
3243 {
3244 switch (param_type) {
3245 case DEVLINK_PARAM_TYPE_U8:
3246 return NLA_U8;
3247 case DEVLINK_PARAM_TYPE_U16:
3248 return NLA_U16;
3249 case DEVLINK_PARAM_TYPE_U32:
3250 return NLA_U32;
3251 case DEVLINK_PARAM_TYPE_STRING:
3252 return NLA_STRING;
3253 case DEVLINK_PARAM_TYPE_BOOL:
3254 return NLA_FLAG;
3255 default:
3256 return -EINVAL;
3257 }
3258 }
3259
3260 static int
3261 devlink_nl_param_value_fill_one(struct sk_buff *msg,
3262 enum devlink_param_type type,
3263 enum devlink_param_cmode cmode,
3264 union devlink_param_value val)
3265 {
3266 struct nlattr *param_value_attr;
3267
3268 param_value_attr = nla_nest_start_noflag(msg,
3269 DEVLINK_ATTR_PARAM_VALUE);
3270 if (!param_value_attr)
3271 goto nla_put_failure;
3272
3273 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
3274 goto value_nest_cancel;
3275
3276 switch (type) {
3277 case DEVLINK_PARAM_TYPE_U8:
3278 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
3279 goto value_nest_cancel;
3280 break;
3281 case DEVLINK_PARAM_TYPE_U16:
3282 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
3283 goto value_nest_cancel;
3284 break;
3285 case DEVLINK_PARAM_TYPE_U32:
3286 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
3287 goto value_nest_cancel;
3288 break;
3289 case DEVLINK_PARAM_TYPE_STRING:
3290 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
3291 val.vstr))
3292 goto value_nest_cancel;
3293 break;
3294 case DEVLINK_PARAM_TYPE_BOOL:
3295 if (val.vbool &&
3296 nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
3297 goto value_nest_cancel;
3298 break;
3299 }
3300
3301 nla_nest_end(msg, param_value_attr);
3302 return 0;
3303
3304 value_nest_cancel:
3305 nla_nest_cancel(msg, param_value_attr);
3306 nla_put_failure:
3307 return -EMSGSIZE;
3308 }
3309
3310 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
3311 unsigned int port_index,
3312 struct devlink_param_item *param_item,
3313 enum devlink_command cmd,
3314 u32 portid, u32 seq, int flags)
3315 {
3316 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
3317 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
3318 const struct devlink_param *param = param_item->param;
3319 struct devlink_param_gset_ctx ctx;
3320 struct nlattr *param_values_list;
3321 struct nlattr *param_attr;
3322 int nla_type;
3323 void *hdr;
3324 int err;
3325 int i;
3326
3327 /* Get value from driver part to driverinit configuration mode */
3328 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
3329 if (!devlink_param_cmode_is_supported(param, i))
3330 continue;
3331 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
3332 if (!param_item->driverinit_value_valid)
3333 return -EOPNOTSUPP;
3334 param_value[i] = param_item->driverinit_value;
3335 } else {
3336 if (!param_item->published)
3337 continue;
3338 ctx.cmode = i;
3339 err = devlink_param_get(devlink, param, &ctx);
3340 if (err)
3341 return err;
3342 param_value[i] = ctx.val;
3343 }
3344 param_value_set[i] = true;
3345 }
3346
3347 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3348 if (!hdr)
3349 return -EMSGSIZE;
3350
3351 if (devlink_nl_put_handle(msg, devlink))
3352 goto genlmsg_cancel;
3353
3354 if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
3355 cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
3356 cmd == DEVLINK_CMD_PORT_PARAM_DEL)
3357 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
3358 goto genlmsg_cancel;
3359
3360 param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
3361 if (!param_attr)
3362 goto genlmsg_cancel;
3363 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
3364 goto param_nest_cancel;
3365 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
3366 goto param_nest_cancel;
3367
3368 nla_type = devlink_param_type_to_nla_type(param->type);
3369 if (nla_type < 0)
3370 goto param_nest_cancel;
3371 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
3372 goto param_nest_cancel;
3373
3374 param_values_list = nla_nest_start_noflag(msg,
3375 DEVLINK_ATTR_PARAM_VALUES_LIST);
3376 if (!param_values_list)
3377 goto param_nest_cancel;
3378
3379 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
3380 if (!param_value_set[i])
3381 continue;
3382 err = devlink_nl_param_value_fill_one(msg, param->type,
3383 i, param_value[i]);
3384 if (err)
3385 goto values_list_nest_cancel;
3386 }
3387
3388 nla_nest_end(msg, param_values_list);
3389 nla_nest_end(msg, param_attr);
3390 genlmsg_end(msg, hdr);
3391 return 0;
3392
3393 values_list_nest_cancel:
3394 nla_nest_end(msg, param_values_list);
3395 param_nest_cancel:
3396 nla_nest_cancel(msg, param_attr);
3397 genlmsg_cancel:
3398 genlmsg_cancel(msg, hdr);
3399 return -EMSGSIZE;
3400 }
3401
3402 static void devlink_param_notify(struct devlink *devlink,
3403 unsigned int port_index,
3404 struct devlink_param_item *param_item,
3405 enum devlink_command cmd)
3406 {
3407 struct sk_buff *msg;
3408 int err;
3409
3410 WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
3411 cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
3412 cmd != DEVLINK_CMD_PORT_PARAM_DEL);
3413
3414 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3415 if (!msg)
3416 return;
3417 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
3418 0, 0, 0);
3419 if (err) {
3420 nlmsg_free(msg);
3421 return;
3422 }
3423
3424 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
3425 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
3426 }
3427
3428 static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
3429 struct netlink_callback *cb)
3430 {
3431 struct devlink_param_item *param_item;
3432 struct devlink *devlink;
3433 int start = cb->args[0];
3434 int idx = 0;
3435 int err = 0;
3436
3437 mutex_lock(&devlink_mutex);
3438 list_for_each_entry(devlink, &devlink_list, list) {
3439 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3440 continue;
3441 mutex_lock(&devlink->lock);
3442 list_for_each_entry(param_item, &devlink->param_list, list) {
3443 if (idx < start) {
3444 idx++;
3445 continue;
3446 }
3447 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
3448 DEVLINK_CMD_PARAM_GET,
3449 NETLINK_CB(cb->skb).portid,
3450 cb->nlh->nlmsg_seq,
3451 NLM_F_MULTI);
3452 if (err && err != -EOPNOTSUPP) {
3453 mutex_unlock(&devlink->lock);
3454 goto out;
3455 }
3456 idx++;
3457 }
3458 mutex_unlock(&devlink->lock);
3459 }
3460 out:
3461 mutex_unlock(&devlink_mutex);
3462
3463 if (err != -EMSGSIZE)
3464 return err;
3465
3466 cb->args[0] = idx;
3467 return msg->len;
3468 }
3469
3470 static int
3471 devlink_param_type_get_from_info(struct genl_info *info,
3472 enum devlink_param_type *param_type)
3473 {
3474 if (!info->attrs[DEVLINK_ATTR_PARAM_TYPE])
3475 return -EINVAL;
3476
3477 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
3478 case NLA_U8:
3479 *param_type = DEVLINK_PARAM_TYPE_U8;
3480 break;
3481 case NLA_U16:
3482 *param_type = DEVLINK_PARAM_TYPE_U16;
3483 break;
3484 case NLA_U32:
3485 *param_type = DEVLINK_PARAM_TYPE_U32;
3486 break;
3487 case NLA_STRING:
3488 *param_type = DEVLINK_PARAM_TYPE_STRING;
3489 break;
3490 case NLA_FLAG:
3491 *param_type = DEVLINK_PARAM_TYPE_BOOL;
3492 break;
3493 default:
3494 return -EINVAL;
3495 }
3496
3497 return 0;
3498 }
3499
3500 static int
3501 devlink_param_value_get_from_info(const struct devlink_param *param,
3502 struct genl_info *info,
3503 union devlink_param_value *value)
3504 {
3505 struct nlattr *param_data;
3506 int len;
3507
3508 param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];
3509
3510 if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
3511 return -EINVAL;
3512
3513 switch (param->type) {
3514 case DEVLINK_PARAM_TYPE_U8:
3515 if (nla_len(param_data) != sizeof(u8))
3516 return -EINVAL;
3517 value->vu8 = nla_get_u8(param_data);
3518 break;
3519 case DEVLINK_PARAM_TYPE_U16:
3520 if (nla_len(param_data) != sizeof(u16))
3521 return -EINVAL;
3522 value->vu16 = nla_get_u16(param_data);
3523 break;
3524 case DEVLINK_PARAM_TYPE_U32:
3525 if (nla_len(param_data) != sizeof(u32))
3526 return -EINVAL;
3527 value->vu32 = nla_get_u32(param_data);
3528 break;
3529 case DEVLINK_PARAM_TYPE_STRING:
3530 len = strnlen(nla_data(param_data), nla_len(param_data));
3531 if (len == nla_len(param_data) ||
3532 len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
3533 return -EINVAL;
3534 strcpy(value->vstr, nla_data(param_data));
3535 break;
3536 case DEVLINK_PARAM_TYPE_BOOL:
3537 if (param_data && nla_len(param_data))
3538 return -EINVAL;
3539 value->vbool = nla_get_flag(param_data);
3540 break;
3541 }
3542 return 0;
3543 }
3544
3545 static struct devlink_param_item *
3546 devlink_param_get_from_info(struct list_head *param_list,
3547 struct genl_info *info)
3548 {
3549 char *param_name;
3550
3551 if (!info->attrs[DEVLINK_ATTR_PARAM_NAME])
3552 return NULL;
3553
3554 param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
3555 return devlink_param_find_by_name(param_list, param_name);
3556 }
3557
3558 static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
3559 struct genl_info *info)
3560 {
3561 struct devlink *devlink = info->user_ptr[0];
3562 struct devlink_param_item *param_item;
3563 struct sk_buff *msg;
3564 int err;
3565
3566 param_item = devlink_param_get_from_info(&devlink->param_list, info);
3567 if (!param_item)
3568 return -EINVAL;
3569
3570 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3571 if (!msg)
3572 return -ENOMEM;
3573
3574 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
3575 DEVLINK_CMD_PARAM_GET,
3576 info->snd_portid, info->snd_seq, 0);
3577 if (err) {
3578 nlmsg_free(msg);
3579 return err;
3580 }
3581
3582 return genlmsg_reply(msg, info);
3583 }
3584
3585 static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
3586 unsigned int port_index,
3587 struct list_head *param_list,
3588 struct genl_info *info,
3589 enum devlink_command cmd)
3590 {
3591 enum devlink_param_type param_type;
3592 struct devlink_param_gset_ctx ctx;
3593 enum devlink_param_cmode cmode;
3594 struct devlink_param_item *param_item;
3595 const struct devlink_param *param;
3596 union devlink_param_value value;
3597 int err = 0;
3598
3599 param_item = devlink_param_get_from_info(param_list, info);
3600 if (!param_item)
3601 return -EINVAL;
3602 param = param_item->param;
3603 err = devlink_param_type_get_from_info(info, &param_type);
3604 if (err)
3605 return err;
3606 if (param_type != param->type)
3607 return -EINVAL;
3608 err = devlink_param_value_get_from_info(param, info, &value);
3609 if (err)
3610 return err;
3611 if (param->validate) {
3612 err = param->validate(devlink, param->id, value, info->extack);
3613 if (err)
3614 return err;
3615 }
3616
3617 if (!info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE])
3618 return -EINVAL;
3619 cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
3620 if (!devlink_param_cmode_is_supported(param, cmode))
3621 return -EOPNOTSUPP;
3622
3623 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
3624 if (param->type == DEVLINK_PARAM_TYPE_STRING)
3625 strcpy(param_item->driverinit_value.vstr, value.vstr);
3626 else
3627 param_item->driverinit_value = value;
3628 param_item->driverinit_value_valid = true;
3629 } else {
3630 if (!param->set)
3631 return -EOPNOTSUPP;
3632 ctx.val = value;
3633 ctx.cmode = cmode;
3634 err = devlink_param_set(devlink, param, &ctx);
3635 if (err)
3636 return err;
3637 }
3638
3639 devlink_param_notify(devlink, port_index, param_item, cmd);
3640 return 0;
3641 }
3642
3643 static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
3644 struct genl_info *info)
3645 {
3646 struct devlink *devlink = info->user_ptr[0];
3647
3648 return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list,
3649 info, DEVLINK_CMD_PARAM_NEW);
3650 }
3651
3652 static int devlink_param_register_one(struct devlink *devlink,
3653 unsigned int port_index,
3654 struct list_head *param_list,
3655 const struct devlink_param *param,
3656 enum devlink_command cmd)
3657 {
3658 struct devlink_param_item *param_item;
3659
3660 if (devlink_param_find_by_name(param_list, param->name))
3661 return -EEXIST;
3662
3663 if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
3664 WARN_ON(param->get || param->set);
3665 else
3666 WARN_ON(!param->get || !param->set);
3667
3668 param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
3669 if (!param_item)
3670 return -ENOMEM;
3671 param_item->param = param;
3672
3673 list_add_tail(&param_item->list, param_list);
3674 devlink_param_notify(devlink, port_index, param_item, cmd);
3675 return 0;
3676 }
3677
3678 static void devlink_param_unregister_one(struct devlink *devlink,
3679 unsigned int port_index,
3680 struct list_head *param_list,
3681 const struct devlink_param *param,
3682 enum devlink_command cmd)
3683 {
3684 struct devlink_param_item *param_item;
3685
3686 param_item = devlink_param_find_by_name(param_list, param->name);
3687 WARN_ON(!param_item);
3688 devlink_param_notify(devlink, port_index, param_item, cmd);
3689 list_del(&param_item->list);
3690 kfree(param_item);
3691 }
3692
3693 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
3694 struct netlink_callback *cb)
3695 {
3696 struct devlink_param_item *param_item;
3697 struct devlink_port *devlink_port;
3698 struct devlink *devlink;
3699 int start = cb->args[0];
3700 int idx = 0;
3701 int err = 0;
3702
3703 mutex_lock(&devlink_mutex);
3704 list_for_each_entry(devlink, &devlink_list, list) {
3705 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3706 continue;
3707 mutex_lock(&devlink->lock);
3708 list_for_each_entry(devlink_port, &devlink->port_list, list) {
3709 list_for_each_entry(param_item,
3710 &devlink_port->param_list, list) {
3711 if (idx < start) {
3712 idx++;
3713 continue;
3714 }
3715 err = devlink_nl_param_fill(msg,
3716 devlink_port->devlink,
3717 devlink_port->index, param_item,
3718 DEVLINK_CMD_PORT_PARAM_GET,
3719 NETLINK_CB(cb->skb).portid,
3720 cb->nlh->nlmsg_seq,
3721 NLM_F_MULTI);
3722 if (err && err != -EOPNOTSUPP) {
3723 mutex_unlock(&devlink->lock);
3724 goto out;
3725 }
3726 idx++;
3727 }
3728 }
3729 mutex_unlock(&devlink->lock);
3730 }
3731 out:
3732 mutex_unlock(&devlink_mutex);
3733
3734 if (err != -EMSGSIZE)
3735 return err;
3736
3737 cb->args[0] = idx;
3738 return msg->len;
3739 }
3740
3741 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
3742 struct genl_info *info)
3743 {
3744 struct devlink_port *devlink_port = info->user_ptr[0];
3745 struct devlink_param_item *param_item;
3746 struct sk_buff *msg;
3747 int err;
3748
3749 param_item = devlink_param_get_from_info(&devlink_port->param_list,
3750 info);
3751 if (!param_item)
3752 return -EINVAL;
3753
3754 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3755 if (!msg)
3756 return -ENOMEM;
3757
3758 err = devlink_nl_param_fill(msg, devlink_port->devlink,
3759 devlink_port->index, param_item,
3760 DEVLINK_CMD_PORT_PARAM_GET,
3761 info->snd_portid, info->snd_seq, 0);
3762 if (err) {
3763 nlmsg_free(msg);
3764 return err;
3765 }
3766
3767 return genlmsg_reply(msg, info);
3768 }
3769
3770 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
3771 struct genl_info *info)
3772 {
3773 struct devlink_port *devlink_port = info->user_ptr[0];
3774
3775 return __devlink_nl_cmd_param_set_doit(devlink_port->devlink,
3776 devlink_port->index,
3777 &devlink_port->param_list, info,
3778 DEVLINK_CMD_PORT_PARAM_NEW);
3779 }
3780
3781 static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
3782 struct devlink *devlink,
3783 struct devlink_snapshot *snapshot)
3784 {
3785 struct nlattr *snap_attr;
3786 int err;
3787
3788 snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
3789 if (!snap_attr)
3790 return -EINVAL;
3791
3792 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
3793 if (err)
3794 goto nla_put_failure;
3795
3796 nla_nest_end(msg, snap_attr);
3797 return 0;
3798
3799 nla_put_failure:
3800 nla_nest_cancel(msg, snap_attr);
3801 return err;
3802 }
3803
3804 static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
3805 struct devlink *devlink,
3806 struct devlink_region *region)
3807 {
3808 struct devlink_snapshot *snapshot;
3809 struct nlattr *snapshots_attr;
3810 int err;
3811
3812 snapshots_attr = nla_nest_start_noflag(msg,
3813 DEVLINK_ATTR_REGION_SNAPSHOTS);
3814 if (!snapshots_attr)
3815 return -EINVAL;
3816
3817 list_for_each_entry(snapshot, &region->snapshot_list, list) {
3818 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
3819 if (err)
3820 goto nla_put_failure;
3821 }
3822
3823 nla_nest_end(msg, snapshots_attr);
3824 return 0;
3825
3826 nla_put_failure:
3827 nla_nest_cancel(msg, snapshots_attr);
3828 return err;
3829 }
3830
3831 static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
3832 enum devlink_command cmd, u32 portid,
3833 u32 seq, int flags,
3834 struct devlink_region *region)
3835 {
3836 void *hdr;
3837 int err;
3838
3839 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3840 if (!hdr)
3841 return -EMSGSIZE;
3842
3843 err = devlink_nl_put_handle(msg, devlink);
3844 if (err)
3845 goto nla_put_failure;
3846
3847 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name);
3848 if (err)
3849 goto nla_put_failure;
3850
3851 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
3852 region->size,
3853 DEVLINK_ATTR_PAD);
3854 if (err)
3855 goto nla_put_failure;
3856
3857 err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
3858 if (err)
3859 goto nla_put_failure;
3860
3861 genlmsg_end(msg, hdr);
3862 return 0;
3863
3864 nla_put_failure:
3865 genlmsg_cancel(msg, hdr);
3866 return err;
3867 }
3868
3869 static struct sk_buff *
3870 devlink_nl_region_notify_build(struct devlink_region *region,
3871 struct devlink_snapshot *snapshot,
3872 enum devlink_command cmd, u32 portid, u32 seq)
3873 {
3874 struct devlink *devlink = region->devlink;
3875 struct sk_buff *msg;
3876 void *hdr;
3877 int err;
3878
3879
3880 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3881 if (!msg)
3882 return ERR_PTR(-ENOMEM);
3883
3884 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
3885 if (!hdr) {
3886 err = -EMSGSIZE;
3887 goto out_free_msg;
3888 }
3889
3890 err = devlink_nl_put_handle(msg, devlink);
3891 if (err)
3892 goto out_cancel_msg;
3893
3894 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
3895 region->ops->name);
3896 if (err)
3897 goto out_cancel_msg;
3898
3899 if (snapshot) {
3900 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
3901 snapshot->id);
3902 if (err)
3903 goto out_cancel_msg;
3904 } else {
3905 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
3906 region->size, DEVLINK_ATTR_PAD);
3907 if (err)
3908 goto out_cancel_msg;
3909 }
3910 genlmsg_end(msg, hdr);
3911
3912 return msg;
3913
3914 out_cancel_msg:
3915 genlmsg_cancel(msg, hdr);
3916 out_free_msg:
3917 nlmsg_free(msg);
3918 return ERR_PTR(err);
3919 }
3920
3921 static void devlink_nl_region_notify(struct devlink_region *region,
3922 struct devlink_snapshot *snapshot,
3923 enum devlink_command cmd)
3924 {
3925 struct devlink *devlink = region->devlink;
3926 struct sk_buff *msg;
3927
3928 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
3929
3930 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
3931 if (IS_ERR(msg))
3932 return;
3933
3934 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
3935 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
3936 }
3937
3938 /**
3939 * __devlink_snapshot_id_increment - Increment number of snapshots using an id
3940 * @devlink: devlink instance
3941 * @id: the snapshot id
3942 *
3943 * Track when a new snapshot begins using an id. Load the count for the
3944 * given id from the snapshot xarray, increment it, and store it back.
3945 *
3946 * Called when a new snapshot is created with the given id.
3947 *
3948 * The id *must* have been previously allocated by
3949 * devlink_region_snapshot_id_get().
3950 *
3951 * Returns 0 on success, or an error on failure.
3952 */
3953 static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
3954 {
3955 unsigned long count;
3956 void *p;
3957
3958 lockdep_assert_held(&devlink->lock);
3959
3960 p = xa_load(&devlink->snapshot_ids, id);
3961 if (WARN_ON(!p))
3962 return -EINVAL;
3963
3964 if (WARN_ON(!xa_is_value(p)))
3965 return -EINVAL;
3966
3967 count = xa_to_value(p);
3968 count++;
3969
3970 return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
3971 GFP_KERNEL));
3972 }
3973
3974 /**
3975 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
3976 * @devlink: devlink instance
3977 * @id: the snapshot id
3978 *
3979 * Track when a snapshot is deleted and stops using an id. Load the count
3980 * for the given id from the snapshot xarray, decrement it, and store it
3981 * back.
3982 *
3983 * If the count reaches zero, erase this id from the xarray, freeing it
3984 * up for future re-use by devlink_region_snapshot_id_get().
3985 *
3986 * Called when a snapshot using the given id is deleted, and when the
3987 * initial allocator of the id is finished using it.
3988 */
3989 static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
3990 {
3991 unsigned long count;
3992 void *p;
3993
3994 lockdep_assert_held(&devlink->lock);
3995
3996 p = xa_load(&devlink->snapshot_ids, id);
3997 if (WARN_ON(!p))
3998 return;
3999
4000 if (WARN_ON(!xa_is_value(p)))
4001 return;
4002
4003 count = xa_to_value(p);
4004
4005 if (count > 1) {
4006 count--;
4007 xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
4008 GFP_KERNEL);
4009 } else {
4010 /* If this was the last user, we can erase this id */
4011 xa_erase(&devlink->snapshot_ids, id);
4012 }
4013 }
4014
4015 /**
4016 * __devlink_snapshot_id_insert - Insert a specific snapshot ID
4017 * @devlink: devlink instance
4018 * @id: the snapshot id
4019 *
4020 * Mark the given snapshot id as used by inserting a zero value into the
4021 * snapshot xarray.
4022 *
4023 * This must be called while holding the devlink instance lock. Unlike
4024 * devlink_snapshot_id_get, the initial reference count is zero, not one.
4025 * It is expected that the id will immediately be used before
4026 * releasing the devlink instance lock.
4027 *
4028 * Returns zero on success, or an error code if the snapshot id could not
4029 * be inserted.
4030 */
4031 static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
4032 {
4033 lockdep_assert_held(&devlink->lock);
4034
4035 if (WARN_ON(xa_load(&devlink->snapshot_ids, id)))
4036 return -EEXIST;
4037
4038 return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
4039 GFP_KERNEL));
4040 }
4041
4042 /**
4043 * __devlink_region_snapshot_id_get - get snapshot ID
4044 * @devlink: devlink instance
4045 * @id: storage to return snapshot id
4046 *
4047 * Allocates a new snapshot id. Returns zero on success, or a negative
4048 * error on failure. Must be called while holding the devlink instance
4049 * lock.
4050 *
4051 * Snapshot IDs are tracked using an xarray which stores the number of
4052 * users of the snapshot id.
4053 *
4054 * Note that the caller of this function counts as a 'user', in order to
4055 * avoid race conditions. The caller must release its hold on the
4056 * snapshot by using devlink_region_snapshot_id_put.
4057 */
4058 static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
4059 {
4060 lockdep_assert_held(&devlink->lock);
4061
4062 return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
4063 xa_limit_32b, GFP_KERNEL);
4064 }
4065
4066 /**
4067 * __devlink_region_snapshot_create - create a new snapshot
4068 * This will add a new snapshot of a region. The snapshot
4069 * will be stored on the region struct and can be accessed
4070 * from devlink. This is useful for future analyses of snapshots.
4071 * Multiple snapshots can be created on a region.
4072 * The @snapshot_id should be obtained using the getter function.
4073 *
4074 * Must be called only while holding the devlink instance lock.
4075 *
4076 * @region: devlink region of the snapshot
4077 * @data: snapshot data
4078 * @snapshot_id: snapshot id to be created
4079 */
4080 static int
4081 __devlink_region_snapshot_create(struct devlink_region *region,
4082 u8 *data, u32 snapshot_id)
4083 {
4084 struct devlink *devlink = region->devlink;
4085 struct devlink_snapshot *snapshot;
4086 int err;
4087
4088 lockdep_assert_held(&devlink->lock);
4089
4090 /* check if region can hold one more snapshot */
4091 if (region->cur_snapshots == region->max_snapshots)
4092 return -ENOSPC;
4093
4094 if (devlink_region_snapshot_get_by_id(region, snapshot_id))
4095 return -EEXIST;
4096
4097 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
4098 if (!snapshot)
4099 return -ENOMEM;
4100
4101 err = __devlink_snapshot_id_increment(devlink, snapshot_id);
4102 if (err)
4103 goto err_snapshot_id_increment;
4104
4105 snapshot->id = snapshot_id;
4106 snapshot->region = region;
4107 snapshot->data = data;
4108
4109 list_add_tail(&snapshot->list, &region->snapshot_list);
4110
4111 region->cur_snapshots++;
4112
4113 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
4114 return 0;
4115
4116 err_snapshot_id_increment:
4117 kfree(snapshot);
4118 return err;
4119 }
4120
4121 static void devlink_region_snapshot_del(struct devlink_region *region,
4122 struct devlink_snapshot *snapshot)
4123 {
4124 struct devlink *devlink = region->devlink;
4125
4126 lockdep_assert_held(&devlink->lock);
4127
4128 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
4129 region->cur_snapshots--;
4130 list_del(&snapshot->list);
4131 region->ops->destructor(snapshot->data);
4132 __devlink_snapshot_id_decrement(devlink, snapshot->id);
4133 kfree(snapshot);
4134 }
4135
4136 static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
4137 struct genl_info *info)
4138 {
4139 struct devlink *devlink = info->user_ptr[0];
4140 struct devlink_region *region;
4141 const char *region_name;
4142 struct sk_buff *msg;
4143 int err;
4144
4145 if (!info->attrs[DEVLINK_ATTR_REGION_NAME])
4146 return -EINVAL;
4147
4148 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
4149 region = devlink_region_get_by_name(devlink, region_name);
4150 if (!region)
4151 return -EINVAL;
4152
4153 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4154 if (!msg)
4155 return -ENOMEM;
4156
4157 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
4158 info->snd_portid, info->snd_seq, 0,
4159 region);
4160 if (err) {
4161 nlmsg_free(msg);
4162 return err;
4163 }
4164
4165 return genlmsg_reply(msg, info);
4166 }
4167
4168 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
4169 struct netlink_callback *cb)
4170 {
4171 struct devlink_region *region;
4172 struct devlink *devlink;
4173 int start = cb->args[0];
4174 int idx = 0;
4175 int err;
4176
4177 mutex_lock(&devlink_mutex);
4178 list_for_each_entry(devlink, &devlink_list, list) {
4179 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
4180 continue;
4181
4182 mutex_lock(&devlink->lock);
4183 list_for_each_entry(region, &devlink->region_list, list) {
4184 if (idx < start) {
4185 idx++;
4186 continue;
4187 }
4188 err = devlink_nl_region_fill(msg, devlink,
4189 DEVLINK_CMD_REGION_GET,
4190 NETLINK_CB(cb->skb).portid,
4191 cb->nlh->nlmsg_seq,
4192 NLM_F_MULTI, region);
4193 if (err) {
4194 mutex_unlock(&devlink->lock);
4195 goto out;
4196 }
4197 idx++;
4198 }
4199 mutex_unlock(&devlink->lock);
4200 }
4201 out:
4202 mutex_unlock(&devlink_mutex);
4203 cb->args[0] = idx;
4204 return msg->len;
4205 }
4206
4207 static int devlink_nl_cmd_region_del(struct sk_buff *skb,
4208 struct genl_info *info)
4209 {
4210 struct devlink *devlink = info->user_ptr[0];
4211 struct devlink_snapshot *snapshot;
4212 struct devlink_region *region;
4213 const char *region_name;
4214 u32 snapshot_id;
4215
4216 if (!info->attrs[DEVLINK_ATTR_REGION_NAME] ||
4217 !info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID])
4218 return -EINVAL;
4219
4220 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
4221 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
4222
4223 region = devlink_region_get_by_name(devlink, region_name);
4224 if (!region)
4225 return -EINVAL;
4226
4227 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
4228 if (!snapshot)
4229 return -EINVAL;
4230
4231 devlink_region_snapshot_del(region, snapshot);
4232 return 0;
4233 }
4234
4235 static int
4236 devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
4237 {
4238 struct devlink *devlink = info->user_ptr[0];
4239 struct devlink_snapshot *snapshot;
4240 struct nlattr *snapshot_id_attr;
4241 struct devlink_region *region;
4242 const char *region_name;
4243 u32 snapshot_id;
4244 u8 *data;
4245 int err;
4246
4247 if (!info->attrs[DEVLINK_ATTR_REGION_NAME]) {
4248 NL_SET_ERR_MSG_MOD(info->extack, "No region name provided");
4249 return -EINVAL;
4250 }
4251
4252 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
4253 region = devlink_region_get_by_name(devlink, region_name);
4254 if (!region) {
4255 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not exist");
4256 return -EINVAL;
4257 }
4258
4259 if (!region->ops->snapshot) {
4260 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not support taking an immediate snapshot");
4261 return -EOPNOTSUPP;
4262 }
4263
4264 if (region->cur_snapshots == region->max_snapshots) {
4265 NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots");
4266 return -ENOSPC;
4267 }
4268
4269 snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
4270 if (snapshot_id_attr) {
4271 snapshot_id = nla_get_u32(snapshot_id_attr);
4272
4273 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
4274 NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
4275 return -EEXIST;
4276 }
4277
4278 err = __devlink_snapshot_id_insert(devlink, snapshot_id);
4279 if (err)
4280 return err;
4281 } else {
4282 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
4283 if (err) {
4284 NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id");
4285 return err;
4286 }
4287 }
4288
4289 err = region->ops->snapshot(devlink, info->extack, &data);
4290 if (err)
4291 goto err_snapshot_capture;
4292
4293 err = __devlink_region_snapshot_create(region, data, snapshot_id);
4294 if (err)
4295 goto err_snapshot_create;
4296
4297 if (!snapshot_id_attr) {
4298 struct sk_buff *msg;
4299
4300 snapshot = devlink_region_snapshot_get_by_id(region,
4301 snapshot_id);
4302 if (WARN_ON(!snapshot))
4303 return -EINVAL;
4304
4305 msg = devlink_nl_region_notify_build(region, snapshot,
4306 DEVLINK_CMD_REGION_NEW,
4307 info->snd_portid,
4308 info->snd_seq);
4309 err = PTR_ERR_OR_ZERO(msg);
4310 if (err)
4311 goto err_notify;
4312
4313 err = genlmsg_reply(msg, info);
4314 if (err)
4315 goto err_notify;
4316 }
4317
4318 return 0;
4319
4320 err_snapshot_create:
4321 region->ops->destructor(data);
4322 err_snapshot_capture:
4323 __devlink_snapshot_id_decrement(devlink, snapshot_id);
4324 return err;
4325
4326 err_notify:
4327 devlink_region_snapshot_del(region, snapshot);
4328 return err;
4329 }
4330
4331 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
4332 struct devlink *devlink,
4333 u8 *chunk, u32 chunk_size,
4334 u64 addr)
4335 {
4336 struct nlattr *chunk_attr;
4337 int err;
4338
4339 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
4340 if (!chunk_attr)
4341 return -EINVAL;
4342
4343 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
4344 if (err)
4345 goto nla_put_failure;
4346
4347 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
4348 DEVLINK_ATTR_PAD);
4349 if (err)
4350 goto nla_put_failure;
4351
4352 nla_nest_end(msg, chunk_attr);
4353 return 0;
4354
4355 nla_put_failure:
4356 nla_nest_cancel(msg, chunk_attr);
4357 return err;
4358 }
4359
4360 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
4361
4362 static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb,
4363 struct devlink *devlink,
4364 struct devlink_region *region,
4365 struct nlattr **attrs,
4366 u64 start_offset,
4367 u64 end_offset,
4368 u64 *new_offset)
4369 {
4370 struct devlink_snapshot *snapshot;
4371 u64 curr_offset = start_offset;
4372 u32 snapshot_id;
4373 int err = 0;
4374
4375 *new_offset = start_offset;
4376
4377 snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
4378 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
4379 if (!snapshot)
4380 return -EINVAL;
4381
4382 while (curr_offset < end_offset) {
4383 u32 data_size;
4384 u8 *data;
4385
4386 if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE)
4387 data_size = end_offset - curr_offset;
4388 else
4389 data_size = DEVLINK_REGION_READ_CHUNK_SIZE;
4390
4391 data = &snapshot->data[curr_offset];
4392 err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink,
4393 data, data_size,
4394 curr_offset);
4395 if (err)
4396 break;
4397
4398 curr_offset += data_size;
4399 }
4400 *new_offset = curr_offset;
4401
4402 return err;
4403 }
4404
4405 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
4406 struct netlink_callback *cb)
4407 {
4408 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
4409 u64 ret_offset, start_offset, end_offset = U64_MAX;
4410 struct nlattr **attrs = info->attrs;
4411 struct devlink_region *region;
4412 struct nlattr *chunks_attr;
4413 const char *region_name;
4414 struct devlink *devlink;
4415 void *hdr;
4416 int err;
4417
4418 start_offset = *((u64 *)&cb->args[0]);
4419
4420 mutex_lock(&devlink_mutex);
4421 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
4422 if (IS_ERR(devlink)) {
4423 err = PTR_ERR(devlink);
4424 goto out_dev;
4425 }
4426
4427 mutex_lock(&devlink->lock);
4428
4429 if (!attrs[DEVLINK_ATTR_REGION_NAME] ||
4430 !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) {
4431 err = -EINVAL;
4432 goto out_unlock;
4433 }
4434
4435 region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]);
4436 region = devlink_region_get_by_name(devlink, region_name);
4437 if (!region) {
4438 err = -EINVAL;
4439 goto out_unlock;
4440 }
4441
4442 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
4443 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
4444 if (!start_offset)
4445 start_offset =
4446 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
4447
4448 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
4449 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
4450 }
4451
4452 if (end_offset > region->size)
4453 end_offset = region->size;
4454
4455 /* return 0 if there is no further data to read */
4456 if (start_offset == end_offset) {
4457 err = 0;
4458 goto out_unlock;
4459 }
4460
4461 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
4462 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
4463 DEVLINK_CMD_REGION_READ);
4464 if (!hdr) {
4465 err = -EMSGSIZE;
4466 goto out_unlock;
4467 }
4468
4469 err = devlink_nl_put_handle(skb, devlink);
4470 if (err)
4471 goto nla_put_failure;
4472
4473 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
4474 if (err)
4475 goto nla_put_failure;
4476
4477 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
4478 if (!chunks_attr) {
4479 err = -EMSGSIZE;
4480 goto nla_put_failure;
4481 }
4482
4483 err = devlink_nl_region_read_snapshot_fill(skb, devlink,
4484 region, attrs,
4485 start_offset,
4486 end_offset, &ret_offset);
4487
4488 if (err && err != -EMSGSIZE)
4489 goto nla_put_failure;
4490
4491 /* Check if there was any progress done to prevent infinite loop */
4492 if (ret_offset == start_offset) {
4493 err = -EINVAL;
4494 goto nla_put_failure;
4495 }
4496
4497 *((u64 *)&cb->args[0]) = ret_offset;
4498
4499 nla_nest_end(skb, chunks_attr);
4500 genlmsg_end(skb, hdr);
4501 mutex_unlock(&devlink->lock);
4502 mutex_unlock(&devlink_mutex);
4503
4504 return skb->len;
4505
4506 nla_put_failure:
4507 genlmsg_cancel(skb, hdr);
4508 out_unlock:
4509 mutex_unlock(&devlink->lock);
4510 out_dev:
4511 mutex_unlock(&devlink_mutex);
4512 return err;
4513 }
4514
4515 struct devlink_info_req {
4516 struct sk_buff *msg;
4517 };
4518
4519 int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name)
4520 {
4521 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name);
4522 }
4523 EXPORT_SYMBOL_GPL(devlink_info_driver_name_put);
4524
4525 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
4526 {
4527 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
4528 }
4529 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
4530
4531 int devlink_info_board_serial_number_put(struct devlink_info_req *req,
4532 const char *bsn)
4533 {
4534 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER,
4535 bsn);
4536 }
4537 EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put);
4538
4539 static int devlink_info_version_put(struct devlink_info_req *req, int attr,
4540 const char *version_name,
4541 const char *version_value)
4542 {
4543 struct nlattr *nest;
4544 int err;
4545
4546 nest = nla_nest_start_noflag(req->msg, attr);
4547 if (!nest)
4548 return -EMSGSIZE;
4549
4550 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
4551 version_name);
4552 if (err)
4553 goto nla_put_failure;
4554
4555 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
4556 version_value);
4557 if (err)
4558 goto nla_put_failure;
4559
4560 nla_nest_end(req->msg, nest);
4561
4562 return 0;
4563
4564 nla_put_failure:
4565 nla_nest_cancel(req->msg, nest);
4566 return err;
4567 }
4568
4569 int devlink_info_version_fixed_put(struct devlink_info_req *req,
4570 const char *version_name,
4571 const char *version_value)
4572 {
4573 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
4574 version_name, version_value);
4575 }
4576 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
4577
4578 int devlink_info_version_stored_put(struct devlink_info_req *req,
4579 const char *version_name,
4580 const char *version_value)
4581 {
4582 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
4583 version_name, version_value);
4584 }
4585 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
4586
4587 int devlink_info_version_running_put(struct devlink_info_req *req,
4588 const char *version_name,
4589 const char *version_value)
4590 {
4591 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
4592 version_name, version_value);
4593 }
4594 EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
4595
4596 static int
4597 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
4598 enum devlink_command cmd, u32 portid,
4599 u32 seq, int flags, struct netlink_ext_ack *extack)
4600 {
4601 struct devlink_info_req req;
4602 void *hdr;
4603 int err;
4604
4605 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
4606 if (!hdr)
4607 return -EMSGSIZE;
4608
4609 err = -EMSGSIZE;
4610 if (devlink_nl_put_handle(msg, devlink))
4611 goto err_cancel_msg;
4612
4613 req.msg = msg;
4614 err = devlink->ops->info_get(devlink, &req, extack);
4615 if (err)
4616 goto err_cancel_msg;
4617
4618 genlmsg_end(msg, hdr);
4619 return 0;
4620
4621 err_cancel_msg:
4622 genlmsg_cancel(msg, hdr);
4623 return err;
4624 }
4625
4626 static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
4627 struct genl_info *info)
4628 {
4629 struct devlink *devlink = info->user_ptr[0];
4630 struct sk_buff *msg;
4631 int err;
4632
4633 if (!devlink->ops->info_get)
4634 return -EOPNOTSUPP;
4635
4636 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4637 if (!msg)
4638 return -ENOMEM;
4639
4640 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
4641 info->snd_portid, info->snd_seq, 0,
4642 info->extack);
4643 if (err) {
4644 nlmsg_free(msg);
4645 return err;
4646 }
4647
4648 return genlmsg_reply(msg, info);
4649 }
4650
4651 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
4652 struct netlink_callback *cb)
4653 {
4654 struct devlink *devlink;
4655 int start = cb->args[0];
4656 int idx = 0;
4657 int err = 0;
4658
4659 mutex_lock(&devlink_mutex);
4660 list_for_each_entry(devlink, &devlink_list, list) {
4661 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
4662 continue;
4663 if (idx < start) {
4664 idx++;
4665 continue;
4666 }
4667
4668 if (!devlink->ops->info_get) {
4669 idx++;
4670 continue;
4671 }
4672
4673 mutex_lock(&devlink->lock);
4674 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
4675 NETLINK_CB(cb->skb).portid,
4676 cb->nlh->nlmsg_seq, NLM_F_MULTI,
4677 cb->extack);
4678 mutex_unlock(&devlink->lock);
4679 if (err && err != -EOPNOTSUPP)
4680 break;
4681 idx++;
4682 }
4683 mutex_unlock(&devlink_mutex);
4684
4685 if (err != -EMSGSIZE)
4686 return err;
4687
4688 cb->args[0] = idx;
4689 return msg->len;
4690 }
4691
4692 struct devlink_fmsg_item {
4693 struct list_head list;
4694 int attrtype;
4695 u8 nla_type;
4696 u16 len;
4697 int value[];
4698 };
4699
4700 struct devlink_fmsg {
4701 struct list_head item_list;
4702 bool putting_binary; /* This flag forces enclosing of binary data
4703 * in an array brackets. It forces using
4704 * of designated API:
4705 * devlink_fmsg_binary_pair_nest_start()
4706 * devlink_fmsg_binary_pair_nest_end()
4707 */
4708 };
4709
4710 static struct devlink_fmsg *devlink_fmsg_alloc(void)
4711 {
4712 struct devlink_fmsg *fmsg;
4713
4714 fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
4715 if (!fmsg)
4716 return NULL;
4717
4718 INIT_LIST_HEAD(&fmsg->item_list);
4719
4720 return fmsg;
4721 }
4722
4723 static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
4724 {
4725 struct devlink_fmsg_item *item, *tmp;
4726
4727 list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
4728 list_del(&item->list);
4729 kfree(item);
4730 }
4731 kfree(fmsg);
4732 }
4733
4734 static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
4735 int attrtype)
4736 {
4737 struct devlink_fmsg_item *item;
4738
4739 item = kzalloc(sizeof(*item), GFP_KERNEL);
4740 if (!item)
4741 return -ENOMEM;
4742
4743 item->attrtype = attrtype;
4744 list_add_tail(&item->list, &fmsg->item_list);
4745
4746 return 0;
4747 }
4748
4749 int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
4750 {
4751 if (fmsg->putting_binary)
4752 return -EINVAL;
4753
4754 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
4755 }
4756 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
4757
4758 static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
4759 {
4760 if (fmsg->putting_binary)
4761 return -EINVAL;
4762
4763 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
4764 }
4765
4766 int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
4767 {
4768 if (fmsg->putting_binary)
4769 return -EINVAL;
4770
4771 return devlink_fmsg_nest_end(fmsg);
4772 }
4773 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
4774
4775 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
4776
4777 static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
4778 {
4779 struct devlink_fmsg_item *item;
4780
4781 if (fmsg->putting_binary)
4782 return -EINVAL;
4783
4784 if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
4785 return -EMSGSIZE;
4786
4787 item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
4788 if (!item)
4789 return -ENOMEM;
4790
4791 item->nla_type = NLA_NUL_STRING;
4792 item->len = strlen(name) + 1;
4793 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
4794 memcpy(&item->value, name, item->len);
4795 list_add_tail(&item->list, &fmsg->item_list);
4796
4797 return 0;
4798 }
4799
4800 int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
4801 {
4802 int err;
4803
4804 if (fmsg->putting_binary)
4805 return -EINVAL;
4806
4807 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
4808 if (err)
4809 return err;
4810
4811 err = devlink_fmsg_put_name(fmsg, name);
4812 if (err)
4813 return err;
4814
4815 return 0;
4816 }
4817 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
4818
4819 int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
4820 {
4821 if (fmsg->putting_binary)
4822 return -EINVAL;
4823
4824 return devlink_fmsg_nest_end(fmsg);
4825 }
4826 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
4827
4828 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
4829 const char *name)
4830 {
4831 int err;
4832
4833 if (fmsg->putting_binary)
4834 return -EINVAL;
4835
4836 err = devlink_fmsg_pair_nest_start(fmsg, name);
4837 if (err)
4838 return err;
4839
4840 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
4841 if (err)
4842 return err;
4843
4844 return 0;
4845 }
4846 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
4847
4848 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
4849 {
4850 int err;
4851
4852 if (fmsg->putting_binary)
4853 return -EINVAL;
4854
4855 err = devlink_fmsg_nest_end(fmsg);
4856 if (err)
4857 return err;
4858
4859 err = devlink_fmsg_nest_end(fmsg);
4860 if (err)
4861 return err;
4862
4863 return 0;
4864 }
4865 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
4866
4867 int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg,
4868 const char *name)
4869 {
4870 int err;
4871
4872 err = devlink_fmsg_arr_pair_nest_start(fmsg, name);
4873 if (err)
4874 return err;
4875
4876 fmsg->putting_binary = true;
4877 return err;
4878 }
4879 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start);
4880
4881 int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg)
4882 {
4883 if (!fmsg->putting_binary)
4884 return -EINVAL;
4885
4886 fmsg->putting_binary = false;
4887 return devlink_fmsg_arr_pair_nest_end(fmsg);
4888 }
4889 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end);
4890
4891 static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
4892 const void *value, u16 value_len,
4893 u8 value_nla_type)
4894 {
4895 struct devlink_fmsg_item *item;
4896
4897 if (value_len > DEVLINK_FMSG_MAX_SIZE)
4898 return -EMSGSIZE;
4899
4900 item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
4901 if (!item)
4902 return -ENOMEM;
4903
4904 item->nla_type = value_nla_type;
4905 item->len = value_len;
4906 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
4907 memcpy(&item->value, value, item->len);
4908 list_add_tail(&item->list, &fmsg->item_list);
4909
4910 return 0;
4911 }
4912
4913 int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
4914 {
4915 if (fmsg->putting_binary)
4916 return -EINVAL;
4917
4918 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
4919 }
4920 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put);
4921
4922 int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
4923 {
4924 if (fmsg->putting_binary)
4925 return -EINVAL;
4926
4927 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
4928 }
4929 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put);
4930
4931 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
4932 {
4933 if (fmsg->putting_binary)
4934 return -EINVAL;
4935
4936 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
4937 }
4938 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
4939
4940 int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
4941 {
4942 if (fmsg->putting_binary)
4943 return -EINVAL;
4944
4945 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
4946 }
4947 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put);
4948
4949 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
4950 {
4951 if (fmsg->putting_binary)
4952 return -EINVAL;
4953
4954 return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
4955 NLA_NUL_STRING);
4956 }
4957 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
4958
4959 int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
4960 u16 value_len)
4961 {
4962 if (!fmsg->putting_binary)
4963 return -EINVAL;
4964
4965 return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
4966 }
4967 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
4968
4969 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
4970 bool value)
4971 {
4972 int err;
4973
4974 err = devlink_fmsg_pair_nest_start(fmsg, name);
4975 if (err)
4976 return err;
4977
4978 err = devlink_fmsg_bool_put(fmsg, value);
4979 if (err)
4980 return err;
4981
4982 err = devlink_fmsg_pair_nest_end(fmsg);
4983 if (err)
4984 return err;
4985
4986 return 0;
4987 }
4988 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
4989
4990 int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
4991 u8 value)
4992 {
4993 int err;
4994
4995 err = devlink_fmsg_pair_nest_start(fmsg, name);
4996 if (err)
4997 return err;
4998
4999 err = devlink_fmsg_u8_put(fmsg, value);
5000 if (err)
5001 return err;
5002
5003 err = devlink_fmsg_pair_nest_end(fmsg);
5004 if (err)
5005 return err;
5006
5007 return 0;
5008 }
5009 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
5010
5011 int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
5012 u32 value)
5013 {
5014 int err;
5015
5016 err = devlink_fmsg_pair_nest_start(fmsg, name);
5017 if (err)
5018 return err;
5019
5020 err = devlink_fmsg_u32_put(fmsg, value);
5021 if (err)
5022 return err;
5023
5024 err = devlink_fmsg_pair_nest_end(fmsg);
5025 if (err)
5026 return err;
5027
5028 return 0;
5029 }
5030 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
5031
5032 int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
5033 u64 value)
5034 {
5035 int err;
5036
5037 err = devlink_fmsg_pair_nest_start(fmsg, name);
5038 if (err)
5039 return err;
5040
5041 err = devlink_fmsg_u64_put(fmsg, value);
5042 if (err)
5043 return err;
5044
5045 err = devlink_fmsg_pair_nest_end(fmsg);
5046 if (err)
5047 return err;
5048
5049 return 0;
5050 }
5051 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
5052
5053 int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
5054 const char *value)
5055 {
5056 int err;
5057
5058 err = devlink_fmsg_pair_nest_start(fmsg, name);
5059 if (err)
5060 return err;
5061
5062 err = devlink_fmsg_string_put(fmsg, value);
5063 if (err)
5064 return err;
5065
5066 err = devlink_fmsg_pair_nest_end(fmsg);
5067 if (err)
5068 return err;
5069
5070 return 0;
5071 }
5072 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
5073
5074 int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
5075 const void *value, u32 value_len)
5076 {
5077 u32 data_size;
5078 int end_err;
5079 u32 offset;
5080 int err;
5081
5082 err = devlink_fmsg_binary_pair_nest_start(fmsg, name);
5083 if (err)
5084 return err;
5085
5086 for (offset = 0; offset < value_len; offset += data_size) {
5087 data_size = value_len - offset;
5088 if (data_size > DEVLINK_FMSG_MAX_SIZE)
5089 data_size = DEVLINK_FMSG_MAX_SIZE;
5090 err = devlink_fmsg_binary_put(fmsg, value + offset, data_size);
5091 if (err)
5092 break;
5093 /* Exit from loop with a break (instead of
5094 * return) to make sure putting_binary is turned off in
5095 * devlink_fmsg_binary_pair_nest_end
5096 */
5097 }
5098
5099 end_err = devlink_fmsg_binary_pair_nest_end(fmsg);
5100 if (end_err)
5101 err = end_err;
5102
5103 return err;
5104 }
5105 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
5106
5107 static int
5108 devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
5109 {
5110 switch (msg->nla_type) {
5111 case NLA_FLAG:
5112 case NLA_U8:
5113 case NLA_U32:
5114 case NLA_U64:
5115 case NLA_NUL_STRING:
5116 case NLA_BINARY:
5117 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
5118 msg->nla_type);
5119 default:
5120 return -EINVAL;
5121 }
5122 }
5123
5124 static int
5125 devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
5126 {
5127 int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
5128 u8 tmp;
5129
5130 switch (msg->nla_type) {
5131 case NLA_FLAG:
5132 /* Always provide flag data, regardless of its value */
5133 tmp = *(bool *) msg->value;
5134
5135 return nla_put_u8(skb, attrtype, tmp);
5136 case NLA_U8:
5137 return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
5138 case NLA_U32:
5139 return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
5140 case NLA_U64:
5141 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
5142 DEVLINK_ATTR_PAD);
5143 case NLA_NUL_STRING:
5144 return nla_put_string(skb, attrtype, (char *) &msg->value);
5145 case NLA_BINARY:
5146 return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
5147 default:
5148 return -EINVAL;
5149 }
5150 }
5151
5152 static int
5153 devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
5154 int *start)
5155 {
5156 struct devlink_fmsg_item *item;
5157 struct nlattr *fmsg_nlattr;
5158 int i = 0;
5159 int err;
5160
5161 fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG);
5162 if (!fmsg_nlattr)
5163 return -EMSGSIZE;
5164
5165 list_for_each_entry(item, &fmsg->item_list, list) {
5166 if (i < *start) {
5167 i++;
5168 continue;
5169 }
5170
5171 switch (item->attrtype) {
5172 case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
5173 case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
5174 case DEVLINK_ATTR_FMSG_ARR_NEST_START:
5175 case DEVLINK_ATTR_FMSG_NEST_END:
5176 err = nla_put_flag(skb, item->attrtype);
5177 break;
5178 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
5179 err = devlink_fmsg_item_fill_type(item, skb);
5180 if (err)
5181 break;
5182 err = devlink_fmsg_item_fill_data(item, skb);
5183 break;
5184 case DEVLINK_ATTR_FMSG_OBJ_NAME:
5185 err = nla_put_string(skb, item->attrtype,
5186 (char *) &item->value);
5187 break;
5188 default:
5189 err = -EINVAL;
5190 break;
5191 }
5192 if (!err)
5193 *start = ++i;
5194 else
5195 break;
5196 }
5197
5198 nla_nest_end(skb, fmsg_nlattr);
5199 return err;
5200 }
5201
5202 static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
5203 struct genl_info *info,
5204 enum devlink_command cmd, int flags)
5205 {
5206 struct nlmsghdr *nlh;
5207 struct sk_buff *skb;
5208 bool last = false;
5209 int index = 0;
5210 void *hdr;
5211 int err;
5212
5213 while (!last) {
5214 int tmp_index = index;
5215
5216 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
5217 if (!skb)
5218 return -ENOMEM;
5219
5220 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
5221 &devlink_nl_family, flags | NLM_F_MULTI, cmd);
5222 if (!hdr) {
5223 err = -EMSGSIZE;
5224 goto nla_put_failure;
5225 }
5226
5227 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
5228 if (!err)
5229 last = true;
5230 else if (err != -EMSGSIZE || tmp_index == index)
5231 goto nla_put_failure;
5232
5233 genlmsg_end(skb, hdr);
5234 err = genlmsg_reply(skb, info);
5235 if (err)
5236 return err;
5237 }
5238
5239 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
5240 if (!skb)
5241 return -ENOMEM;
5242 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
5243 NLMSG_DONE, 0, flags | NLM_F_MULTI);
5244 if (!nlh) {
5245 err = -EMSGSIZE;
5246 goto nla_put_failure;
5247 }
5248
5249 return genlmsg_reply(skb, info);
5250
5251 nla_put_failure:
5252 nlmsg_free(skb);
5253 return err;
5254 }
5255
5256 static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb,
5257 struct netlink_callback *cb,
5258 enum devlink_command cmd)
5259 {
5260 int index = cb->args[0];
5261 int tmp_index = index;
5262 void *hdr;
5263 int err;
5264
5265 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
5266 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd);
5267 if (!hdr) {
5268 err = -EMSGSIZE;
5269 goto nla_put_failure;
5270 }
5271
5272 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
5273 if ((err && err != -EMSGSIZE) || tmp_index == index)
5274 goto nla_put_failure;
5275
5276 cb->args[0] = index;
5277 genlmsg_end(skb, hdr);
5278 return skb->len;
5279
5280 nla_put_failure:
5281 genlmsg_cancel(skb, hdr);
5282 return err;
5283 }
5284
5285 struct devlink_health_reporter {
5286 struct list_head list;
5287 void *priv;
5288 const struct devlink_health_reporter_ops *ops;
5289 struct devlink *devlink;
5290 struct devlink_fmsg *dump_fmsg;
5291 struct mutex dump_lock; /* lock parallel read/write from dump buffers */
5292 u64 graceful_period;
5293 bool auto_recover;
5294 bool auto_dump;
5295 u8 health_state;
5296 u64 dump_ts;
5297 u64 dump_real_ts;
5298 u64 error_count;
5299 u64 recovery_count;
5300 u64 last_recovery_ts;
5301 refcount_t refcount;
5302 };
5303
5304 void *
5305 devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
5306 {
5307 return reporter->priv;
5308 }
5309 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
5310
5311 static struct devlink_health_reporter *
5312 devlink_health_reporter_find_by_name(struct devlink *devlink,
5313 const char *reporter_name)
5314 {
5315 struct devlink_health_reporter *reporter;
5316
5317 lockdep_assert_held(&devlink->reporters_lock);
5318 list_for_each_entry(reporter, &devlink->reporter_list, list)
5319 if (!strcmp(reporter->ops->name, reporter_name))
5320 return reporter;
5321 return NULL;
5322 }
5323
5324 static struct devlink_health_reporter *
5325 __devlink_health_reporter_create(struct devlink *devlink,
5326 const struct devlink_health_reporter_ops *ops,
5327 u64 graceful_period, void *priv)
5328 {
5329 struct devlink_health_reporter *reporter;
5330
5331 if (WARN_ON(graceful_period && !ops->recover))
5332 return ERR_PTR(-EINVAL);
5333
5334 reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
5335 if (!reporter)
5336 return ERR_PTR(-ENOMEM);
5337
5338 reporter->priv = priv;
5339 reporter->ops = ops;
5340 reporter->devlink = devlink;
5341 reporter->graceful_period = graceful_period;
5342 reporter->auto_recover = !!ops->recover;
5343 reporter->auto_dump = !!ops->dump;
5344 mutex_init(&reporter->dump_lock);
5345 refcount_set(&reporter->refcount, 1);
5346 return reporter;
5347 }
5348
5349 /**
5350 * devlink_health_reporter_create - create devlink health reporter
5351 *
5352 * @devlink: devlink
5353 * @ops: ops
5354 * @graceful_period: to avoid recovery loops, in msecs
5355 * @priv: priv
5356 */
5357 struct devlink_health_reporter *
5358 devlink_health_reporter_create(struct devlink *devlink,
5359 const struct devlink_health_reporter_ops *ops,
5360 u64 graceful_period, void *priv)
5361 {
5362 struct devlink_health_reporter *reporter;
5363
5364 mutex_lock(&devlink->reporters_lock);
5365 if (devlink_health_reporter_find_by_name(devlink, ops->name)) {
5366 reporter = ERR_PTR(-EEXIST);
5367 goto unlock;
5368 }
5369
5370 reporter = __devlink_health_reporter_create(devlink, ops,
5371 graceful_period, priv);
5372 if (IS_ERR(reporter))
5373 goto unlock;
5374
5375 list_add_tail(&reporter->list, &devlink->reporter_list);
5376 unlock:
5377 mutex_unlock(&devlink->reporters_lock);
5378 return reporter;
5379 }
5380 EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
5381
5382 static void
5383 devlink_health_reporter_free(struct devlink_health_reporter *reporter)
5384 {
5385 mutex_destroy(&reporter->dump_lock);
5386 if (reporter->dump_fmsg)
5387 devlink_fmsg_free(reporter->dump_fmsg);
5388 kfree(reporter);
5389 }
5390
5391 static void
5392 devlink_health_reporter_put(struct devlink_health_reporter *reporter)
5393 {
5394 if (refcount_dec_and_test(&reporter->refcount))
5395 devlink_health_reporter_free(reporter);
5396 }
5397
5398 static void
5399 __devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
5400 {
5401 list_del(&reporter->list);
5402 devlink_health_reporter_put(reporter);
5403 }
5404
5405 /**
5406 * devlink_health_reporter_destroy - destroy devlink health reporter
5407 *
5408 * @reporter: devlink health reporter to destroy
5409 */
5410 void
5411 devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
5412 {
5413 mutex_lock(&reporter->devlink->reporters_lock);
5414 __devlink_health_reporter_destroy(reporter);
5415 mutex_unlock(&reporter->devlink->reporters_lock);
5416 }
5417 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
5418
5419 static int
5420 devlink_nl_health_reporter_fill(struct sk_buff *msg,
5421 struct devlink *devlink,
5422 struct devlink_health_reporter *reporter,
5423 enum devlink_command cmd, u32 portid,
5424 u32 seq, int flags)
5425 {
5426 struct nlattr *reporter_attr;
5427 void *hdr;
5428
5429 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5430 if (!hdr)
5431 return -EMSGSIZE;
5432
5433 if (devlink_nl_put_handle(msg, devlink))
5434 goto genlmsg_cancel;
5435
5436 reporter_attr = nla_nest_start_noflag(msg,
5437 DEVLINK_ATTR_HEALTH_REPORTER);
5438 if (!reporter_attr)
5439 goto genlmsg_cancel;
5440 if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
5441 reporter->ops->name))
5442 goto reporter_nest_cancel;
5443 if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
5444 reporter->health_state))
5445 goto reporter_nest_cancel;
5446 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
5447 reporter->error_count, DEVLINK_ATTR_PAD))
5448 goto reporter_nest_cancel;
5449 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
5450 reporter->recovery_count, DEVLINK_ATTR_PAD))
5451 goto reporter_nest_cancel;
5452 if (reporter->ops->recover &&
5453 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
5454 reporter->graceful_period,
5455 DEVLINK_ATTR_PAD))
5456 goto reporter_nest_cancel;
5457 if (reporter->ops->recover &&
5458 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
5459 reporter->auto_recover))
5460 goto reporter_nest_cancel;
5461 if (reporter->dump_fmsg &&
5462 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
5463 jiffies_to_msecs(reporter->dump_ts),
5464 DEVLINK_ATTR_PAD))
5465 goto reporter_nest_cancel;
5466 if (reporter->dump_fmsg &&
5467 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS,
5468 reporter->dump_real_ts, DEVLINK_ATTR_PAD))
5469 goto reporter_nest_cancel;
5470 if (reporter->ops->dump &&
5471 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP,
5472 reporter->auto_dump))
5473 goto reporter_nest_cancel;
5474
5475 nla_nest_end(msg, reporter_attr);
5476 genlmsg_end(msg, hdr);
5477 return 0;
5478
5479 reporter_nest_cancel:
5480 nla_nest_end(msg, reporter_attr);
5481 genlmsg_cancel:
5482 genlmsg_cancel(msg, hdr);
5483 return -EMSGSIZE;
5484 }
5485
5486 static void devlink_recover_notify(struct devlink_health_reporter *reporter,
5487 enum devlink_command cmd)
5488 {
5489 struct sk_buff *msg;
5490 int err;
5491
5492 WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
5493
5494 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5495 if (!msg)
5496 return;
5497
5498 err = devlink_nl_health_reporter_fill(msg, reporter->devlink,
5499 reporter, cmd, 0, 0, 0);
5500 if (err) {
5501 nlmsg_free(msg);
5502 return;
5503 }
5504
5505 genlmsg_multicast_netns(&devlink_nl_family,
5506 devlink_net(reporter->devlink),
5507 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
5508 }
5509
5510 void
5511 devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter)
5512 {
5513 reporter->recovery_count++;
5514 reporter->last_recovery_ts = jiffies;
5515 }
5516 EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done);
5517
5518 static int
5519 devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
5520 void *priv_ctx, struct netlink_ext_ack *extack)
5521 {
5522 int err;
5523
5524 if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY)
5525 return 0;
5526
5527 if (!reporter->ops->recover)
5528 return -EOPNOTSUPP;
5529
5530 err = reporter->ops->recover(reporter, priv_ctx, extack);
5531 if (err)
5532 return err;
5533
5534 devlink_health_reporter_recovery_done(reporter);
5535 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
5536 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
5537
5538 return 0;
5539 }
5540
5541 static void
5542 devlink_health_dump_clear(struct devlink_health_reporter *reporter)
5543 {
5544 if (!reporter->dump_fmsg)
5545 return;
5546 devlink_fmsg_free(reporter->dump_fmsg);
5547 reporter->dump_fmsg = NULL;
5548 }
5549
5550 static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
5551 void *priv_ctx,
5552 struct netlink_ext_ack *extack)
5553 {
5554 int err;
5555
5556 if (!reporter->ops->dump)
5557 return 0;
5558
5559 if (reporter->dump_fmsg)
5560 return 0;
5561
5562 reporter->dump_fmsg = devlink_fmsg_alloc();
5563 if (!reporter->dump_fmsg) {
5564 err = -ENOMEM;
5565 return err;
5566 }
5567
5568 err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
5569 if (err)
5570 goto dump_err;
5571
5572 err = reporter->ops->dump(reporter, reporter->dump_fmsg,
5573 priv_ctx, extack);
5574 if (err)
5575 goto dump_err;
5576
5577 err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
5578 if (err)
5579 goto dump_err;
5580
5581 reporter->dump_ts = jiffies;
5582 reporter->dump_real_ts = ktime_get_real_ns();
5583
5584 return 0;
5585
5586 dump_err:
5587 devlink_health_dump_clear(reporter);
5588 return err;
5589 }
5590
5591 int devlink_health_report(struct devlink_health_reporter *reporter,
5592 const char *msg, void *priv_ctx)
5593 {
5594 enum devlink_health_reporter_state prev_health_state;
5595 struct devlink *devlink = reporter->devlink;
5596 unsigned long recover_ts_threshold;
5597
5598 /* write a log message of the current error */
5599 WARN_ON(!msg);
5600 trace_devlink_health_report(devlink, reporter->ops->name, msg);
5601 reporter->error_count++;
5602 prev_health_state = reporter->health_state;
5603 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
5604 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
5605
5606 /* abort if the previous error wasn't recovered */
5607 recover_ts_threshold = reporter->last_recovery_ts +
5608 msecs_to_jiffies(reporter->graceful_period);
5609 if (reporter->auto_recover &&
5610 (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
5611 (reporter->last_recovery_ts && reporter->recovery_count &&
5612 time_is_after_jiffies(recover_ts_threshold)))) {
5613 trace_devlink_health_recover_aborted(devlink,
5614 reporter->ops->name,
5615 reporter->health_state,
5616 jiffies -
5617 reporter->last_recovery_ts);
5618 return -ECANCELED;
5619 }
5620
5621 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
5622
5623 if (reporter->auto_dump) {
5624 mutex_lock(&reporter->dump_lock);
5625 /* store current dump of current error, for later analysis */
5626 devlink_health_do_dump(reporter, priv_ctx, NULL);
5627 mutex_unlock(&reporter->dump_lock);
5628 }
5629
5630 if (reporter->auto_recover)
5631 return devlink_health_reporter_recover(reporter,
5632 priv_ctx, NULL);
5633
5634 return 0;
5635 }
5636 EXPORT_SYMBOL_GPL(devlink_health_report);
5637
5638 static struct devlink_health_reporter *
5639 devlink_health_reporter_get_from_attrs(struct devlink *devlink,
5640 struct nlattr **attrs)
5641 {
5642 struct devlink_health_reporter *reporter;
5643 char *reporter_name;
5644
5645 if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
5646 return NULL;
5647
5648 reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
5649 mutex_lock(&devlink->reporters_lock);
5650 reporter = devlink_health_reporter_find_by_name(devlink, reporter_name);
5651 if (reporter)
5652 refcount_inc(&reporter->refcount);
5653 mutex_unlock(&devlink->reporters_lock);
5654 return reporter;
5655 }
5656
5657 static struct devlink_health_reporter *
5658 devlink_health_reporter_get_from_info(struct devlink *devlink,
5659 struct genl_info *info)
5660 {
5661 return devlink_health_reporter_get_from_attrs(devlink, info->attrs);
5662 }
5663
5664 static struct devlink_health_reporter *
5665 devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
5666 {
5667 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
5668 struct devlink_health_reporter *reporter;
5669 struct nlattr **attrs = info->attrs;
5670 struct devlink *devlink;
5671
5672 mutex_lock(&devlink_mutex);
5673 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
5674 if (IS_ERR(devlink))
5675 goto unlock;
5676
5677 reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
5678 mutex_unlock(&devlink_mutex);
5679 return reporter;
5680 unlock:
5681 mutex_unlock(&devlink_mutex);
5682 return NULL;
5683 }
5684
5685 void
5686 devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
5687 enum devlink_health_reporter_state state)
5688 {
5689 if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
5690 state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
5691 return;
5692
5693 if (reporter->health_state == state)
5694 return;
5695
5696 reporter->health_state = state;
5697 trace_devlink_health_reporter_state_update(reporter->devlink,
5698 reporter->ops->name, state);
5699 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
5700 }
5701 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
5702
5703 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
5704 struct genl_info *info)
5705 {
5706 struct devlink *devlink = info->user_ptr[0];
5707 struct devlink_health_reporter *reporter;
5708 struct sk_buff *msg;
5709 int err;
5710
5711 reporter = devlink_health_reporter_get_from_info(devlink, info);
5712 if (!reporter)
5713 return -EINVAL;
5714
5715 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5716 if (!msg) {
5717 err = -ENOMEM;
5718 goto out;
5719 }
5720
5721 err = devlink_nl_health_reporter_fill(msg, devlink, reporter,
5722 DEVLINK_CMD_HEALTH_REPORTER_GET,
5723 info->snd_portid, info->snd_seq,
5724 0);
5725 if (err) {
5726 nlmsg_free(msg);
5727 goto out;
5728 }
5729
5730 err = genlmsg_reply(msg, info);
5731 out:
5732 devlink_health_reporter_put(reporter);
5733 return err;
5734 }
5735
5736 static int
5737 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
5738 struct netlink_callback *cb)
5739 {
5740 struct devlink_health_reporter *reporter;
5741 struct devlink *devlink;
5742 int start = cb->args[0];
5743 int idx = 0;
5744 int err;
5745
5746 mutex_lock(&devlink_mutex);
5747 list_for_each_entry(devlink, &devlink_list, list) {
5748 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
5749 continue;
5750 mutex_lock(&devlink->reporters_lock);
5751 list_for_each_entry(reporter, &devlink->reporter_list,
5752 list) {
5753 if (idx < start) {
5754 idx++;
5755 continue;
5756 }
5757 err = devlink_nl_health_reporter_fill(msg, devlink,
5758 reporter,
5759 DEVLINK_CMD_HEALTH_REPORTER_GET,
5760 NETLINK_CB(cb->skb).portid,
5761 cb->nlh->nlmsg_seq,
5762 NLM_F_MULTI);
5763 if (err) {
5764 mutex_unlock(&devlink->reporters_lock);
5765 goto out;
5766 }
5767 idx++;
5768 }
5769 mutex_unlock(&devlink->reporters_lock);
5770 }
5771 out:
5772 mutex_unlock(&devlink_mutex);
5773
5774 cb->args[0] = idx;
5775 return msg->len;
5776 }
5777
5778 static int
5779 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
5780 struct genl_info *info)
5781 {
5782 struct devlink *devlink = info->user_ptr[0];
5783 struct devlink_health_reporter *reporter;
5784 int err;
5785
5786 reporter = devlink_health_reporter_get_from_info(devlink, info);
5787 if (!reporter)
5788 return -EINVAL;
5789
5790 if (!reporter->ops->recover &&
5791 (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
5792 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) {
5793 err = -EOPNOTSUPP;
5794 goto out;
5795 }
5796 if (!reporter->ops->dump &&
5797 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) {
5798 err = -EOPNOTSUPP;
5799 goto out;
5800 }
5801
5802 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
5803 reporter->graceful_period =
5804 nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
5805
5806 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
5807 reporter->auto_recover =
5808 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
5809
5810 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
5811 reporter->auto_dump =
5812 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]);
5813
5814 devlink_health_reporter_put(reporter);
5815 return 0;
5816 out:
5817 devlink_health_reporter_put(reporter);
5818 return err;
5819 }
5820
5821 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
5822 struct genl_info *info)
5823 {
5824 struct devlink *devlink = info->user_ptr[0];
5825 struct devlink_health_reporter *reporter;
5826 int err;
5827
5828 reporter = devlink_health_reporter_get_from_info(devlink, info);
5829 if (!reporter)
5830 return -EINVAL;
5831
5832 err = devlink_health_reporter_recover(reporter, NULL, info->extack);
5833
5834 devlink_health_reporter_put(reporter);
5835 return err;
5836 }
5837
5838 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
5839 struct genl_info *info)
5840 {
5841 struct devlink *devlink = info->user_ptr[0];
5842 struct devlink_health_reporter *reporter;
5843 struct devlink_fmsg *fmsg;
5844 int err;
5845
5846 reporter = devlink_health_reporter_get_from_info(devlink, info);
5847 if (!reporter)
5848 return -EINVAL;
5849
5850 if (!reporter->ops->diagnose) {
5851 devlink_health_reporter_put(reporter);
5852 return -EOPNOTSUPP;
5853 }
5854
5855 fmsg = devlink_fmsg_alloc();
5856 if (!fmsg) {
5857 devlink_health_reporter_put(reporter);
5858 return -ENOMEM;
5859 }
5860
5861 err = devlink_fmsg_obj_nest_start(fmsg);
5862 if (err)
5863 goto out;
5864
5865 err = reporter->ops->diagnose(reporter, fmsg, info->extack);
5866 if (err)
5867 goto out;
5868
5869 err = devlink_fmsg_obj_nest_end(fmsg);
5870 if (err)
5871 goto out;
5872
5873 err = devlink_fmsg_snd(fmsg, info,
5874 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
5875
5876 out:
5877 devlink_fmsg_free(fmsg);
5878 devlink_health_reporter_put(reporter);
5879 return err;
5880 }
5881
5882 static int
5883 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
5884 struct netlink_callback *cb)
5885 {
5886 struct devlink_health_reporter *reporter;
5887 u64 start = cb->args[0];
5888 int err;
5889
5890 reporter = devlink_health_reporter_get_from_cb(cb);
5891 if (!reporter)
5892 return -EINVAL;
5893
5894 if (!reporter->ops->dump) {
5895 err = -EOPNOTSUPP;
5896 goto out;
5897 }
5898 mutex_lock(&reporter->dump_lock);
5899 if (!start) {
5900 err = devlink_health_do_dump(reporter, NULL, cb->extack);
5901 if (err)
5902 goto unlock;
5903 cb->args[1] = reporter->dump_ts;
5904 }
5905 if (!reporter->dump_fmsg || cb->args[1] != reporter->dump_ts) {
5906 NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry");
5907 err = -EAGAIN;
5908 goto unlock;
5909 }
5910
5911 err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
5912 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
5913 unlock:
5914 mutex_unlock(&reporter->dump_lock);
5915 out:
5916 devlink_health_reporter_put(reporter);
5917 return err;
5918 }
5919
5920 static int
5921 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
5922 struct genl_info *info)
5923 {
5924 struct devlink *devlink = info->user_ptr[0];
5925 struct devlink_health_reporter *reporter;
5926
5927 reporter = devlink_health_reporter_get_from_info(devlink, info);
5928 if (!reporter)
5929 return -EINVAL;
5930
5931 if (!reporter->ops->dump) {
5932 devlink_health_reporter_put(reporter);
5933 return -EOPNOTSUPP;
5934 }
5935
5936 mutex_lock(&reporter->dump_lock);
5937 devlink_health_dump_clear(reporter);
5938 mutex_unlock(&reporter->dump_lock);
5939 devlink_health_reporter_put(reporter);
5940 return 0;
5941 }
5942
5943 struct devlink_stats {
5944 u64 rx_bytes;
5945 u64 rx_packets;
5946 struct u64_stats_sync syncp;
5947 };
5948
5949 /**
5950 * struct devlink_trap_policer_item - Packet trap policer attributes.
5951 * @policer: Immutable packet trap policer attributes.
5952 * @rate: Rate in packets / sec.
5953 * @burst: Burst size in packets.
5954 * @list: trap_policer_list member.
5955 *
5956 * Describes packet trap policer attributes. Created by devlink during trap
5957 * policer registration.
5958 */
5959 struct devlink_trap_policer_item {
5960 const struct devlink_trap_policer *policer;
5961 u64 rate;
5962 u64 burst;
5963 struct list_head list;
5964 };
5965
5966 /**
5967 * struct devlink_trap_group_item - Packet trap group attributes.
5968 * @group: Immutable packet trap group attributes.
5969 * @policer_item: Associated policer item. Can be NULL.
5970 * @list: trap_group_list member.
5971 * @stats: Trap group statistics.
5972 *
5973 * Describes packet trap group attributes. Created by devlink during trap
5974 * group registration.
5975 */
5976 struct devlink_trap_group_item {
5977 const struct devlink_trap_group *group;
5978 struct devlink_trap_policer_item *policer_item;
5979 struct list_head list;
5980 struct devlink_stats __percpu *stats;
5981 };
5982
5983 /**
5984 * struct devlink_trap_item - Packet trap attributes.
5985 * @trap: Immutable packet trap attributes.
5986 * @group_item: Associated group item.
5987 * @list: trap_list member.
5988 * @action: Trap action.
5989 * @stats: Trap statistics.
5990 * @priv: Driver private information.
5991 *
5992 * Describes both mutable and immutable packet trap attributes. Created by
5993 * devlink during trap registration and used for all trap related operations.
5994 */
5995 struct devlink_trap_item {
5996 const struct devlink_trap *trap;
5997 struct devlink_trap_group_item *group_item;
5998 struct list_head list;
5999 enum devlink_trap_action action;
6000 struct devlink_stats __percpu *stats;
6001 void *priv;
6002 };
6003
6004 static struct devlink_trap_policer_item *
6005 devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id)
6006 {
6007 struct devlink_trap_policer_item *policer_item;
6008
6009 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
6010 if (policer_item->policer->id == id)
6011 return policer_item;
6012 }
6013
6014 return NULL;
6015 }
6016
6017 static struct devlink_trap_item *
6018 devlink_trap_item_lookup(struct devlink *devlink, const char *name)
6019 {
6020 struct devlink_trap_item *trap_item;
6021
6022 list_for_each_entry(trap_item, &devlink->trap_list, list) {
6023 if (!strcmp(trap_item->trap->name, name))
6024 return trap_item;
6025 }
6026
6027 return NULL;
6028 }
6029
6030 static struct devlink_trap_item *
6031 devlink_trap_item_get_from_info(struct devlink *devlink,
6032 struct genl_info *info)
6033 {
6034 struct nlattr *attr;
6035
6036 if (!info->attrs[DEVLINK_ATTR_TRAP_NAME])
6037 return NULL;
6038 attr = info->attrs[DEVLINK_ATTR_TRAP_NAME];
6039
6040 return devlink_trap_item_lookup(devlink, nla_data(attr));
6041 }
6042
6043 static int
6044 devlink_trap_action_get_from_info(struct genl_info *info,
6045 enum devlink_trap_action *p_trap_action)
6046 {
6047 u8 val;
6048
6049 val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]);
6050 switch (val) {
6051 case DEVLINK_TRAP_ACTION_DROP: /* fall-through */
6052 case DEVLINK_TRAP_ACTION_TRAP: /* fall-through */
6053 case DEVLINK_TRAP_ACTION_MIRROR:
6054 *p_trap_action = val;
6055 break;
6056 default:
6057 return -EINVAL;
6058 }
6059
6060 return 0;
6061 }
6062
6063 static int devlink_trap_metadata_put(struct sk_buff *msg,
6064 const struct devlink_trap *trap)
6065 {
6066 struct nlattr *attr;
6067
6068 attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA);
6069 if (!attr)
6070 return -EMSGSIZE;
6071
6072 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) &&
6073 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT))
6074 goto nla_put_failure;
6075 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) &&
6076 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE))
6077 goto nla_put_failure;
6078
6079 nla_nest_end(msg, attr);
6080
6081 return 0;
6082
6083 nla_put_failure:
6084 nla_nest_cancel(msg, attr);
6085 return -EMSGSIZE;
6086 }
6087
6088 static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
6089 struct devlink_stats *stats)
6090 {
6091 int i;
6092
6093 memset(stats, 0, sizeof(*stats));
6094 for_each_possible_cpu(i) {
6095 struct devlink_stats *cpu_stats;
6096 u64 rx_packets, rx_bytes;
6097 unsigned int start;
6098
6099 cpu_stats = per_cpu_ptr(trap_stats, i);
6100 do {
6101 start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
6102 rx_packets = cpu_stats->rx_packets;
6103 rx_bytes = cpu_stats->rx_bytes;
6104 } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
6105
6106 stats->rx_packets += rx_packets;
6107 stats->rx_bytes += rx_bytes;
6108 }
6109 }
6110
6111 static int devlink_trap_stats_put(struct sk_buff *msg,
6112 struct devlink_stats __percpu *trap_stats)
6113 {
6114 struct devlink_stats stats;
6115 struct nlattr *attr;
6116
6117 devlink_trap_stats_read(trap_stats, &stats);
6118
6119 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
6120 if (!attr)
6121 return -EMSGSIZE;
6122
6123 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
6124 stats.rx_packets, DEVLINK_ATTR_PAD))
6125 goto nla_put_failure;
6126
6127 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
6128 stats.rx_bytes, DEVLINK_ATTR_PAD))
6129 goto nla_put_failure;
6130
6131 nla_nest_end(msg, attr);
6132
6133 return 0;
6134
6135 nla_put_failure:
6136 nla_nest_cancel(msg, attr);
6137 return -EMSGSIZE;
6138 }
6139
6140 static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink,
6141 const struct devlink_trap_item *trap_item,
6142 enum devlink_command cmd, u32 portid, u32 seq,
6143 int flags)
6144 {
6145 struct devlink_trap_group_item *group_item = trap_item->group_item;
6146 void *hdr;
6147 int err;
6148
6149 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6150 if (!hdr)
6151 return -EMSGSIZE;
6152
6153 if (devlink_nl_put_handle(msg, devlink))
6154 goto nla_put_failure;
6155
6156 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
6157 group_item->group->name))
6158 goto nla_put_failure;
6159
6160 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name))
6161 goto nla_put_failure;
6162
6163 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type))
6164 goto nla_put_failure;
6165
6166 if (trap_item->trap->generic &&
6167 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
6168 goto nla_put_failure;
6169
6170 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action))
6171 goto nla_put_failure;
6172
6173 err = devlink_trap_metadata_put(msg, trap_item->trap);
6174 if (err)
6175 goto nla_put_failure;
6176
6177 err = devlink_trap_stats_put(msg, trap_item->stats);
6178 if (err)
6179 goto nla_put_failure;
6180
6181 genlmsg_end(msg, hdr);
6182
6183 return 0;
6184
6185 nla_put_failure:
6186 genlmsg_cancel(msg, hdr);
6187 return -EMSGSIZE;
6188 }
6189
6190 static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
6191 struct genl_info *info)
6192 {
6193 struct netlink_ext_ack *extack = info->extack;
6194 struct devlink *devlink = info->user_ptr[0];
6195 struct devlink_trap_item *trap_item;
6196 struct sk_buff *msg;
6197 int err;
6198
6199 if (list_empty(&devlink->trap_list))
6200 return -EOPNOTSUPP;
6201
6202 trap_item = devlink_trap_item_get_from_info(devlink, info);
6203 if (!trap_item) {
6204 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
6205 return -ENOENT;
6206 }
6207
6208 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6209 if (!msg)
6210 return -ENOMEM;
6211
6212 err = devlink_nl_trap_fill(msg, devlink, trap_item,
6213 DEVLINK_CMD_TRAP_NEW, info->snd_portid,
6214 info->snd_seq, 0);
6215 if (err)
6216 goto err_trap_fill;
6217
6218 return genlmsg_reply(msg, info);
6219
6220 err_trap_fill:
6221 nlmsg_free(msg);
6222 return err;
6223 }
6224
6225 static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg,
6226 struct netlink_callback *cb)
6227 {
6228 struct devlink_trap_item *trap_item;
6229 struct devlink *devlink;
6230 int start = cb->args[0];
6231 int idx = 0;
6232 int err;
6233
6234 mutex_lock(&devlink_mutex);
6235 list_for_each_entry(devlink, &devlink_list, list) {
6236 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
6237 continue;
6238 mutex_lock(&devlink->lock);
6239 list_for_each_entry(trap_item, &devlink->trap_list, list) {
6240 if (idx < start) {
6241 idx++;
6242 continue;
6243 }
6244 err = devlink_nl_trap_fill(msg, devlink, trap_item,
6245 DEVLINK_CMD_TRAP_NEW,
6246 NETLINK_CB(cb->skb).portid,
6247 cb->nlh->nlmsg_seq,
6248 NLM_F_MULTI);
6249 if (err) {
6250 mutex_unlock(&devlink->lock);
6251 goto out;
6252 }
6253 idx++;
6254 }
6255 mutex_unlock(&devlink->lock);
6256 }
6257 out:
6258 mutex_unlock(&devlink_mutex);
6259
6260 cb->args[0] = idx;
6261 return msg->len;
6262 }
6263
6264 static int __devlink_trap_action_set(struct devlink *devlink,
6265 struct devlink_trap_item *trap_item,
6266 enum devlink_trap_action trap_action,
6267 struct netlink_ext_ack *extack)
6268 {
6269 int err;
6270
6271 if (trap_item->action != trap_action &&
6272 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) {
6273 NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping");
6274 return 0;
6275 }
6276
6277 err = devlink->ops->trap_action_set(devlink, trap_item->trap,
6278 trap_action);
6279 if (err)
6280 return err;
6281
6282 trap_item->action = trap_action;
6283
6284 return 0;
6285 }
6286
6287 static int devlink_trap_action_set(struct devlink *devlink,
6288 struct devlink_trap_item *trap_item,
6289 struct genl_info *info)
6290 {
6291 enum devlink_trap_action trap_action;
6292 int err;
6293
6294 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
6295 return 0;
6296
6297 err = devlink_trap_action_get_from_info(info, &trap_action);
6298 if (err) {
6299 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
6300 return -EINVAL;
6301 }
6302
6303 return __devlink_trap_action_set(devlink, trap_item, trap_action,
6304 info->extack);
6305 }
6306
6307 static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
6308 struct genl_info *info)
6309 {
6310 struct netlink_ext_ack *extack = info->extack;
6311 struct devlink *devlink = info->user_ptr[0];
6312 struct devlink_trap_item *trap_item;
6313 int err;
6314
6315 if (list_empty(&devlink->trap_list))
6316 return -EOPNOTSUPP;
6317
6318 trap_item = devlink_trap_item_get_from_info(devlink, info);
6319 if (!trap_item) {
6320 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
6321 return -ENOENT;
6322 }
6323
6324 err = devlink_trap_action_set(devlink, trap_item, info);
6325 if (err)
6326 return err;
6327
6328 return 0;
6329 }
6330
6331 static struct devlink_trap_group_item *
6332 devlink_trap_group_item_lookup(struct devlink *devlink, const char *name)
6333 {
6334 struct devlink_trap_group_item *group_item;
6335
6336 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
6337 if (!strcmp(group_item->group->name, name))
6338 return group_item;
6339 }
6340
6341 return NULL;
6342 }
6343
6344 static struct devlink_trap_group_item *
6345 devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id)
6346 {
6347 struct devlink_trap_group_item *group_item;
6348
6349 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
6350 if (group_item->group->id == id)
6351 return group_item;
6352 }
6353
6354 return NULL;
6355 }
6356
6357 static struct devlink_trap_group_item *
6358 devlink_trap_group_item_get_from_info(struct devlink *devlink,
6359 struct genl_info *info)
6360 {
6361 char *name;
6362
6363 if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME])
6364 return NULL;
6365 name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]);
6366
6367 return devlink_trap_group_item_lookup(devlink, name);
6368 }
6369
6370 static int
6371 devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
6372 const struct devlink_trap_group_item *group_item,
6373 enum devlink_command cmd, u32 portid, u32 seq,
6374 int flags)
6375 {
6376 void *hdr;
6377 int err;
6378
6379 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6380 if (!hdr)
6381 return -EMSGSIZE;
6382
6383 if (devlink_nl_put_handle(msg, devlink))
6384 goto nla_put_failure;
6385
6386 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
6387 group_item->group->name))
6388 goto nla_put_failure;
6389
6390 if (group_item->group->generic &&
6391 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
6392 goto nla_put_failure;
6393
6394 if (group_item->policer_item &&
6395 nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
6396 group_item->policer_item->policer->id))
6397 goto nla_put_failure;
6398
6399 err = devlink_trap_stats_put(msg, group_item->stats);
6400 if (err)
6401 goto nla_put_failure;
6402
6403 genlmsg_end(msg, hdr);
6404
6405 return 0;
6406
6407 nla_put_failure:
6408 genlmsg_cancel(msg, hdr);
6409 return -EMSGSIZE;
6410 }
6411
6412 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
6413 struct genl_info *info)
6414 {
6415 struct netlink_ext_ack *extack = info->extack;
6416 struct devlink *devlink = info->user_ptr[0];
6417 struct devlink_trap_group_item *group_item;
6418 struct sk_buff *msg;
6419 int err;
6420
6421 if (list_empty(&devlink->trap_group_list))
6422 return -EOPNOTSUPP;
6423
6424 group_item = devlink_trap_group_item_get_from_info(devlink, info);
6425 if (!group_item) {
6426 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
6427 return -ENOENT;
6428 }
6429
6430 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6431 if (!msg)
6432 return -ENOMEM;
6433
6434 err = devlink_nl_trap_group_fill(msg, devlink, group_item,
6435 DEVLINK_CMD_TRAP_GROUP_NEW,
6436 info->snd_portid, info->snd_seq, 0);
6437 if (err)
6438 goto err_trap_group_fill;
6439
6440 return genlmsg_reply(msg, info);
6441
6442 err_trap_group_fill:
6443 nlmsg_free(msg);
6444 return err;
6445 }
6446
6447 static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg,
6448 struct netlink_callback *cb)
6449 {
6450 enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW;
6451 struct devlink_trap_group_item *group_item;
6452 u32 portid = NETLINK_CB(cb->skb).portid;
6453 struct devlink *devlink;
6454 int start = cb->args[0];
6455 int idx = 0;
6456 int err;
6457
6458 mutex_lock(&devlink_mutex);
6459 list_for_each_entry(devlink, &devlink_list, list) {
6460 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
6461 continue;
6462 mutex_lock(&devlink->lock);
6463 list_for_each_entry(group_item, &devlink->trap_group_list,
6464 list) {
6465 if (idx < start) {
6466 idx++;
6467 continue;
6468 }
6469 err = devlink_nl_trap_group_fill(msg, devlink,
6470 group_item, cmd,
6471 portid,
6472 cb->nlh->nlmsg_seq,
6473 NLM_F_MULTI);
6474 if (err) {
6475 mutex_unlock(&devlink->lock);
6476 goto out;
6477 }
6478 idx++;
6479 }
6480 mutex_unlock(&devlink->lock);
6481 }
6482 out:
6483 mutex_unlock(&devlink_mutex);
6484
6485 cb->args[0] = idx;
6486 return msg->len;
6487 }
6488
6489 static int
6490 __devlink_trap_group_action_set(struct devlink *devlink,
6491 struct devlink_trap_group_item *group_item,
6492 enum devlink_trap_action trap_action,
6493 struct netlink_ext_ack *extack)
6494 {
6495 const char *group_name = group_item->group->name;
6496 struct devlink_trap_item *trap_item;
6497 int err;
6498
6499 list_for_each_entry(trap_item, &devlink->trap_list, list) {
6500 if (strcmp(trap_item->group_item->group->name, group_name))
6501 continue;
6502 err = __devlink_trap_action_set(devlink, trap_item,
6503 trap_action, extack);
6504 if (err)
6505 return err;
6506 }
6507
6508 return 0;
6509 }
6510
6511 static int
6512 devlink_trap_group_action_set(struct devlink *devlink,
6513 struct devlink_trap_group_item *group_item,
6514 struct genl_info *info, bool *p_modified)
6515 {
6516 enum devlink_trap_action trap_action;
6517 int err;
6518
6519 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
6520 return 0;
6521
6522 err = devlink_trap_action_get_from_info(info, &trap_action);
6523 if (err) {
6524 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
6525 return -EINVAL;
6526 }
6527
6528 err = __devlink_trap_group_action_set(devlink, group_item, trap_action,
6529 info->extack);
6530 if (err)
6531 return err;
6532
6533 *p_modified = true;
6534
6535 return 0;
6536 }
6537
6538 static int devlink_trap_group_set(struct devlink *devlink,
6539 struct devlink_trap_group_item *group_item,
6540 struct genl_info *info)
6541 {
6542 struct devlink_trap_policer_item *policer_item;
6543 struct netlink_ext_ack *extack = info->extack;
6544 const struct devlink_trap_policer *policer;
6545 struct nlattr **attrs = info->attrs;
6546 int err;
6547
6548 if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
6549 return 0;
6550
6551 if (!devlink->ops->trap_group_set)
6552 return -EOPNOTSUPP;
6553
6554 policer_item = group_item->policer_item;
6555 if (attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) {
6556 u32 policer_id;
6557
6558 policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
6559 policer_item = devlink_trap_policer_item_lookup(devlink,
6560 policer_id);
6561 if (policer_id && !policer_item) {
6562 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
6563 return -ENOENT;
6564 }
6565 }
6566 policer = policer_item ? policer_item->policer : NULL;
6567
6568 err = devlink->ops->trap_group_set(devlink, group_item->group, policer);
6569 if (err)
6570 return err;
6571
6572 group_item->policer_item = policer_item;
6573
6574 return 0;
6575 }
6576
6577 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb,
6578 struct genl_info *info)
6579 {
6580 struct netlink_ext_ack *extack = info->extack;
6581 struct devlink *devlink = info->user_ptr[0];
6582 struct devlink_trap_group_item *group_item;
6583 bool modified = false;
6584 int err;
6585
6586 if (list_empty(&devlink->trap_group_list))
6587 return -EOPNOTSUPP;
6588
6589 group_item = devlink_trap_group_item_get_from_info(devlink, info);
6590 if (!group_item) {
6591 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
6592 return -ENOENT;
6593 }
6594
6595 err = devlink_trap_group_action_set(devlink, group_item, info,
6596 &modified);
6597 if (err)
6598 return err;
6599
6600 err = devlink_trap_group_set(devlink, group_item, info);
6601 if (err)
6602 goto err_trap_group_set;
6603
6604 return 0;
6605
6606 err_trap_group_set:
6607 if (modified)
6608 NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already");
6609 return err;
6610 }
6611
6612 static struct devlink_trap_policer_item *
6613 devlink_trap_policer_item_get_from_info(struct devlink *devlink,
6614 struct genl_info *info)
6615 {
6616 u32 id;
6617
6618 if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
6619 return NULL;
6620 id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
6621
6622 return devlink_trap_policer_item_lookup(devlink, id);
6623 }
6624
6625 static int
6626 devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink,
6627 const struct devlink_trap_policer *policer)
6628 {
6629 struct nlattr *attr;
6630 u64 drops;
6631 int err;
6632
6633 if (!devlink->ops->trap_policer_counter_get)
6634 return 0;
6635
6636 err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops);
6637 if (err)
6638 return err;
6639
6640 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
6641 if (!attr)
6642 return -EMSGSIZE;
6643
6644 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
6645 DEVLINK_ATTR_PAD))
6646 goto nla_put_failure;
6647
6648 nla_nest_end(msg, attr);
6649
6650 return 0;
6651
6652 nla_put_failure:
6653 nla_nest_cancel(msg, attr);
6654 return -EMSGSIZE;
6655 }
6656
6657 static int
6658 devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink,
6659 const struct devlink_trap_policer_item *policer_item,
6660 enum devlink_command cmd, u32 portid, u32 seq,
6661 int flags)
6662 {
6663 void *hdr;
6664 int err;
6665
6666 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6667 if (!hdr)
6668 return -EMSGSIZE;
6669
6670 if (devlink_nl_put_handle(msg, devlink))
6671 goto nla_put_failure;
6672
6673 if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
6674 policer_item->policer->id))
6675 goto nla_put_failure;
6676
6677 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE,
6678 policer_item->rate, DEVLINK_ATTR_PAD))
6679 goto nla_put_failure;
6680
6681 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST,
6682 policer_item->burst, DEVLINK_ATTR_PAD))
6683 goto nla_put_failure;
6684
6685 err = devlink_trap_policer_stats_put(msg, devlink,
6686 policer_item->policer);
6687 if (err)
6688 goto nla_put_failure;
6689
6690 genlmsg_end(msg, hdr);
6691
6692 return 0;
6693
6694 nla_put_failure:
6695 genlmsg_cancel(msg, hdr);
6696 return -EMSGSIZE;
6697 }
6698
6699 static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb,
6700 struct genl_info *info)
6701 {
6702 struct devlink_trap_policer_item *policer_item;
6703 struct netlink_ext_ack *extack = info->extack;
6704 struct devlink *devlink = info->user_ptr[0];
6705 struct sk_buff *msg;
6706 int err;
6707
6708 if (list_empty(&devlink->trap_policer_list))
6709 return -EOPNOTSUPP;
6710
6711 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
6712 if (!policer_item) {
6713 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
6714 return -ENOENT;
6715 }
6716
6717 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6718 if (!msg)
6719 return -ENOMEM;
6720
6721 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
6722 DEVLINK_CMD_TRAP_POLICER_NEW,
6723 info->snd_portid, info->snd_seq, 0);
6724 if (err)
6725 goto err_trap_policer_fill;
6726
6727 return genlmsg_reply(msg, info);
6728
6729 err_trap_policer_fill:
6730 nlmsg_free(msg);
6731 return err;
6732 }
6733
6734 static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg,
6735 struct netlink_callback *cb)
6736 {
6737 enum devlink_command cmd = DEVLINK_CMD_TRAP_POLICER_NEW;
6738 struct devlink_trap_policer_item *policer_item;
6739 u32 portid = NETLINK_CB(cb->skb).portid;
6740 struct devlink *devlink;
6741 int start = cb->args[0];
6742 int idx = 0;
6743 int err;
6744
6745 mutex_lock(&devlink_mutex);
6746 list_for_each_entry(devlink, &devlink_list, list) {
6747 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
6748 continue;
6749 mutex_lock(&devlink->lock);
6750 list_for_each_entry(policer_item, &devlink->trap_policer_list,
6751 list) {
6752 if (idx < start) {
6753 idx++;
6754 continue;
6755 }
6756 err = devlink_nl_trap_policer_fill(msg, devlink,
6757 policer_item, cmd,
6758 portid,
6759 cb->nlh->nlmsg_seq,
6760 NLM_F_MULTI);
6761 if (err) {
6762 mutex_unlock(&devlink->lock);
6763 goto out;
6764 }
6765 idx++;
6766 }
6767 mutex_unlock(&devlink->lock);
6768 }
6769 out:
6770 mutex_unlock(&devlink_mutex);
6771
6772 cb->args[0] = idx;
6773 return msg->len;
6774 }
6775
6776 static int
6777 devlink_trap_policer_set(struct devlink *devlink,
6778 struct devlink_trap_policer_item *policer_item,
6779 struct genl_info *info)
6780 {
6781 struct netlink_ext_ack *extack = info->extack;
6782 struct nlattr **attrs = info->attrs;
6783 u64 rate, burst;
6784 int err;
6785
6786 rate = policer_item->rate;
6787 burst = policer_item->burst;
6788
6789 if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE])
6790 rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]);
6791
6792 if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST])
6793 burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]);
6794
6795 if (rate < policer_item->policer->min_rate) {
6796 NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit");
6797 return -EINVAL;
6798 }
6799
6800 if (rate > policer_item->policer->max_rate) {
6801 NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit");
6802 return -EINVAL;
6803 }
6804
6805 if (burst < policer_item->policer->min_burst) {
6806 NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit");
6807 return -EINVAL;
6808 }
6809
6810 if (burst > policer_item->policer->max_burst) {
6811 NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit");
6812 return -EINVAL;
6813 }
6814
6815 err = devlink->ops->trap_policer_set(devlink, policer_item->policer,
6816 rate, burst, info->extack);
6817 if (err)
6818 return err;
6819
6820 policer_item->rate = rate;
6821 policer_item->burst = burst;
6822
6823 return 0;
6824 }
6825
6826 static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb,
6827 struct genl_info *info)
6828 {
6829 struct devlink_trap_policer_item *policer_item;
6830 struct netlink_ext_ack *extack = info->extack;
6831 struct devlink *devlink = info->user_ptr[0];
6832
6833 if (list_empty(&devlink->trap_policer_list))
6834 return -EOPNOTSUPP;
6835
6836 if (!devlink->ops->trap_policer_set)
6837 return -EOPNOTSUPP;
6838
6839 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
6840 if (!policer_item) {
6841 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
6842 return -ENOENT;
6843 }
6844
6845 return devlink_trap_policer_set(devlink, policer_item, info);
6846 }
6847
6848 static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
6849 [DEVLINK_ATTR_UNSPEC] = { .strict_start_type =
6850 DEVLINK_ATTR_TRAP_POLICER_ID },
6851 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
6852 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
6853 [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
6854 [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
6855 [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
6856 [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
6857 [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
6858 [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
6859 [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
6860 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
6861 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
6862 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
6863 [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
6864 [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
6865 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
6866 [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
6867 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
6868 [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64},
6869 [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64},
6870 [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING },
6871 [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 },
6872 [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 },
6873 [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING },
6874 [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 },
6875 [DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .type = NLA_U64 },
6876 [DEVLINK_ATTR_REGION_CHUNK_LEN] = { .type = NLA_U64 },
6877 [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING },
6878 [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 },
6879 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 },
6880 [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING },
6881 [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING },
6882 [DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING },
6883 [DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 },
6884 [DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING },
6885 [DEVLINK_ATTR_NETNS_PID] = { .type = NLA_U32 },
6886 [DEVLINK_ATTR_NETNS_FD] = { .type = NLA_U32 },
6887 [DEVLINK_ATTR_NETNS_ID] = { .type = NLA_U32 },
6888 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP] = { .type = NLA_U8 },
6889 [DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32 },
6890 [DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64 },
6891 [DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64 },
6892 [DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED },
6893 };
6894
6895 static const struct genl_ops devlink_nl_ops[] = {
6896 {
6897 .cmd = DEVLINK_CMD_GET,
6898 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6899 .doit = devlink_nl_cmd_get_doit,
6900 .dumpit = devlink_nl_cmd_get_dumpit,
6901 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6902 /* can be retrieved by unprivileged users */
6903 },
6904 {
6905 .cmd = DEVLINK_CMD_PORT_GET,
6906 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6907 .doit = devlink_nl_cmd_port_get_doit,
6908 .dumpit = devlink_nl_cmd_port_get_dumpit,
6909 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6910 /* can be retrieved by unprivileged users */
6911 },
6912 {
6913 .cmd = DEVLINK_CMD_PORT_SET,
6914 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6915 .doit = devlink_nl_cmd_port_set_doit,
6916 .flags = GENL_ADMIN_PERM,
6917 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6918 },
6919 {
6920 .cmd = DEVLINK_CMD_PORT_SPLIT,
6921 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6922 .doit = devlink_nl_cmd_port_split_doit,
6923 .flags = GENL_ADMIN_PERM,
6924 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6925 DEVLINK_NL_FLAG_NO_LOCK,
6926 },
6927 {
6928 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
6929 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6930 .doit = devlink_nl_cmd_port_unsplit_doit,
6931 .flags = GENL_ADMIN_PERM,
6932 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6933 DEVLINK_NL_FLAG_NO_LOCK,
6934 },
6935 {
6936 .cmd = DEVLINK_CMD_SB_GET,
6937 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6938 .doit = devlink_nl_cmd_sb_get_doit,
6939 .dumpit = devlink_nl_cmd_sb_get_dumpit,
6940 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6941 DEVLINK_NL_FLAG_NEED_SB,
6942 /* can be retrieved by unprivileged users */
6943 },
6944 {
6945 .cmd = DEVLINK_CMD_SB_POOL_GET,
6946 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6947 .doit = devlink_nl_cmd_sb_pool_get_doit,
6948 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
6949 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6950 DEVLINK_NL_FLAG_NEED_SB,
6951 /* can be retrieved by unprivileged users */
6952 },
6953 {
6954 .cmd = DEVLINK_CMD_SB_POOL_SET,
6955 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6956 .doit = devlink_nl_cmd_sb_pool_set_doit,
6957 .flags = GENL_ADMIN_PERM,
6958 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6959 DEVLINK_NL_FLAG_NEED_SB,
6960 },
6961 {
6962 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
6963 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6964 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
6965 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
6966 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
6967 DEVLINK_NL_FLAG_NEED_SB,
6968 /* can be retrieved by unprivileged users */
6969 },
6970 {
6971 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
6972 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6973 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
6974 .flags = GENL_ADMIN_PERM,
6975 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
6976 DEVLINK_NL_FLAG_NEED_SB,
6977 },
6978 {
6979 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
6980 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6981 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
6982 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
6983 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
6984 DEVLINK_NL_FLAG_NEED_SB,
6985 /* can be retrieved by unprivileged users */
6986 },
6987 {
6988 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
6989 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6990 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
6991 .flags = GENL_ADMIN_PERM,
6992 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
6993 DEVLINK_NL_FLAG_NEED_SB,
6994 },
6995 {
6996 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
6997 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6998 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
6999 .flags = GENL_ADMIN_PERM,
7000 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
7001 DEVLINK_NL_FLAG_NEED_SB,
7002 },
7003 {
7004 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
7005 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7006 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
7007 .flags = GENL_ADMIN_PERM,
7008 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
7009 DEVLINK_NL_FLAG_NEED_SB,
7010 },
7011 {
7012 .cmd = DEVLINK_CMD_ESWITCH_GET,
7013 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7014 .doit = devlink_nl_cmd_eswitch_get_doit,
7015 .flags = GENL_ADMIN_PERM,
7016 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
7017 DEVLINK_NL_FLAG_NO_LOCK,
7018 },
7019 {
7020 .cmd = DEVLINK_CMD_ESWITCH_SET,
7021 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7022 .doit = devlink_nl_cmd_eswitch_set_doit,
7023 .flags = GENL_ADMIN_PERM,
7024 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
7025 DEVLINK_NL_FLAG_NO_LOCK,
7026 },
7027 {
7028 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
7029 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7030 .doit = devlink_nl_cmd_dpipe_table_get,
7031 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7032 /* can be retrieved by unprivileged users */
7033 },
7034 {
7035 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
7036 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7037 .doit = devlink_nl_cmd_dpipe_entries_get,
7038 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7039 /* can be retrieved by unprivileged users */
7040 },
7041 {
7042 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
7043 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7044 .doit = devlink_nl_cmd_dpipe_headers_get,
7045 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7046 /* can be retrieved by unprivileged users */
7047 },
7048 {
7049 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
7050 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7051 .doit = devlink_nl_cmd_dpipe_table_counters_set,
7052 .flags = GENL_ADMIN_PERM,
7053 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7054 },
7055 {
7056 .cmd = DEVLINK_CMD_RESOURCE_SET,
7057 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7058 .doit = devlink_nl_cmd_resource_set,
7059 .flags = GENL_ADMIN_PERM,
7060 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7061 },
7062 {
7063 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
7064 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7065 .doit = devlink_nl_cmd_resource_dump,
7066 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7067 /* can be retrieved by unprivileged users */
7068 },
7069 {
7070 .cmd = DEVLINK_CMD_RELOAD,
7071 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7072 .doit = devlink_nl_cmd_reload,
7073 .flags = GENL_ADMIN_PERM,
7074 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
7075 DEVLINK_NL_FLAG_NO_LOCK,
7076 },
7077 {
7078 .cmd = DEVLINK_CMD_PARAM_GET,
7079 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7080 .doit = devlink_nl_cmd_param_get_doit,
7081 .dumpit = devlink_nl_cmd_param_get_dumpit,
7082 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7083 /* can be retrieved by unprivileged users */
7084 },
7085 {
7086 .cmd = DEVLINK_CMD_PARAM_SET,
7087 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7088 .doit = devlink_nl_cmd_param_set_doit,
7089 .flags = GENL_ADMIN_PERM,
7090 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7091 },
7092 {
7093 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
7094 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7095 .doit = devlink_nl_cmd_port_param_get_doit,
7096 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
7097 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7098 /* can be retrieved by unprivileged users */
7099 },
7100 {
7101 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
7102 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7103 .doit = devlink_nl_cmd_port_param_set_doit,
7104 .flags = GENL_ADMIN_PERM,
7105 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
7106 },
7107 {
7108 .cmd = DEVLINK_CMD_REGION_GET,
7109 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7110 .doit = devlink_nl_cmd_region_get_doit,
7111 .dumpit = devlink_nl_cmd_region_get_dumpit,
7112 .flags = GENL_ADMIN_PERM,
7113 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7114 },
7115 {
7116 .cmd = DEVLINK_CMD_REGION_NEW,
7117 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7118 .doit = devlink_nl_cmd_region_new,
7119 .flags = GENL_ADMIN_PERM,
7120 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7121 },
7122 {
7123 .cmd = DEVLINK_CMD_REGION_DEL,
7124 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7125 .doit = devlink_nl_cmd_region_del,
7126 .flags = GENL_ADMIN_PERM,
7127 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7128 },
7129 {
7130 .cmd = DEVLINK_CMD_REGION_READ,
7131 .validate = GENL_DONT_VALIDATE_STRICT |
7132 GENL_DONT_VALIDATE_DUMP_STRICT,
7133 .dumpit = devlink_nl_cmd_region_read_dumpit,
7134 .flags = GENL_ADMIN_PERM,
7135 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7136 },
7137 {
7138 .cmd = DEVLINK_CMD_INFO_GET,
7139 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7140 .doit = devlink_nl_cmd_info_get_doit,
7141 .dumpit = devlink_nl_cmd_info_get_dumpit,
7142 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7143 /* can be retrieved by unprivileged users */
7144 },
7145 {
7146 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
7147 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7148 .doit = devlink_nl_cmd_health_reporter_get_doit,
7149 .dumpit = devlink_nl_cmd_health_reporter_get_dumpit,
7150 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
7151 DEVLINK_NL_FLAG_NO_LOCK,
7152 /* can be retrieved by unprivileged users */
7153 },
7154 {
7155 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
7156 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7157 .doit = devlink_nl_cmd_health_reporter_set_doit,
7158 .flags = GENL_ADMIN_PERM,
7159 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
7160 DEVLINK_NL_FLAG_NO_LOCK,
7161 },
7162 {
7163 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
7164 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7165 .doit = devlink_nl_cmd_health_reporter_recover_doit,
7166 .flags = GENL_ADMIN_PERM,
7167 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
7168 DEVLINK_NL_FLAG_NO_LOCK,
7169 },
7170 {
7171 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
7172 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7173 .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
7174 .flags = GENL_ADMIN_PERM,
7175 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
7176 DEVLINK_NL_FLAG_NO_LOCK,
7177 },
7178 {
7179 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
7180 .validate = GENL_DONT_VALIDATE_STRICT |
7181 GENL_DONT_VALIDATE_DUMP_STRICT,
7182 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
7183 .flags = GENL_ADMIN_PERM,
7184 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
7185 DEVLINK_NL_FLAG_NO_LOCK,
7186 },
7187 {
7188 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
7189 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7190 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
7191 .flags = GENL_ADMIN_PERM,
7192 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
7193 DEVLINK_NL_FLAG_NO_LOCK,
7194 },
7195 {
7196 .cmd = DEVLINK_CMD_FLASH_UPDATE,
7197 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7198 .doit = devlink_nl_cmd_flash_update,
7199 .flags = GENL_ADMIN_PERM,
7200 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7201 },
7202 {
7203 .cmd = DEVLINK_CMD_TRAP_GET,
7204 .doit = devlink_nl_cmd_trap_get_doit,
7205 .dumpit = devlink_nl_cmd_trap_get_dumpit,
7206 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7207 /* can be retrieved by unprivileged users */
7208 },
7209 {
7210 .cmd = DEVLINK_CMD_TRAP_SET,
7211 .doit = devlink_nl_cmd_trap_set_doit,
7212 .flags = GENL_ADMIN_PERM,
7213 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7214 },
7215 {
7216 .cmd = DEVLINK_CMD_TRAP_GROUP_GET,
7217 .doit = devlink_nl_cmd_trap_group_get_doit,
7218 .dumpit = devlink_nl_cmd_trap_group_get_dumpit,
7219 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7220 /* can be retrieved by unprivileged users */
7221 },
7222 {
7223 .cmd = DEVLINK_CMD_TRAP_GROUP_SET,
7224 .doit = devlink_nl_cmd_trap_group_set_doit,
7225 .flags = GENL_ADMIN_PERM,
7226 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7227 },
7228 {
7229 .cmd = DEVLINK_CMD_TRAP_POLICER_GET,
7230 .doit = devlink_nl_cmd_trap_policer_get_doit,
7231 .dumpit = devlink_nl_cmd_trap_policer_get_dumpit,
7232 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7233 /* can be retrieved by unprivileged users */
7234 },
7235 {
7236 .cmd = DEVLINK_CMD_TRAP_POLICER_SET,
7237 .doit = devlink_nl_cmd_trap_policer_set_doit,
7238 .flags = GENL_ADMIN_PERM,
7239 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
7240 },
7241 };
7242
7243 static struct genl_family devlink_nl_family __ro_after_init = {
7244 .name = DEVLINK_GENL_NAME,
7245 .version = DEVLINK_GENL_VERSION,
7246 .maxattr = DEVLINK_ATTR_MAX,
7247 .policy = devlink_nl_policy,
7248 .netnsok = true,
7249 .pre_doit = devlink_nl_pre_doit,
7250 .post_doit = devlink_nl_post_doit,
7251 .module = THIS_MODULE,
7252 .ops = devlink_nl_ops,
7253 .n_ops = ARRAY_SIZE(devlink_nl_ops),
7254 .mcgrps = devlink_nl_mcgrps,
7255 .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps),
7256 };
7257
7258 /**
7259 * devlink_alloc - Allocate new devlink instance resources
7260 *
7261 * @ops: ops
7262 * @priv_size: size of user private data
7263 *
7264 * Allocate new devlink instance resources, including devlink index
7265 * and name.
7266 */
7267 struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
7268 {
7269 struct devlink *devlink;
7270
7271 if (WARN_ON(!ops))
7272 return NULL;
7273
7274 devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
7275 if (!devlink)
7276 return NULL;
7277 devlink->ops = ops;
7278 xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC);
7279 __devlink_net_set(devlink, &init_net);
7280 INIT_LIST_HEAD(&devlink->port_list);
7281 INIT_LIST_HEAD(&devlink->sb_list);
7282 INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
7283 INIT_LIST_HEAD(&devlink->resource_list);
7284 INIT_LIST_HEAD(&devlink->param_list);
7285 INIT_LIST_HEAD(&devlink->region_list);
7286 INIT_LIST_HEAD(&devlink->reporter_list);
7287 INIT_LIST_HEAD(&devlink->trap_list);
7288 INIT_LIST_HEAD(&devlink->trap_group_list);
7289 INIT_LIST_HEAD(&devlink->trap_policer_list);
7290 mutex_init(&devlink->lock);
7291 mutex_init(&devlink->reporters_lock);
7292 return devlink;
7293 }
7294 EXPORT_SYMBOL_GPL(devlink_alloc);
7295
7296 /**
7297 * devlink_register - Register devlink instance
7298 *
7299 * @devlink: devlink
7300 * @dev: parent device
7301 */
7302 int devlink_register(struct devlink *devlink, struct device *dev)
7303 {
7304 mutex_lock(&devlink_mutex);
7305 devlink->dev = dev;
7306 devlink->registered = true;
7307 list_add_tail(&devlink->list, &devlink_list);
7308 devlink_notify(devlink, DEVLINK_CMD_NEW);
7309 mutex_unlock(&devlink_mutex);
7310 return 0;
7311 }
7312 EXPORT_SYMBOL_GPL(devlink_register);
7313
7314 /**
7315 * devlink_unregister - Unregister devlink instance
7316 *
7317 * @devlink: devlink
7318 */
7319 void devlink_unregister(struct devlink *devlink)
7320 {
7321 mutex_lock(&devlink_mutex);
7322 WARN_ON(devlink_reload_supported(devlink) &&
7323 devlink->reload_enabled);
7324 devlink_notify(devlink, DEVLINK_CMD_DEL);
7325 list_del(&devlink->list);
7326 mutex_unlock(&devlink_mutex);
7327 }
7328 EXPORT_SYMBOL_GPL(devlink_unregister);
7329
7330 /**
7331 * devlink_reload_enable - Enable reload of devlink instance
7332 *
7333 * @devlink: devlink
7334 *
7335 * Should be called at end of device initialization
7336 * process when reload operation is supported.
7337 */
7338 void devlink_reload_enable(struct devlink *devlink)
7339 {
7340 mutex_lock(&devlink_mutex);
7341 devlink->reload_enabled = true;
7342 mutex_unlock(&devlink_mutex);
7343 }
7344 EXPORT_SYMBOL_GPL(devlink_reload_enable);
7345
7346 /**
7347 * devlink_reload_disable - Disable reload of devlink instance
7348 *
7349 * @devlink: devlink
7350 *
7351 * Should be called at the beginning of device cleanup
7352 * process when reload operation is supported.
7353 */
7354 void devlink_reload_disable(struct devlink *devlink)
7355 {
7356 mutex_lock(&devlink_mutex);
7357 /* Mutex is taken which ensures that no reload operation is in
7358 * progress while setting up forbidded flag.
7359 */
7360 devlink->reload_enabled = false;
7361 mutex_unlock(&devlink_mutex);
7362 }
7363 EXPORT_SYMBOL_GPL(devlink_reload_disable);
7364
7365 /**
7366 * devlink_free - Free devlink instance resources
7367 *
7368 * @devlink: devlink
7369 */
7370 void devlink_free(struct devlink *devlink)
7371 {
7372 mutex_destroy(&devlink->reporters_lock);
7373 mutex_destroy(&devlink->lock);
7374 WARN_ON(!list_empty(&devlink->trap_policer_list));
7375 WARN_ON(!list_empty(&devlink->trap_group_list));
7376 WARN_ON(!list_empty(&devlink->trap_list));
7377 WARN_ON(!list_empty(&devlink->reporter_list));
7378 WARN_ON(!list_empty(&devlink->region_list));
7379 WARN_ON(!list_empty(&devlink->param_list));
7380 WARN_ON(!list_empty(&devlink->resource_list));
7381 WARN_ON(!list_empty(&devlink->dpipe_table_list));
7382 WARN_ON(!list_empty(&devlink->sb_list));
7383 WARN_ON(!list_empty(&devlink->port_list));
7384
7385 xa_destroy(&devlink->snapshot_ids);
7386
7387 kfree(devlink);
7388 }
7389 EXPORT_SYMBOL_GPL(devlink_free);
7390
7391 static void devlink_port_type_warn(struct work_struct *work)
7392 {
7393 WARN(true, "Type was not set for devlink port.");
7394 }
7395
7396 static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
7397 {
7398 /* Ignore CPU and DSA flavours. */
7399 return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU &&
7400 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA;
7401 }
7402
7403 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
7404
7405 static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port)
7406 {
7407 if (!devlink_port_type_should_warn(devlink_port))
7408 return;
7409 /* Schedule a work to WARN in case driver does not set port
7410 * type within timeout.
7411 */
7412 schedule_delayed_work(&devlink_port->type_warn_dw,
7413 DEVLINK_PORT_TYPE_WARN_TIMEOUT);
7414 }
7415
7416 static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port)
7417 {
7418 if (!devlink_port_type_should_warn(devlink_port))
7419 return;
7420 cancel_delayed_work_sync(&devlink_port->type_warn_dw);
7421 }
7422
7423 /**
7424 * devlink_port_register - Register devlink port
7425 *
7426 * @devlink: devlink
7427 * @devlink_port: devlink port
7428 * @port_index: driver-specific numerical identifier of the port
7429 *
7430 * Register devlink port with provided port index. User can use
7431 * any indexing, even hw-related one. devlink_port structure
7432 * is convenient to be embedded inside user driver private structure.
7433 * Note that the caller should take care of zeroing the devlink_port
7434 * structure.
7435 */
7436 int devlink_port_register(struct devlink *devlink,
7437 struct devlink_port *devlink_port,
7438 unsigned int port_index)
7439 {
7440 mutex_lock(&devlink->lock);
7441 if (devlink_port_index_exists(devlink, port_index)) {
7442 mutex_unlock(&devlink->lock);
7443 return -EEXIST;
7444 }
7445 devlink_port->devlink = devlink;
7446 devlink_port->index = port_index;
7447 devlink_port->registered = true;
7448 spin_lock_init(&devlink_port->type_lock);
7449 list_add_tail(&devlink_port->list, &devlink->port_list);
7450 INIT_LIST_HEAD(&devlink_port->param_list);
7451 mutex_unlock(&devlink->lock);
7452 INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
7453 devlink_port_type_warn_schedule(devlink_port);
7454 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
7455 return 0;
7456 }
7457 EXPORT_SYMBOL_GPL(devlink_port_register);
7458
7459 /**
7460 * devlink_port_unregister - Unregister devlink port
7461 *
7462 * @devlink_port: devlink port
7463 */
7464 void devlink_port_unregister(struct devlink_port *devlink_port)
7465 {
7466 struct devlink *devlink = devlink_port->devlink;
7467
7468 devlink_port_type_warn_cancel(devlink_port);
7469 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
7470 mutex_lock(&devlink->lock);
7471 list_del(&devlink_port->list);
7472 mutex_unlock(&devlink->lock);
7473 }
7474 EXPORT_SYMBOL_GPL(devlink_port_unregister);
7475
7476 static void __devlink_port_type_set(struct devlink_port *devlink_port,
7477 enum devlink_port_type type,
7478 void *type_dev)
7479 {
7480 if (WARN_ON(!devlink_port->registered))
7481 return;
7482 devlink_port_type_warn_cancel(devlink_port);
7483 spin_lock_bh(&devlink_port->type_lock);
7484 devlink_port->type = type;
7485 devlink_port->type_dev = type_dev;
7486 spin_unlock_bh(&devlink_port->type_lock);
7487 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
7488 }
7489
7490 /**
7491 * devlink_port_type_eth_set - Set port type to Ethernet
7492 *
7493 * @devlink_port: devlink port
7494 * @netdev: related netdevice
7495 */
7496 void devlink_port_type_eth_set(struct devlink_port *devlink_port,
7497 struct net_device *netdev)
7498 {
7499 const struct net_device_ops *ops = netdev->netdev_ops;
7500
7501 /* If driver registers devlink port, it should set devlink port
7502 * attributes accordingly so the compat functions are called
7503 * and the original ops are not used.
7504 */
7505 if (ops->ndo_get_phys_port_name) {
7506 /* Some drivers use the same set of ndos for netdevs
7507 * that have devlink_port registered and also for
7508 * those who don't. Make sure that ndo_get_phys_port_name
7509 * returns -EOPNOTSUPP here in case it is defined.
7510 * Warn if not.
7511 */
7512 char name[IFNAMSIZ];
7513 int err;
7514
7515 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
7516 WARN_ON(err != -EOPNOTSUPP);
7517 }
7518 if (ops->ndo_get_port_parent_id) {
7519 /* Some drivers use the same set of ndos for netdevs
7520 * that have devlink_port registered and also for
7521 * those who don't. Make sure that ndo_get_port_parent_id
7522 * returns -EOPNOTSUPP here in case it is defined.
7523 * Warn if not.
7524 */
7525 struct netdev_phys_item_id ppid;
7526 int err;
7527
7528 err = ops->ndo_get_port_parent_id(netdev, &ppid);
7529 WARN_ON(err != -EOPNOTSUPP);
7530 }
7531 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev);
7532 }
7533 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
7534
7535 /**
7536 * devlink_port_type_ib_set - Set port type to InfiniBand
7537 *
7538 * @devlink_port: devlink port
7539 * @ibdev: related IB device
7540 */
7541 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
7542 struct ib_device *ibdev)
7543 {
7544 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
7545 }
7546 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
7547
7548 /**
7549 * devlink_port_type_clear - Clear port type
7550 *
7551 * @devlink_port: devlink port
7552 */
7553 void devlink_port_type_clear(struct devlink_port *devlink_port)
7554 {
7555 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
7556 devlink_port_type_warn_schedule(devlink_port);
7557 }
7558 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
7559
7560 static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
7561 enum devlink_port_flavour flavour)
7562 {
7563 struct devlink_port_attrs *attrs = &devlink_port->attrs;
7564
7565 if (WARN_ON(devlink_port->registered))
7566 return -EEXIST;
7567 devlink_port->attrs_set = true;
7568 attrs->flavour = flavour;
7569 if (attrs->switch_id.id_len) {
7570 devlink_port->switch_port = true;
7571 if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN))
7572 attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN;
7573 } else {
7574 devlink_port->switch_port = false;
7575 }
7576 return 0;
7577 }
7578
7579 /**
7580 * devlink_port_attrs_set - Set port attributes
7581 *
7582 * @devlink_port: devlink port
7583 * @attrs: devlink port attrs
7584 */
7585 void devlink_port_attrs_set(struct devlink_port *devlink_port,
7586 struct devlink_port_attrs *attrs)
7587 {
7588 int ret;
7589
7590 devlink_port->attrs = *attrs;
7591 ret = __devlink_port_attrs_set(devlink_port, attrs->flavour);
7592 if (ret)
7593 return;
7594 WARN_ON(attrs->splittable && attrs->split);
7595 }
7596 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
7597
7598 /**
7599 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
7600 *
7601 * @devlink_port: devlink port
7602 * @pf: associated PF for the devlink port instance
7603 */
7604 void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u16 pf)
7605 {
7606 struct devlink_port_attrs *attrs = &devlink_port->attrs;
7607 int ret;
7608
7609 ret = __devlink_port_attrs_set(devlink_port,
7610 DEVLINK_PORT_FLAVOUR_PCI_PF);
7611 if (ret)
7612 return;
7613
7614 attrs->pci_pf.pf = pf;
7615 }
7616 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
7617
7618 /**
7619 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
7620 *
7621 * @devlink_port: devlink port
7622 * @pf: associated PF for the devlink port instance
7623 * @vf: associated VF of a PF for the devlink port instance
7624 */
7625 void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port,
7626 u16 pf, u16 vf)
7627 {
7628 struct devlink_port_attrs *attrs = &devlink_port->attrs;
7629 int ret;
7630
7631 ret = __devlink_port_attrs_set(devlink_port,
7632 DEVLINK_PORT_FLAVOUR_PCI_VF);
7633 if (ret)
7634 return;
7635 attrs->pci_vf.pf = pf;
7636 attrs->pci_vf.vf = vf;
7637 }
7638 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
7639
7640 static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
7641 char *name, size_t len)
7642 {
7643 struct devlink_port_attrs *attrs = &devlink_port->attrs;
7644 int n = 0;
7645
7646 if (!devlink_port->attrs_set)
7647 return -EOPNOTSUPP;
7648
7649 switch (attrs->flavour) {
7650 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
7651 case DEVLINK_PORT_FLAVOUR_VIRTUAL:
7652 if (!attrs->split)
7653 n = snprintf(name, len, "p%u", attrs->phys.port_number);
7654 else
7655 n = snprintf(name, len, "p%us%u",
7656 attrs->phys.port_number,
7657 attrs->phys.split_subport_number);
7658 break;
7659 case DEVLINK_PORT_FLAVOUR_CPU:
7660 case DEVLINK_PORT_FLAVOUR_DSA:
7661 /* As CPU and DSA ports do not have a netdevice associated
7662 * case should not ever happen.
7663 */
7664 WARN_ON(1);
7665 return -EINVAL;
7666 case DEVLINK_PORT_FLAVOUR_PCI_PF:
7667 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
7668 break;
7669 case DEVLINK_PORT_FLAVOUR_PCI_VF:
7670 n = snprintf(name, len, "pf%uvf%u",
7671 attrs->pci_vf.pf, attrs->pci_vf.vf);
7672 break;
7673 }
7674
7675 if (n >= len)
7676 return -EINVAL;
7677
7678 return 0;
7679 }
7680
7681 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
7682 u32 size, u16 ingress_pools_count,
7683 u16 egress_pools_count, u16 ingress_tc_count,
7684 u16 egress_tc_count)
7685 {
7686 struct devlink_sb *devlink_sb;
7687 int err = 0;
7688
7689 mutex_lock(&devlink->lock);
7690 if (devlink_sb_index_exists(devlink, sb_index)) {
7691 err = -EEXIST;
7692 goto unlock;
7693 }
7694
7695 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
7696 if (!devlink_sb) {
7697 err = -ENOMEM;
7698 goto unlock;
7699 }
7700 devlink_sb->index = sb_index;
7701 devlink_sb->size = size;
7702 devlink_sb->ingress_pools_count = ingress_pools_count;
7703 devlink_sb->egress_pools_count = egress_pools_count;
7704 devlink_sb->ingress_tc_count = ingress_tc_count;
7705 devlink_sb->egress_tc_count = egress_tc_count;
7706 list_add_tail(&devlink_sb->list, &devlink->sb_list);
7707 unlock:
7708 mutex_unlock(&devlink->lock);
7709 return err;
7710 }
7711 EXPORT_SYMBOL_GPL(devlink_sb_register);
7712
7713 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
7714 {
7715 struct devlink_sb *devlink_sb;
7716
7717 mutex_lock(&devlink->lock);
7718 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
7719 WARN_ON(!devlink_sb);
7720 list_del(&devlink_sb->list);
7721 mutex_unlock(&devlink->lock);
7722 kfree(devlink_sb);
7723 }
7724 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
7725
7726 /**
7727 * devlink_dpipe_headers_register - register dpipe headers
7728 *
7729 * @devlink: devlink
7730 * @dpipe_headers: dpipe header array
7731 *
7732 * Register the headers supported by hardware.
7733 */
7734 int devlink_dpipe_headers_register(struct devlink *devlink,
7735 struct devlink_dpipe_headers *dpipe_headers)
7736 {
7737 mutex_lock(&devlink->lock);
7738 devlink->dpipe_headers = dpipe_headers;
7739 mutex_unlock(&devlink->lock);
7740 return 0;
7741 }
7742 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register);
7743
7744 /**
7745 * devlink_dpipe_headers_unregister - unregister dpipe headers
7746 *
7747 * @devlink: devlink
7748 *
7749 * Unregister the headers supported by hardware.
7750 */
7751 void devlink_dpipe_headers_unregister(struct devlink *devlink)
7752 {
7753 mutex_lock(&devlink->lock);
7754 devlink->dpipe_headers = NULL;
7755 mutex_unlock(&devlink->lock);
7756 }
7757 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister);
7758
7759 /**
7760 * devlink_dpipe_table_counter_enabled - check if counter allocation
7761 * required
7762 * @devlink: devlink
7763 * @table_name: tables name
7764 *
7765 * Used by driver to check if counter allocation is required.
7766 * After counter allocation is turned on the table entries
7767 * are updated to include counter statistics.
7768 *
7769 * After that point on the driver must respect the counter
7770 * state so that each entry added to the table is added
7771 * with a counter.
7772 */
7773 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
7774 const char *table_name)
7775 {
7776 struct devlink_dpipe_table *table;
7777 bool enabled;
7778
7779 rcu_read_lock();
7780 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
7781 table_name, devlink);
7782 enabled = false;
7783 if (table)
7784 enabled = table->counters_enabled;
7785 rcu_read_unlock();
7786 return enabled;
7787 }
7788 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
7789
7790 /**
7791 * devlink_dpipe_table_register - register dpipe table
7792 *
7793 * @devlink: devlink
7794 * @table_name: table name
7795 * @table_ops: table ops
7796 * @priv: priv
7797 * @counter_control_extern: external control for counters
7798 */
7799 int devlink_dpipe_table_register(struct devlink *devlink,
7800 const char *table_name,
7801 struct devlink_dpipe_table_ops *table_ops,
7802 void *priv, bool counter_control_extern)
7803 {
7804 struct devlink_dpipe_table *table;
7805 int err = 0;
7806
7807 if (WARN_ON(!table_ops->size_get))
7808 return -EINVAL;
7809
7810 mutex_lock(&devlink->lock);
7811
7812 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name,
7813 devlink)) {
7814 err = -EEXIST;
7815 goto unlock;
7816 }
7817
7818 table = kzalloc(sizeof(*table), GFP_KERNEL);
7819 if (!table) {
7820 err = -ENOMEM;
7821 goto unlock;
7822 }
7823
7824 table->name = table_name;
7825 table->table_ops = table_ops;
7826 table->priv = priv;
7827 table->counter_control_extern = counter_control_extern;
7828
7829 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
7830 unlock:
7831 mutex_unlock(&devlink->lock);
7832 return err;
7833 }
7834 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register);
7835
7836 /**
7837 * devlink_dpipe_table_unregister - unregister dpipe table
7838 *
7839 * @devlink: devlink
7840 * @table_name: table name
7841 */
7842 void devlink_dpipe_table_unregister(struct devlink *devlink,
7843 const char *table_name)
7844 {
7845 struct devlink_dpipe_table *table;
7846
7847 mutex_lock(&devlink->lock);
7848 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
7849 table_name, devlink);
7850 if (!table)
7851 goto unlock;
7852 list_del_rcu(&table->list);
7853 mutex_unlock(&devlink->lock);
7854 kfree_rcu(table, rcu);
7855 return;
7856 unlock:
7857 mutex_unlock(&devlink->lock);
7858 }
7859 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
7860
7861 /**
7862 * devlink_resource_register - devlink resource register
7863 *
7864 * @devlink: devlink
7865 * @resource_name: resource's name
7866 * @resource_size: resource's size
7867 * @resource_id: resource's id
7868 * @parent_resource_id: resource's parent id
7869 * @size_params: size parameters
7870 */
7871 int devlink_resource_register(struct devlink *devlink,
7872 const char *resource_name,
7873 u64 resource_size,
7874 u64 resource_id,
7875 u64 parent_resource_id,
7876 const struct devlink_resource_size_params *size_params)
7877 {
7878 struct devlink_resource *resource;
7879 struct list_head *resource_list;
7880 bool top_hierarchy;
7881 int err = 0;
7882
7883 top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
7884
7885 mutex_lock(&devlink->lock);
7886 resource = devlink_resource_find(devlink, NULL, resource_id);
7887 if (resource) {
7888 err = -EINVAL;
7889 goto out;
7890 }
7891
7892 resource = kzalloc(sizeof(*resource), GFP_KERNEL);
7893 if (!resource) {
7894 err = -ENOMEM;
7895 goto out;
7896 }
7897
7898 if (top_hierarchy) {
7899 resource_list = &devlink->resource_list;
7900 } else {
7901 struct devlink_resource *parent_resource;
7902
7903 parent_resource = devlink_resource_find(devlink, NULL,
7904 parent_resource_id);
7905 if (parent_resource) {
7906 resource_list = &parent_resource->resource_list;
7907 resource->parent = parent_resource;
7908 } else {
7909 kfree(resource);
7910 err = -EINVAL;
7911 goto out;
7912 }
7913 }
7914
7915 resource->name = resource_name;
7916 resource->size = resource_size;
7917 resource->size_new = resource_size;
7918 resource->id = resource_id;
7919 resource->size_valid = true;
7920 memcpy(&resource->size_params, size_params,
7921 sizeof(resource->size_params));
7922 INIT_LIST_HEAD(&resource->resource_list);
7923 list_add_tail(&resource->list, resource_list);
7924 out:
7925 mutex_unlock(&devlink->lock);
7926 return err;
7927 }
7928 EXPORT_SYMBOL_GPL(devlink_resource_register);
7929
7930 /**
7931 * devlink_resources_unregister - free all resources
7932 *
7933 * @devlink: devlink
7934 * @resource: resource
7935 */
7936 void devlink_resources_unregister(struct devlink *devlink,
7937 struct devlink_resource *resource)
7938 {
7939 struct devlink_resource *tmp, *child_resource;
7940 struct list_head *resource_list;
7941
7942 if (resource)
7943 resource_list = &resource->resource_list;
7944 else
7945 resource_list = &devlink->resource_list;
7946
7947 if (!resource)
7948 mutex_lock(&devlink->lock);
7949
7950 list_for_each_entry_safe(child_resource, tmp, resource_list, list) {
7951 devlink_resources_unregister(devlink, child_resource);
7952 list_del(&child_resource->list);
7953 kfree(child_resource);
7954 }
7955
7956 if (!resource)
7957 mutex_unlock(&devlink->lock);
7958 }
7959 EXPORT_SYMBOL_GPL(devlink_resources_unregister);
7960
7961 /**
7962 * devlink_resource_size_get - get and update size
7963 *
7964 * @devlink: devlink
7965 * @resource_id: the requested resource id
7966 * @p_resource_size: ptr to update
7967 */
7968 int devlink_resource_size_get(struct devlink *devlink,
7969 u64 resource_id,
7970 u64 *p_resource_size)
7971 {
7972 struct devlink_resource *resource;
7973 int err = 0;
7974
7975 mutex_lock(&devlink->lock);
7976 resource = devlink_resource_find(devlink, NULL, resource_id);
7977 if (!resource) {
7978 err = -EINVAL;
7979 goto out;
7980 }
7981 *p_resource_size = resource->size_new;
7982 resource->size = resource->size_new;
7983 out:
7984 mutex_unlock(&devlink->lock);
7985 return err;
7986 }
7987 EXPORT_SYMBOL_GPL(devlink_resource_size_get);
7988
7989 /**
7990 * devlink_dpipe_table_resource_set - set the resource id
7991 *
7992 * @devlink: devlink
7993 * @table_name: table name
7994 * @resource_id: resource id
7995 * @resource_units: number of resource's units consumed per table's entry
7996 */
7997 int devlink_dpipe_table_resource_set(struct devlink *devlink,
7998 const char *table_name, u64 resource_id,
7999 u64 resource_units)
8000 {
8001 struct devlink_dpipe_table *table;
8002 int err = 0;
8003
8004 mutex_lock(&devlink->lock);
8005 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
8006 table_name, devlink);
8007 if (!table) {
8008 err = -EINVAL;
8009 goto out;
8010 }
8011 table->resource_id = resource_id;
8012 table->resource_units = resource_units;
8013 table->resource_valid = true;
8014 out:
8015 mutex_unlock(&devlink->lock);
8016 return err;
8017 }
8018 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set);
8019
8020 /**
8021 * devlink_resource_occ_get_register - register occupancy getter
8022 *
8023 * @devlink: devlink
8024 * @resource_id: resource id
8025 * @occ_get: occupancy getter callback
8026 * @occ_get_priv: occupancy getter callback priv
8027 */
8028 void devlink_resource_occ_get_register(struct devlink *devlink,
8029 u64 resource_id,
8030 devlink_resource_occ_get_t *occ_get,
8031 void *occ_get_priv)
8032 {
8033 struct devlink_resource *resource;
8034
8035 mutex_lock(&devlink->lock);
8036 resource = devlink_resource_find(devlink, NULL, resource_id);
8037 if (WARN_ON(!resource))
8038 goto out;
8039 WARN_ON(resource->occ_get);
8040
8041 resource->occ_get = occ_get;
8042 resource->occ_get_priv = occ_get_priv;
8043 out:
8044 mutex_unlock(&devlink->lock);
8045 }
8046 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
8047
8048 /**
8049 * devlink_resource_occ_get_unregister - unregister occupancy getter
8050 *
8051 * @devlink: devlink
8052 * @resource_id: resource id
8053 */
8054 void devlink_resource_occ_get_unregister(struct devlink *devlink,
8055 u64 resource_id)
8056 {
8057 struct devlink_resource *resource;
8058
8059 mutex_lock(&devlink->lock);
8060 resource = devlink_resource_find(devlink, NULL, resource_id);
8061 if (WARN_ON(!resource))
8062 goto out;
8063 WARN_ON(!resource->occ_get);
8064
8065 resource->occ_get = NULL;
8066 resource->occ_get_priv = NULL;
8067 out:
8068 mutex_unlock(&devlink->lock);
8069 }
8070 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
8071
8072 static int devlink_param_verify(const struct devlink_param *param)
8073 {
8074 if (!param || !param->name || !param->supported_cmodes)
8075 return -EINVAL;
8076 if (param->generic)
8077 return devlink_param_generic_verify(param);
8078 else
8079 return devlink_param_driver_verify(param);
8080 }
8081
8082 static int __devlink_params_register(struct devlink *devlink,
8083 unsigned int port_index,
8084 struct list_head *param_list,
8085 const struct devlink_param *params,
8086 size_t params_count,
8087 enum devlink_command reg_cmd,
8088 enum devlink_command unreg_cmd)
8089 {
8090 const struct devlink_param *param = params;
8091 int i;
8092 int err;
8093
8094 mutex_lock(&devlink->lock);
8095 for (i = 0; i < params_count; i++, param++) {
8096 err = devlink_param_verify(param);
8097 if (err)
8098 goto rollback;
8099
8100 err = devlink_param_register_one(devlink, port_index,
8101 param_list, param, reg_cmd);
8102 if (err)
8103 goto rollback;
8104 }
8105
8106 mutex_unlock(&devlink->lock);
8107 return 0;
8108
8109 rollback:
8110 if (!i)
8111 goto unlock;
8112 for (param--; i > 0; i--, param--)
8113 devlink_param_unregister_one(devlink, port_index, param_list,
8114 param, unreg_cmd);
8115 unlock:
8116 mutex_unlock(&devlink->lock);
8117 return err;
8118 }
8119
8120 static void __devlink_params_unregister(struct devlink *devlink,
8121 unsigned int port_index,
8122 struct list_head *param_list,
8123 const struct devlink_param *params,
8124 size_t params_count,
8125 enum devlink_command cmd)
8126 {
8127 const struct devlink_param *param = params;
8128 int i;
8129
8130 mutex_lock(&devlink->lock);
8131 for (i = 0; i < params_count; i++, param++)
8132 devlink_param_unregister_one(devlink, 0, param_list, param,
8133 cmd);
8134 mutex_unlock(&devlink->lock);
8135 }
8136
8137 /**
8138 * devlink_params_register - register configuration parameters
8139 *
8140 * @devlink: devlink
8141 * @params: configuration parameters array
8142 * @params_count: number of parameters provided
8143 *
8144 * Register the configuration parameters supported by the driver.
8145 */
8146 int devlink_params_register(struct devlink *devlink,
8147 const struct devlink_param *params,
8148 size_t params_count)
8149 {
8150 return __devlink_params_register(devlink, 0, &devlink->param_list,
8151 params, params_count,
8152 DEVLINK_CMD_PARAM_NEW,
8153 DEVLINK_CMD_PARAM_DEL);
8154 }
8155 EXPORT_SYMBOL_GPL(devlink_params_register);
8156
8157 /**
8158 * devlink_params_unregister - unregister configuration parameters
8159 * @devlink: devlink
8160 * @params: configuration parameters to unregister
8161 * @params_count: number of parameters provided
8162 */
8163 void devlink_params_unregister(struct devlink *devlink,
8164 const struct devlink_param *params,
8165 size_t params_count)
8166 {
8167 return __devlink_params_unregister(devlink, 0, &devlink->param_list,
8168 params, params_count,
8169 DEVLINK_CMD_PARAM_DEL);
8170 }
8171 EXPORT_SYMBOL_GPL(devlink_params_unregister);
8172
8173 /**
8174 * devlink_params_publish - publish configuration parameters
8175 *
8176 * @devlink: devlink
8177 *
8178 * Publish previously registered configuration parameters.
8179 */
8180 void devlink_params_publish(struct devlink *devlink)
8181 {
8182 struct devlink_param_item *param_item;
8183
8184 list_for_each_entry(param_item, &devlink->param_list, list) {
8185 if (param_item->published)
8186 continue;
8187 param_item->published = true;
8188 devlink_param_notify(devlink, 0, param_item,
8189 DEVLINK_CMD_PARAM_NEW);
8190 }
8191 }
8192 EXPORT_SYMBOL_GPL(devlink_params_publish);
8193
8194 /**
8195 * devlink_params_unpublish - unpublish configuration parameters
8196 *
8197 * @devlink: devlink
8198 *
8199 * Unpublish previously registered configuration parameters.
8200 */
8201 void devlink_params_unpublish(struct devlink *devlink)
8202 {
8203 struct devlink_param_item *param_item;
8204
8205 list_for_each_entry(param_item, &devlink->param_list, list) {
8206 if (!param_item->published)
8207 continue;
8208 param_item->published = false;
8209 devlink_param_notify(devlink, 0, param_item,
8210 DEVLINK_CMD_PARAM_DEL);
8211 }
8212 }
8213 EXPORT_SYMBOL_GPL(devlink_params_unpublish);
8214
8215 /**
8216 * devlink_port_params_register - register port configuration parameters
8217 *
8218 * @devlink_port: devlink port
8219 * @params: configuration parameters array
8220 * @params_count: number of parameters provided
8221 *
8222 * Register the configuration parameters supported by the port.
8223 */
8224 int devlink_port_params_register(struct devlink_port *devlink_port,
8225 const struct devlink_param *params,
8226 size_t params_count)
8227 {
8228 return __devlink_params_register(devlink_port->devlink,
8229 devlink_port->index,
8230 &devlink_port->param_list, params,
8231 params_count,
8232 DEVLINK_CMD_PORT_PARAM_NEW,
8233 DEVLINK_CMD_PORT_PARAM_DEL);
8234 }
8235 EXPORT_SYMBOL_GPL(devlink_port_params_register);
8236
8237 /**
8238 * devlink_port_params_unregister - unregister port configuration
8239 * parameters
8240 *
8241 * @devlink_port: devlink port
8242 * @params: configuration parameters array
8243 * @params_count: number of parameters provided
8244 */
8245 void devlink_port_params_unregister(struct devlink_port *devlink_port,
8246 const struct devlink_param *params,
8247 size_t params_count)
8248 {
8249 return __devlink_params_unregister(devlink_port->devlink,
8250 devlink_port->index,
8251 &devlink_port->param_list,
8252 params, params_count,
8253 DEVLINK_CMD_PORT_PARAM_DEL);
8254 }
8255 EXPORT_SYMBOL_GPL(devlink_port_params_unregister);
8256
8257 static int
8258 __devlink_param_driverinit_value_get(struct list_head *param_list, u32 param_id,
8259 union devlink_param_value *init_val)
8260 {
8261 struct devlink_param_item *param_item;
8262
8263 param_item = devlink_param_find_by_id(param_list, param_id);
8264 if (!param_item)
8265 return -EINVAL;
8266
8267 if (!param_item->driverinit_value_valid ||
8268 !devlink_param_cmode_is_supported(param_item->param,
8269 DEVLINK_PARAM_CMODE_DRIVERINIT))
8270 return -EOPNOTSUPP;
8271
8272 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
8273 strcpy(init_val->vstr, param_item->driverinit_value.vstr);
8274 else
8275 *init_val = param_item->driverinit_value;
8276
8277 return 0;
8278 }
8279
8280 static int
8281 __devlink_param_driverinit_value_set(struct devlink *devlink,
8282 unsigned int port_index,
8283 struct list_head *param_list, u32 param_id,
8284 union devlink_param_value init_val,
8285 enum devlink_command cmd)
8286 {
8287 struct devlink_param_item *param_item;
8288
8289 param_item = devlink_param_find_by_id(param_list, param_id);
8290 if (!param_item)
8291 return -EINVAL;
8292
8293 if (!devlink_param_cmode_is_supported(param_item->param,
8294 DEVLINK_PARAM_CMODE_DRIVERINIT))
8295 return -EOPNOTSUPP;
8296
8297 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
8298 strcpy(param_item->driverinit_value.vstr, init_val.vstr);
8299 else
8300 param_item->driverinit_value = init_val;
8301 param_item->driverinit_value_valid = true;
8302
8303 devlink_param_notify(devlink, port_index, param_item, cmd);
8304 return 0;
8305 }
8306
8307 /**
8308 * devlink_param_driverinit_value_get - get configuration parameter
8309 * value for driver initializing
8310 *
8311 * @devlink: devlink
8312 * @param_id: parameter ID
8313 * @init_val: value of parameter in driverinit configuration mode
8314 *
8315 * This function should be used by the driver to get driverinit
8316 * configuration for initialization after reload command.
8317 */
8318 int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
8319 union devlink_param_value *init_val)
8320 {
8321 if (!devlink_reload_supported(devlink))
8322 return -EOPNOTSUPP;
8323
8324 return __devlink_param_driverinit_value_get(&devlink->param_list,
8325 param_id, init_val);
8326 }
8327 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get);
8328
8329 /**
8330 * devlink_param_driverinit_value_set - set value of configuration
8331 * parameter for driverinit
8332 * configuration mode
8333 *
8334 * @devlink: devlink
8335 * @param_id: parameter ID
8336 * @init_val: value of parameter to set for driverinit configuration mode
8337 *
8338 * This function should be used by the driver to set driverinit
8339 * configuration mode default value.
8340 */
8341 int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
8342 union devlink_param_value init_val)
8343 {
8344 return __devlink_param_driverinit_value_set(devlink, 0,
8345 &devlink->param_list,
8346 param_id, init_val,
8347 DEVLINK_CMD_PARAM_NEW);
8348 }
8349 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);
8350
8351 /**
8352 * devlink_port_param_driverinit_value_get - get configuration parameter
8353 * value for driver initializing
8354 *
8355 * @devlink_port: devlink_port
8356 * @param_id: parameter ID
8357 * @init_val: value of parameter in driverinit configuration mode
8358 *
8359 * This function should be used by the driver to get driverinit
8360 * configuration for initialization after reload command.
8361 */
8362 int devlink_port_param_driverinit_value_get(struct devlink_port *devlink_port,
8363 u32 param_id,
8364 union devlink_param_value *init_val)
8365 {
8366 struct devlink *devlink = devlink_port->devlink;
8367
8368 if (!devlink_reload_supported(devlink))
8369 return -EOPNOTSUPP;
8370
8371 return __devlink_param_driverinit_value_get(&devlink_port->param_list,
8372 param_id, init_val);
8373 }
8374 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get);
8375
8376 /**
8377 * devlink_port_param_driverinit_value_set - set value of configuration
8378 * parameter for driverinit
8379 * configuration mode
8380 *
8381 * @devlink_port: devlink_port
8382 * @param_id: parameter ID
8383 * @init_val: value of parameter to set for driverinit configuration mode
8384 *
8385 * This function should be used by the driver to set driverinit
8386 * configuration mode default value.
8387 */
8388 int devlink_port_param_driverinit_value_set(struct devlink_port *devlink_port,
8389 u32 param_id,
8390 union devlink_param_value init_val)
8391 {
8392 return __devlink_param_driverinit_value_set(devlink_port->devlink,
8393 devlink_port->index,
8394 &devlink_port->param_list,
8395 param_id, init_val,
8396 DEVLINK_CMD_PORT_PARAM_NEW);
8397 }
8398 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set);
8399
8400 /**
8401 * devlink_param_value_changed - notify devlink on a parameter's value
8402 * change. Should be called by the driver
8403 * right after the change.
8404 *
8405 * @devlink: devlink
8406 * @param_id: parameter ID
8407 *
8408 * This function should be used by the driver to notify devlink on value
8409 * change, excluding driverinit configuration mode.
8410 * For driverinit configuration mode driver should use the function
8411 */
8412 void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
8413 {
8414 struct devlink_param_item *param_item;
8415
8416 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
8417 WARN_ON(!param_item);
8418
8419 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
8420 }
8421 EXPORT_SYMBOL_GPL(devlink_param_value_changed);
8422
8423 /**
8424 * devlink_port_param_value_changed - notify devlink on a parameter's value
8425 * change. Should be called by the driver
8426 * right after the change.
8427 *
8428 * @devlink_port: devlink_port
8429 * @param_id: parameter ID
8430 *
8431 * This function should be used by the driver to notify devlink on value
8432 * change, excluding driverinit configuration mode.
8433 * For driverinit configuration mode driver should use the function
8434 * devlink_port_param_driverinit_value_set() instead.
8435 */
8436 void devlink_port_param_value_changed(struct devlink_port *devlink_port,
8437 u32 param_id)
8438 {
8439 struct devlink_param_item *param_item;
8440
8441 param_item = devlink_param_find_by_id(&devlink_port->param_list,
8442 param_id);
8443 WARN_ON(!param_item);
8444
8445 devlink_param_notify(devlink_port->devlink, devlink_port->index,
8446 param_item, DEVLINK_CMD_PORT_PARAM_NEW);
8447 }
8448 EXPORT_SYMBOL_GPL(devlink_port_param_value_changed);
8449
8450 /**
8451 * devlink_param_value_str_fill - Safely fill-up the string preventing
8452 * from overflow of the preallocated buffer
8453 *
8454 * @dst_val: destination devlink_param_value
8455 * @src: source buffer
8456 */
8457 void devlink_param_value_str_fill(union devlink_param_value *dst_val,
8458 const char *src)
8459 {
8460 size_t len;
8461
8462 len = strlcpy(dst_val->vstr, src, __DEVLINK_PARAM_MAX_STRING_VALUE);
8463 WARN_ON(len >= __DEVLINK_PARAM_MAX_STRING_VALUE);
8464 }
8465 EXPORT_SYMBOL_GPL(devlink_param_value_str_fill);
8466
8467 /**
8468 * devlink_region_create - create a new address region
8469 *
8470 * @devlink: devlink
8471 * @ops: region operations and name
8472 * @region_max_snapshots: Maximum supported number of snapshots for region
8473 * @region_size: size of region
8474 */
8475 struct devlink_region *
8476 devlink_region_create(struct devlink *devlink,
8477 const struct devlink_region_ops *ops,
8478 u32 region_max_snapshots, u64 region_size)
8479 {
8480 struct devlink_region *region;
8481 int err = 0;
8482
8483 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
8484 return ERR_PTR(-EINVAL);
8485
8486 mutex_lock(&devlink->lock);
8487
8488 if (devlink_region_get_by_name(devlink, ops->name)) {
8489 err = -EEXIST;
8490 goto unlock;
8491 }
8492
8493 region = kzalloc(sizeof(*region), GFP_KERNEL);
8494 if (!region) {
8495 err = -ENOMEM;
8496 goto unlock;
8497 }
8498
8499 region->devlink = devlink;
8500 region->max_snapshots = region_max_snapshots;
8501 region->ops = ops;
8502 region->size = region_size;
8503 INIT_LIST_HEAD(&region->snapshot_list);
8504 list_add_tail(&region->list, &devlink->region_list);
8505 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
8506
8507 mutex_unlock(&devlink->lock);
8508 return region;
8509
8510 unlock:
8511 mutex_unlock(&devlink->lock);
8512 return ERR_PTR(err);
8513 }
8514 EXPORT_SYMBOL_GPL(devlink_region_create);
8515
8516 /**
8517 * devlink_region_destroy - destroy address region
8518 *
8519 * @region: devlink region to destroy
8520 */
8521 void devlink_region_destroy(struct devlink_region *region)
8522 {
8523 struct devlink *devlink = region->devlink;
8524 struct devlink_snapshot *snapshot, *ts;
8525
8526 mutex_lock(&devlink->lock);
8527
8528 /* Free all snapshots of region */
8529 list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list)
8530 devlink_region_snapshot_del(region, snapshot);
8531
8532 list_del(&region->list);
8533
8534 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
8535 mutex_unlock(&devlink->lock);
8536 kfree(region);
8537 }
8538 EXPORT_SYMBOL_GPL(devlink_region_destroy);
8539
8540 /**
8541 * devlink_region_snapshot_id_get - get snapshot ID
8542 *
8543 * This callback should be called when adding a new snapshot,
8544 * Driver should use the same id for multiple snapshots taken
8545 * on multiple regions at the same time/by the same trigger.
8546 *
8547 * The caller of this function must use devlink_region_snapshot_id_put
8548 * when finished creating regions using this id.
8549 *
8550 * Returns zero on success, or a negative error code on failure.
8551 *
8552 * @devlink: devlink
8553 * @id: storage to return id
8554 */
8555 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
8556 {
8557 int err;
8558
8559 mutex_lock(&devlink->lock);
8560 err = __devlink_region_snapshot_id_get(devlink, id);
8561 mutex_unlock(&devlink->lock);
8562
8563 return err;
8564 }
8565 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
8566
8567 /**
8568 * devlink_region_snapshot_id_put - put snapshot ID reference
8569 *
8570 * This should be called by a driver after finishing creating snapshots
8571 * with an id. Doing so ensures that the ID can later be released in the
8572 * event that all snapshots using it have been destroyed.
8573 *
8574 * @devlink: devlink
8575 * @id: id to release reference on
8576 */
8577 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
8578 {
8579 mutex_lock(&devlink->lock);
8580 __devlink_snapshot_id_decrement(devlink, id);
8581 mutex_unlock(&devlink->lock);
8582 }
8583 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
8584
8585 /**
8586 * devlink_region_snapshot_create - create a new snapshot
8587 * This will add a new snapshot of a region. The snapshot
8588 * will be stored on the region struct and can be accessed
8589 * from devlink. This is useful for future analyses of snapshots.
8590 * Multiple snapshots can be created on a region.
8591 * The @snapshot_id should be obtained using the getter function.
8592 *
8593 * @region: devlink region of the snapshot
8594 * @data: snapshot data
8595 * @snapshot_id: snapshot id to be created
8596 */
8597 int devlink_region_snapshot_create(struct devlink_region *region,
8598 u8 *data, u32 snapshot_id)
8599 {
8600 struct devlink *devlink = region->devlink;
8601 int err;
8602
8603 mutex_lock(&devlink->lock);
8604 err = __devlink_region_snapshot_create(region, data, snapshot_id);
8605 mutex_unlock(&devlink->lock);
8606
8607 return err;
8608 }
8609 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
8610
8611 #define DEVLINK_TRAP(_id, _type) \
8612 { \
8613 .type = DEVLINK_TRAP_TYPE_##_type, \
8614 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
8615 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
8616 }
8617
8618 static const struct devlink_trap devlink_trap_generic[] = {
8619 DEVLINK_TRAP(SMAC_MC, DROP),
8620 DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP),
8621 DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP),
8622 DEVLINK_TRAP(INGRESS_STP_FILTER, DROP),
8623 DEVLINK_TRAP(EMPTY_TX_LIST, DROP),
8624 DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP),
8625 DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP),
8626 DEVLINK_TRAP(TTL_ERROR, EXCEPTION),
8627 DEVLINK_TRAP(TAIL_DROP, DROP),
8628 DEVLINK_TRAP(NON_IP_PACKET, DROP),
8629 DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP),
8630 DEVLINK_TRAP(DIP_LB, DROP),
8631 DEVLINK_TRAP(SIP_MC, DROP),
8632 DEVLINK_TRAP(SIP_LB, DROP),
8633 DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP),
8634 DEVLINK_TRAP(IPV4_SIP_BC, DROP),
8635 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP),
8636 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP),
8637 DEVLINK_TRAP(MTU_ERROR, EXCEPTION),
8638 DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION),
8639 DEVLINK_TRAP(RPF, EXCEPTION),
8640 DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION),
8641 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION),
8642 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION),
8643 DEVLINK_TRAP(NON_ROUTABLE, DROP),
8644 DEVLINK_TRAP(DECAP_ERROR, EXCEPTION),
8645 DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP),
8646 DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP),
8647 DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP),
8648 DEVLINK_TRAP(STP, CONTROL),
8649 DEVLINK_TRAP(LACP, CONTROL),
8650 DEVLINK_TRAP(LLDP, CONTROL),
8651 DEVLINK_TRAP(IGMP_QUERY, CONTROL),
8652 DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL),
8653 DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL),
8654 DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL),
8655 DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL),
8656 DEVLINK_TRAP(MLD_QUERY, CONTROL),
8657 DEVLINK_TRAP(MLD_V1_REPORT, CONTROL),
8658 DEVLINK_TRAP(MLD_V2_REPORT, CONTROL),
8659 DEVLINK_TRAP(MLD_V1_DONE, CONTROL),
8660 DEVLINK_TRAP(IPV4_DHCP, CONTROL),
8661 DEVLINK_TRAP(IPV6_DHCP, CONTROL),
8662 DEVLINK_TRAP(ARP_REQUEST, CONTROL),
8663 DEVLINK_TRAP(ARP_RESPONSE, CONTROL),
8664 DEVLINK_TRAP(ARP_OVERLAY, CONTROL),
8665 DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL),
8666 DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL),
8667 DEVLINK_TRAP(IPV4_BFD, CONTROL),
8668 DEVLINK_TRAP(IPV6_BFD, CONTROL),
8669 DEVLINK_TRAP(IPV4_OSPF, CONTROL),
8670 DEVLINK_TRAP(IPV6_OSPF, CONTROL),
8671 DEVLINK_TRAP(IPV4_BGP, CONTROL),
8672 DEVLINK_TRAP(IPV6_BGP, CONTROL),
8673 DEVLINK_TRAP(IPV4_VRRP, CONTROL),
8674 DEVLINK_TRAP(IPV6_VRRP, CONTROL),
8675 DEVLINK_TRAP(IPV4_PIM, CONTROL),
8676 DEVLINK_TRAP(IPV6_PIM, CONTROL),
8677 DEVLINK_TRAP(UC_LB, CONTROL),
8678 DEVLINK_TRAP(LOCAL_ROUTE, CONTROL),
8679 DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL),
8680 DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL),
8681 DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL),
8682 DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL),
8683 DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL),
8684 DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL),
8685 DEVLINK_TRAP(IPV6_REDIRECT, CONTROL),
8686 DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL),
8687 DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL),
8688 DEVLINK_TRAP(PTP_EVENT, CONTROL),
8689 DEVLINK_TRAP(PTP_GENERAL, CONTROL),
8690 DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL),
8691 DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL),
8692 };
8693
8694 #define DEVLINK_TRAP_GROUP(_id) \
8695 { \
8696 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
8697 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
8698 }
8699
8700 static const struct devlink_trap_group devlink_trap_group_generic[] = {
8701 DEVLINK_TRAP_GROUP(L2_DROPS),
8702 DEVLINK_TRAP_GROUP(L3_DROPS),
8703 DEVLINK_TRAP_GROUP(L3_EXCEPTIONS),
8704 DEVLINK_TRAP_GROUP(BUFFER_DROPS),
8705 DEVLINK_TRAP_GROUP(TUNNEL_DROPS),
8706 DEVLINK_TRAP_GROUP(ACL_DROPS),
8707 DEVLINK_TRAP_GROUP(STP),
8708 DEVLINK_TRAP_GROUP(LACP),
8709 DEVLINK_TRAP_GROUP(LLDP),
8710 DEVLINK_TRAP_GROUP(MC_SNOOPING),
8711 DEVLINK_TRAP_GROUP(DHCP),
8712 DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY),
8713 DEVLINK_TRAP_GROUP(BFD),
8714 DEVLINK_TRAP_GROUP(OSPF),
8715 DEVLINK_TRAP_GROUP(BGP),
8716 DEVLINK_TRAP_GROUP(VRRP),
8717 DEVLINK_TRAP_GROUP(PIM),
8718 DEVLINK_TRAP_GROUP(UC_LB),
8719 DEVLINK_TRAP_GROUP(LOCAL_DELIVERY),
8720 DEVLINK_TRAP_GROUP(IPV6),
8721 DEVLINK_TRAP_GROUP(PTP_EVENT),
8722 DEVLINK_TRAP_GROUP(PTP_GENERAL),
8723 DEVLINK_TRAP_GROUP(ACL_SAMPLE),
8724 DEVLINK_TRAP_GROUP(ACL_TRAP),
8725 };
8726
8727 static int devlink_trap_generic_verify(const struct devlink_trap *trap)
8728 {
8729 if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX)
8730 return -EINVAL;
8731
8732 if (strcmp(trap->name, devlink_trap_generic[trap->id].name))
8733 return -EINVAL;
8734
8735 if (trap->type != devlink_trap_generic[trap->id].type)
8736 return -EINVAL;
8737
8738 return 0;
8739 }
8740
8741 static int devlink_trap_driver_verify(const struct devlink_trap *trap)
8742 {
8743 int i;
8744
8745 if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX)
8746 return -EINVAL;
8747
8748 for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) {
8749 if (!strcmp(trap->name, devlink_trap_generic[i].name))
8750 return -EEXIST;
8751 }
8752
8753 return 0;
8754 }
8755
8756 static int devlink_trap_verify(const struct devlink_trap *trap)
8757 {
8758 if (!trap || !trap->name)
8759 return -EINVAL;
8760
8761 if (trap->generic)
8762 return devlink_trap_generic_verify(trap);
8763 else
8764 return devlink_trap_driver_verify(trap);
8765 }
8766
8767 static int
8768 devlink_trap_group_generic_verify(const struct devlink_trap_group *group)
8769 {
8770 if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
8771 return -EINVAL;
8772
8773 if (strcmp(group->name, devlink_trap_group_generic[group->id].name))
8774 return -EINVAL;
8775
8776 return 0;
8777 }
8778
8779 static int
8780 devlink_trap_group_driver_verify(const struct devlink_trap_group *group)
8781 {
8782 int i;
8783
8784 if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
8785 return -EINVAL;
8786
8787 for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) {
8788 if (!strcmp(group->name, devlink_trap_group_generic[i].name))
8789 return -EEXIST;
8790 }
8791
8792 return 0;
8793 }
8794
8795 static int devlink_trap_group_verify(const struct devlink_trap_group *group)
8796 {
8797 if (group->generic)
8798 return devlink_trap_group_generic_verify(group);
8799 else
8800 return devlink_trap_group_driver_verify(group);
8801 }
8802
8803 static void
8804 devlink_trap_group_notify(struct devlink *devlink,
8805 const struct devlink_trap_group_item *group_item,
8806 enum devlink_command cmd)
8807 {
8808 struct sk_buff *msg;
8809 int err;
8810
8811 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
8812 cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
8813
8814 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8815 if (!msg)
8816 return;
8817
8818 err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0,
8819 0);
8820 if (err) {
8821 nlmsg_free(msg);
8822 return;
8823 }
8824
8825 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
8826 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
8827 }
8828
8829 static int
8830 devlink_trap_item_group_link(struct devlink *devlink,
8831 struct devlink_trap_item *trap_item)
8832 {
8833 u16 group_id = trap_item->trap->init_group_id;
8834 struct devlink_trap_group_item *group_item;
8835
8836 group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id);
8837 if (WARN_ON_ONCE(!group_item))
8838 return -EINVAL;
8839
8840 trap_item->group_item = group_item;
8841
8842 return 0;
8843 }
8844
8845 static void devlink_trap_notify(struct devlink *devlink,
8846 const struct devlink_trap_item *trap_item,
8847 enum devlink_command cmd)
8848 {
8849 struct sk_buff *msg;
8850 int err;
8851
8852 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
8853 cmd != DEVLINK_CMD_TRAP_DEL);
8854
8855 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8856 if (!msg)
8857 return;
8858
8859 err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0);
8860 if (err) {
8861 nlmsg_free(msg);
8862 return;
8863 }
8864
8865 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
8866 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
8867 }
8868
8869 static int
8870 devlink_trap_register(struct devlink *devlink,
8871 const struct devlink_trap *trap, void *priv)
8872 {
8873 struct devlink_trap_item *trap_item;
8874 int err;
8875
8876 if (devlink_trap_item_lookup(devlink, trap->name))
8877 return -EEXIST;
8878
8879 trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL);
8880 if (!trap_item)
8881 return -ENOMEM;
8882
8883 trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
8884 if (!trap_item->stats) {
8885 err = -ENOMEM;
8886 goto err_stats_alloc;
8887 }
8888
8889 trap_item->trap = trap;
8890 trap_item->action = trap->init_action;
8891 trap_item->priv = priv;
8892
8893 err = devlink_trap_item_group_link(devlink, trap_item);
8894 if (err)
8895 goto err_group_link;
8896
8897 err = devlink->ops->trap_init(devlink, trap, trap_item);
8898 if (err)
8899 goto err_trap_init;
8900
8901 list_add_tail(&trap_item->list, &devlink->trap_list);
8902 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
8903
8904 return 0;
8905
8906 err_trap_init:
8907 err_group_link:
8908 free_percpu(trap_item->stats);
8909 err_stats_alloc:
8910 kfree(trap_item);
8911 return err;
8912 }
8913
8914 static void devlink_trap_unregister(struct devlink *devlink,
8915 const struct devlink_trap *trap)
8916 {
8917 struct devlink_trap_item *trap_item;
8918
8919 trap_item = devlink_trap_item_lookup(devlink, trap->name);
8920 if (WARN_ON_ONCE(!trap_item))
8921 return;
8922
8923 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
8924 list_del(&trap_item->list);
8925 if (devlink->ops->trap_fini)
8926 devlink->ops->trap_fini(devlink, trap, trap_item);
8927 free_percpu(trap_item->stats);
8928 kfree(trap_item);
8929 }
8930
8931 static void devlink_trap_disable(struct devlink *devlink,
8932 const struct devlink_trap *trap)
8933 {
8934 struct devlink_trap_item *trap_item;
8935
8936 trap_item = devlink_trap_item_lookup(devlink, trap->name);
8937 if (WARN_ON_ONCE(!trap_item))
8938 return;
8939
8940 devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP);
8941 trap_item->action = DEVLINK_TRAP_ACTION_DROP;
8942 }
8943
8944 /**
8945 * devlink_traps_register - Register packet traps with devlink.
8946 * @devlink: devlink.
8947 * @traps: Packet traps.
8948 * @traps_count: Count of provided packet traps.
8949 * @priv: Driver private information.
8950 *
8951 * Return: Non-zero value on failure.
8952 */
8953 int devlink_traps_register(struct devlink *devlink,
8954 const struct devlink_trap *traps,
8955 size_t traps_count, void *priv)
8956 {
8957 int i, err;
8958
8959 if (!devlink->ops->trap_init || !devlink->ops->trap_action_set)
8960 return -EINVAL;
8961
8962 mutex_lock(&devlink->lock);
8963 for (i = 0; i < traps_count; i++) {
8964 const struct devlink_trap *trap = &traps[i];
8965
8966 err = devlink_trap_verify(trap);
8967 if (err)
8968 goto err_trap_verify;
8969
8970 err = devlink_trap_register(devlink, trap, priv);
8971 if (err)
8972 goto err_trap_register;
8973 }
8974 mutex_unlock(&devlink->lock);
8975
8976 return 0;
8977
8978 err_trap_register:
8979 err_trap_verify:
8980 for (i--; i >= 0; i--)
8981 devlink_trap_unregister(devlink, &traps[i]);
8982 mutex_unlock(&devlink->lock);
8983 return err;
8984 }
8985 EXPORT_SYMBOL_GPL(devlink_traps_register);
8986
8987 /**
8988 * devlink_traps_unregister - Unregister packet traps from devlink.
8989 * @devlink: devlink.
8990 * @traps: Packet traps.
8991 * @traps_count: Count of provided packet traps.
8992 */
8993 void devlink_traps_unregister(struct devlink *devlink,
8994 const struct devlink_trap *traps,
8995 size_t traps_count)
8996 {
8997 int i;
8998
8999 mutex_lock(&devlink->lock);
9000 /* Make sure we do not have any packets in-flight while unregistering
9001 * traps by disabling all of them and waiting for a grace period.
9002 */
9003 for (i = traps_count - 1; i >= 0; i--)
9004 devlink_trap_disable(devlink, &traps[i]);
9005 synchronize_rcu();
9006 for (i = traps_count - 1; i >= 0; i--)
9007 devlink_trap_unregister(devlink, &traps[i]);
9008 mutex_unlock(&devlink->lock);
9009 }
9010 EXPORT_SYMBOL_GPL(devlink_traps_unregister);
9011
9012 static void
9013 devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
9014 size_t skb_len)
9015 {
9016 struct devlink_stats *stats;
9017
9018 stats = this_cpu_ptr(trap_stats);
9019 u64_stats_update_begin(&stats->syncp);
9020 stats->rx_bytes += skb_len;
9021 stats->rx_packets++;
9022 u64_stats_update_end(&stats->syncp);
9023 }
9024
9025 static void
9026 devlink_trap_report_metadata_fill(struct net_dm_hw_metadata *hw_metadata,
9027 const struct devlink_trap_item *trap_item,
9028 struct devlink_port *in_devlink_port,
9029 const struct flow_action_cookie *fa_cookie)
9030 {
9031 struct devlink_trap_group_item *group_item = trap_item->group_item;
9032
9033 hw_metadata->trap_group_name = group_item->group->name;
9034 hw_metadata->trap_name = trap_item->trap->name;
9035 hw_metadata->fa_cookie = fa_cookie;
9036
9037 spin_lock(&in_devlink_port->type_lock);
9038 if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH)
9039 hw_metadata->input_dev = in_devlink_port->type_dev;
9040 spin_unlock(&in_devlink_port->type_lock);
9041 }
9042
9043 /**
9044 * devlink_trap_report - Report trapped packet to drop monitor.
9045 * @devlink: devlink.
9046 * @skb: Trapped packet.
9047 * @trap_ctx: Trap context.
9048 * @in_devlink_port: Input devlink port.
9049 * @fa_cookie: Flow action cookie. Could be NULL.
9050 */
9051 void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
9052 void *trap_ctx, struct devlink_port *in_devlink_port,
9053 const struct flow_action_cookie *fa_cookie)
9054
9055 {
9056 struct devlink_trap_item *trap_item = trap_ctx;
9057 struct net_dm_hw_metadata hw_metadata = {};
9058
9059 devlink_trap_stats_update(trap_item->stats, skb->len);
9060 devlink_trap_stats_update(trap_item->group_item->stats, skb->len);
9061
9062 /* Control packets were not dropped by the device or encountered an
9063 * exception during forwarding and therefore should not be reported to
9064 * the kernel's drop monitor.
9065 */
9066 if (trap_item->trap->type == DEVLINK_TRAP_TYPE_CONTROL)
9067 return;
9068
9069 devlink_trap_report_metadata_fill(&hw_metadata, trap_item,
9070 in_devlink_port, fa_cookie);
9071 net_dm_hw_report(skb, &hw_metadata);
9072 }
9073 EXPORT_SYMBOL_GPL(devlink_trap_report);
9074
9075 /**
9076 * devlink_trap_ctx_priv - Trap context to driver private information.
9077 * @trap_ctx: Trap context.
9078 *
9079 * Return: Driver private information passed during registration.
9080 */
9081 void *devlink_trap_ctx_priv(void *trap_ctx)
9082 {
9083 struct devlink_trap_item *trap_item = trap_ctx;
9084
9085 return trap_item->priv;
9086 }
9087 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
9088
9089 static int
9090 devlink_trap_group_item_policer_link(struct devlink *devlink,
9091 struct devlink_trap_group_item *group_item)
9092 {
9093 u32 policer_id = group_item->group->init_policer_id;
9094 struct devlink_trap_policer_item *policer_item;
9095
9096 if (policer_id == 0)
9097 return 0;
9098
9099 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
9100 if (WARN_ON_ONCE(!policer_item))
9101 return -EINVAL;
9102
9103 group_item->policer_item = policer_item;
9104
9105 return 0;
9106 }
9107
9108 static int
9109 devlink_trap_group_register(struct devlink *devlink,
9110 const struct devlink_trap_group *group)
9111 {
9112 struct devlink_trap_group_item *group_item;
9113 int err;
9114
9115 if (devlink_trap_group_item_lookup(devlink, group->name))
9116 return -EEXIST;
9117
9118 group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
9119 if (!group_item)
9120 return -ENOMEM;
9121
9122 group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
9123 if (!group_item->stats) {
9124 err = -ENOMEM;
9125 goto err_stats_alloc;
9126 }
9127
9128 group_item->group = group;
9129
9130 err = devlink_trap_group_item_policer_link(devlink, group_item);
9131 if (err)
9132 goto err_policer_link;
9133
9134 if (devlink->ops->trap_group_init) {
9135 err = devlink->ops->trap_group_init(devlink, group);
9136 if (err)
9137 goto err_group_init;
9138 }
9139
9140 list_add_tail(&group_item->list, &devlink->trap_group_list);
9141 devlink_trap_group_notify(devlink, group_item,
9142 DEVLINK_CMD_TRAP_GROUP_NEW);
9143
9144 return 0;
9145
9146 err_group_init:
9147 err_policer_link:
9148 free_percpu(group_item->stats);
9149 err_stats_alloc:
9150 kfree(group_item);
9151 return err;
9152 }
9153
9154 static void
9155 devlink_trap_group_unregister(struct devlink *devlink,
9156 const struct devlink_trap_group *group)
9157 {
9158 struct devlink_trap_group_item *group_item;
9159
9160 group_item = devlink_trap_group_item_lookup(devlink, group->name);
9161 if (WARN_ON_ONCE(!group_item))
9162 return;
9163
9164 devlink_trap_group_notify(devlink, group_item,
9165 DEVLINK_CMD_TRAP_GROUP_DEL);
9166 list_del(&group_item->list);
9167 free_percpu(group_item->stats);
9168 kfree(group_item);
9169 }
9170
9171 /**
9172 * devlink_trap_groups_register - Register packet trap groups with devlink.
9173 * @devlink: devlink.
9174 * @groups: Packet trap groups.
9175 * @groups_count: Count of provided packet trap groups.
9176 *
9177 * Return: Non-zero value on failure.
9178 */
9179 int devlink_trap_groups_register(struct devlink *devlink,
9180 const struct devlink_trap_group *groups,
9181 size_t groups_count)
9182 {
9183 int i, err;
9184
9185 mutex_lock(&devlink->lock);
9186 for (i = 0; i < groups_count; i++) {
9187 const struct devlink_trap_group *group = &groups[i];
9188
9189 err = devlink_trap_group_verify(group);
9190 if (err)
9191 goto err_trap_group_verify;
9192
9193 err = devlink_trap_group_register(devlink, group);
9194 if (err)
9195 goto err_trap_group_register;
9196 }
9197 mutex_unlock(&devlink->lock);
9198
9199 return 0;
9200
9201 err_trap_group_register:
9202 err_trap_group_verify:
9203 for (i--; i >= 0; i--)
9204 devlink_trap_group_unregister(devlink, &groups[i]);
9205 mutex_unlock(&devlink->lock);
9206 return err;
9207 }
9208 EXPORT_SYMBOL_GPL(devlink_trap_groups_register);
9209
9210 /**
9211 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
9212 * @devlink: devlink.
9213 * @groups: Packet trap groups.
9214 * @groups_count: Count of provided packet trap groups.
9215 */
9216 void devlink_trap_groups_unregister(struct devlink *devlink,
9217 const struct devlink_trap_group *groups,
9218 size_t groups_count)
9219 {
9220 int i;
9221
9222 mutex_lock(&devlink->lock);
9223 for (i = groups_count - 1; i >= 0; i--)
9224 devlink_trap_group_unregister(devlink, &groups[i]);
9225 mutex_unlock(&devlink->lock);
9226 }
9227 EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister);
9228
9229 static void
9230 devlink_trap_policer_notify(struct devlink *devlink,
9231 const struct devlink_trap_policer_item *policer_item,
9232 enum devlink_command cmd)
9233 {
9234 struct sk_buff *msg;
9235 int err;
9236
9237 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW &&
9238 cmd != DEVLINK_CMD_TRAP_POLICER_DEL);
9239
9240 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
9241 if (!msg)
9242 return;
9243
9244 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0,
9245 0, 0);
9246 if (err) {
9247 nlmsg_free(msg);
9248 return;
9249 }
9250
9251 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
9252 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
9253 }
9254
9255 static int
9256 devlink_trap_policer_register(struct devlink *devlink,
9257 const struct devlink_trap_policer *policer)
9258 {
9259 struct devlink_trap_policer_item *policer_item;
9260 int err;
9261
9262 if (devlink_trap_policer_item_lookup(devlink, policer->id))
9263 return -EEXIST;
9264
9265 policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL);
9266 if (!policer_item)
9267 return -ENOMEM;
9268
9269 policer_item->policer = policer;
9270 policer_item->rate = policer->init_rate;
9271 policer_item->burst = policer->init_burst;
9272
9273 if (devlink->ops->trap_policer_init) {
9274 err = devlink->ops->trap_policer_init(devlink, policer);
9275 if (err)
9276 goto err_policer_init;
9277 }
9278
9279 list_add_tail(&policer_item->list, &devlink->trap_policer_list);
9280 devlink_trap_policer_notify(devlink, policer_item,
9281 DEVLINK_CMD_TRAP_POLICER_NEW);
9282
9283 return 0;
9284
9285 err_policer_init:
9286 kfree(policer_item);
9287 return err;
9288 }
9289
9290 static void
9291 devlink_trap_policer_unregister(struct devlink *devlink,
9292 const struct devlink_trap_policer *policer)
9293 {
9294 struct devlink_trap_policer_item *policer_item;
9295
9296 policer_item = devlink_trap_policer_item_lookup(devlink, policer->id);
9297 if (WARN_ON_ONCE(!policer_item))
9298 return;
9299
9300 devlink_trap_policer_notify(devlink, policer_item,
9301 DEVLINK_CMD_TRAP_POLICER_DEL);
9302 list_del(&policer_item->list);
9303 if (devlink->ops->trap_policer_fini)
9304 devlink->ops->trap_policer_fini(devlink, policer);
9305 kfree(policer_item);
9306 }
9307
9308 /**
9309 * devlink_trap_policers_register - Register packet trap policers with devlink.
9310 * @devlink: devlink.
9311 * @policers: Packet trap policers.
9312 * @policers_count: Count of provided packet trap policers.
9313 *
9314 * Return: Non-zero value on failure.
9315 */
9316 int
9317 devlink_trap_policers_register(struct devlink *devlink,
9318 const struct devlink_trap_policer *policers,
9319 size_t policers_count)
9320 {
9321 int i, err;
9322
9323 mutex_lock(&devlink->lock);
9324 for (i = 0; i < policers_count; i++) {
9325 const struct devlink_trap_policer *policer = &policers[i];
9326
9327 if (WARN_ON(policer->id == 0 ||
9328 policer->max_rate < policer->min_rate ||
9329 policer->max_burst < policer->min_burst)) {
9330 err = -EINVAL;
9331 goto err_trap_policer_verify;
9332 }
9333
9334 err = devlink_trap_policer_register(devlink, policer);
9335 if (err)
9336 goto err_trap_policer_register;
9337 }
9338 mutex_unlock(&devlink->lock);
9339
9340 return 0;
9341
9342 err_trap_policer_register:
9343 err_trap_policer_verify:
9344 for (i--; i >= 0; i--)
9345 devlink_trap_policer_unregister(devlink, &policers[i]);
9346 mutex_unlock(&devlink->lock);
9347 return err;
9348 }
9349 EXPORT_SYMBOL_GPL(devlink_trap_policers_register);
9350
9351 /**
9352 * devlink_trap_policers_unregister - Unregister packet trap policers from devlink.
9353 * @devlink: devlink.
9354 * @policers: Packet trap policers.
9355 * @policers_count: Count of provided packet trap policers.
9356 */
9357 void
9358 devlink_trap_policers_unregister(struct devlink *devlink,
9359 const struct devlink_trap_policer *policers,
9360 size_t policers_count)
9361 {
9362 int i;
9363
9364 mutex_lock(&devlink->lock);
9365 for (i = policers_count - 1; i >= 0; i--)
9366 devlink_trap_policer_unregister(devlink, &policers[i]);
9367 mutex_unlock(&devlink->lock);
9368 }
9369 EXPORT_SYMBOL_GPL(devlink_trap_policers_unregister);
9370
9371 static void __devlink_compat_running_version(struct devlink *devlink,
9372 char *buf, size_t len)
9373 {
9374 const struct nlattr *nlattr;
9375 struct devlink_info_req req;
9376 struct sk_buff *msg;
9377 int rem, err;
9378
9379 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
9380 if (!msg)
9381 return;
9382
9383 req.msg = msg;
9384 err = devlink->ops->info_get(devlink, &req, NULL);
9385 if (err)
9386 goto free_msg;
9387
9388 nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
9389 const struct nlattr *kv;
9390 int rem_kv;
9391
9392 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
9393 continue;
9394
9395 nla_for_each_nested(kv, nlattr, rem_kv) {
9396 if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
9397 continue;
9398
9399 strlcat(buf, nla_data(kv), len);
9400 strlcat(buf, " ", len);
9401 }
9402 }
9403 free_msg:
9404 nlmsg_free(msg);
9405 }
9406
9407 void devlink_compat_running_version(struct net_device *dev,
9408 char *buf, size_t len)
9409 {
9410 struct devlink *devlink;
9411
9412 dev_hold(dev);
9413 rtnl_unlock();
9414
9415 devlink = netdev_to_devlink(dev);
9416 if (!devlink || !devlink->ops->info_get)
9417 goto out;
9418
9419 mutex_lock(&devlink->lock);
9420 __devlink_compat_running_version(devlink, buf, len);
9421 mutex_unlock(&devlink->lock);
9422
9423 out:
9424 rtnl_lock();
9425 dev_put(dev);
9426 }
9427
9428 int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
9429 {
9430 struct devlink *devlink;
9431 int ret;
9432
9433 dev_hold(dev);
9434 rtnl_unlock();
9435
9436 devlink = netdev_to_devlink(dev);
9437 if (!devlink || !devlink->ops->flash_update) {
9438 ret = -EOPNOTSUPP;
9439 goto out;
9440 }
9441
9442 mutex_lock(&devlink->lock);
9443 ret = devlink->ops->flash_update(devlink, file_name, NULL, NULL);
9444 mutex_unlock(&devlink->lock);
9445
9446 out:
9447 rtnl_lock();
9448 dev_put(dev);
9449
9450 return ret;
9451 }
9452
9453 int devlink_compat_phys_port_name_get(struct net_device *dev,
9454 char *name, size_t len)
9455 {
9456 struct devlink_port *devlink_port;
9457
9458 /* RTNL mutex is held here which ensures that devlink_port
9459 * instance cannot disappear in the middle. No need to take
9460 * any devlink lock as only permanent values are accessed.
9461 */
9462 ASSERT_RTNL();
9463
9464 devlink_port = netdev_to_devlink_port(dev);
9465 if (!devlink_port)
9466 return -EOPNOTSUPP;
9467
9468 return __devlink_port_phys_port_name_get(devlink_port, name, len);
9469 }
9470
9471 int devlink_compat_switch_id_get(struct net_device *dev,
9472 struct netdev_phys_item_id *ppid)
9473 {
9474 struct devlink_port *devlink_port;
9475
9476 /* Caller must hold RTNL mutex or reference to dev, which ensures that
9477 * devlink_port instance cannot disappear in the middle. No need to take
9478 * any devlink lock as only permanent values are accessed.
9479 */
9480 devlink_port = netdev_to_devlink_port(dev);
9481 if (!devlink_port || !devlink_port->switch_port)
9482 return -EOPNOTSUPP;
9483
9484 memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));
9485
9486 return 0;
9487 }
9488
9489 static void __net_exit devlink_pernet_pre_exit(struct net *net)
9490 {
9491 struct devlink *devlink;
9492 int err;
9493
9494 /* In case network namespace is getting destroyed, reload
9495 * all devlink instances from this namespace into init_net.
9496 */
9497 mutex_lock(&devlink_mutex);
9498 list_for_each_entry(devlink, &devlink_list, list) {
9499 if (net_eq(devlink_net(devlink), net)) {
9500 if (WARN_ON(!devlink_reload_supported(devlink)))
9501 continue;
9502 err = devlink_reload(devlink, &init_net, NULL);
9503 if (err && err != -EOPNOTSUPP)
9504 pr_warn("Failed to reload devlink instance into init_net\n");
9505 }
9506 }
9507 mutex_unlock(&devlink_mutex);
9508 }
9509
9510 static struct pernet_operations devlink_pernet_ops __net_initdata = {
9511 .pre_exit = devlink_pernet_pre_exit,
9512 };
9513
9514 static int __init devlink_init(void)
9515 {
9516 int err;
9517
9518 err = genl_register_family(&devlink_nl_family);
9519 if (err)
9520 goto out;
9521 err = register_pernet_subsys(&devlink_pernet_ops);
9522
9523 out:
9524 WARN_ON(err);
9525 return err;
9526 }
9527
9528 subsys_initcall(devlink_init);