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