devlink: Move dpipe entry clear function into devlink
[linux-2.6/btrfs-unstable.git] / net / core / devlink.c
blob194708aa5f11d366e9ed78f0463f86cfad030475
1 /*
2 * net/core/devlink.c - Network physical/parent device Netlink interface
4 * Heavily inspired by net/wireless/
5 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
6 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/types.h>
17 #include <linux/slab.h>
18 #include <linux/gfp.h>
19 #include <linux/device.h>
20 #include <linux/list.h>
21 #include <linux/netdevice.h>
22 #include <rdma/ib_verbs.h>
23 #include <net/netlink.h>
24 #include <net/genetlink.h>
25 #include <net/rtnetlink.h>
26 #include <net/net_namespace.h>
27 #include <net/sock.h>
28 #include <net/devlink.h>
29 #define CREATE_TRACE_POINTS
30 #include <trace/events/devlink.h>
32 static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
34 .name = "destination_mac",
35 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
36 .bitwidth = 48,
40 struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
41 .name = "ethernet",
42 .id = DEVLINK_DPIPE_HEADER_ETHERNET,
43 .fields = devlink_dpipe_fields_ethernet,
44 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
45 .global = true,
47 EXPORT_SYMBOL(devlink_dpipe_header_ethernet);
49 static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
51 .name = "destination ip",
52 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
53 .bitwidth = 32,
57 struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
58 .name = "ipv4",
59 .id = DEVLINK_DPIPE_HEADER_IPV4,
60 .fields = devlink_dpipe_fields_ipv4,
61 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
62 .global = true,
64 EXPORT_SYMBOL(devlink_dpipe_header_ipv4);
66 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
68 static LIST_HEAD(devlink_list);
70 /* devlink_mutex
72 * An overall lock guarding every operation coming from userspace.
73 * It also guards devlink devices list and it is taken when
74 * driver registers/unregisters it.
76 static DEFINE_MUTEX(devlink_mutex);
78 /* devlink_port_mutex
80 * Shared lock to guard lists of ports in all devlink devices.
82 static DEFINE_MUTEX(devlink_port_mutex);
84 static struct net *devlink_net(const struct devlink *devlink)
86 return read_pnet(&devlink->_net);
89 static void devlink_net_set(struct devlink *devlink, struct net *net)
91 write_pnet(&devlink->_net, net);
94 static struct devlink *devlink_get_from_attrs(struct net *net,
95 struct nlattr **attrs)
97 struct devlink *devlink;
98 char *busname;
99 char *devname;
101 if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
102 return ERR_PTR(-EINVAL);
104 busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
105 devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
107 list_for_each_entry(devlink, &devlink_list, list) {
108 if (strcmp(devlink->dev->bus->name, busname) == 0 &&
109 strcmp(dev_name(devlink->dev), devname) == 0 &&
110 net_eq(devlink_net(devlink), net))
111 return devlink;
114 return ERR_PTR(-ENODEV);
117 static struct devlink *devlink_get_from_info(struct genl_info *info)
119 return devlink_get_from_attrs(genl_info_net(info), info->attrs);
122 static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
123 int port_index)
125 struct devlink_port *devlink_port;
127 list_for_each_entry(devlink_port, &devlink->port_list, list) {
128 if (devlink_port->index == port_index)
129 return devlink_port;
131 return NULL;
134 static bool devlink_port_index_exists(struct devlink *devlink, int port_index)
136 return devlink_port_get_by_index(devlink, port_index);
139 static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
140 struct nlattr **attrs)
142 if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
143 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
144 struct devlink_port *devlink_port;
146 devlink_port = devlink_port_get_by_index(devlink, port_index);
147 if (!devlink_port)
148 return ERR_PTR(-ENODEV);
149 return devlink_port;
151 return ERR_PTR(-EINVAL);
154 static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
155 struct genl_info *info)
157 return devlink_port_get_from_attrs(devlink, info->attrs);
160 struct devlink_sb {
161 struct list_head list;
162 unsigned int index;
163 u32 size;
164 u16 ingress_pools_count;
165 u16 egress_pools_count;
166 u16 ingress_tc_count;
167 u16 egress_tc_count;
170 static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
172 return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
175 static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
176 unsigned int sb_index)
178 struct devlink_sb *devlink_sb;
180 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
181 if (devlink_sb->index == sb_index)
182 return devlink_sb;
184 return NULL;
187 static bool devlink_sb_index_exists(struct devlink *devlink,
188 unsigned int sb_index)
190 return devlink_sb_get_by_index(devlink, sb_index);
193 static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
194 struct nlattr **attrs)
196 if (attrs[DEVLINK_ATTR_SB_INDEX]) {
197 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
198 struct devlink_sb *devlink_sb;
200 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
201 if (!devlink_sb)
202 return ERR_PTR(-ENODEV);
203 return devlink_sb;
205 return ERR_PTR(-EINVAL);
208 static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
209 struct genl_info *info)
211 return devlink_sb_get_from_attrs(devlink, info->attrs);
214 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
215 struct nlattr **attrs,
216 u16 *p_pool_index)
218 u16 val;
220 if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
221 return -EINVAL;
223 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
224 if (val >= devlink_sb_pool_count(devlink_sb))
225 return -EINVAL;
226 *p_pool_index = val;
227 return 0;
230 static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
231 struct genl_info *info,
232 u16 *p_pool_index)
234 return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
235 p_pool_index);
238 static int
239 devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
240 enum devlink_sb_pool_type *p_pool_type)
242 u8 val;
244 if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
245 return -EINVAL;
247 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
248 if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
249 val != DEVLINK_SB_POOL_TYPE_EGRESS)
250 return -EINVAL;
251 *p_pool_type = val;
252 return 0;
255 static int
256 devlink_sb_pool_type_get_from_info(struct genl_info *info,
257 enum devlink_sb_pool_type *p_pool_type)
259 return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
262 static int
263 devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
264 enum devlink_sb_threshold_type *p_th_type)
266 u8 val;
268 if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
269 return -EINVAL;
271 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
272 if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
273 val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
274 return -EINVAL;
275 *p_th_type = val;
276 return 0;
279 static int
280 devlink_sb_th_type_get_from_info(struct genl_info *info,
281 enum devlink_sb_threshold_type *p_th_type)
283 return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
286 static int
287 devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
288 struct nlattr **attrs,
289 enum devlink_sb_pool_type pool_type,
290 u16 *p_tc_index)
292 u16 val;
294 if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
295 return -EINVAL;
297 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
298 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
299 val >= devlink_sb->ingress_tc_count)
300 return -EINVAL;
301 if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
302 val >= devlink_sb->egress_tc_count)
303 return -EINVAL;
304 *p_tc_index = val;
305 return 0;
308 static int
309 devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
310 struct genl_info *info,
311 enum devlink_sb_pool_type pool_type,
312 u16 *p_tc_index)
314 return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
315 pool_type, p_tc_index);
318 #define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0)
319 #define DEVLINK_NL_FLAG_NEED_PORT BIT(1)
320 #define DEVLINK_NL_FLAG_NEED_SB BIT(2)
321 #define DEVLINK_NL_FLAG_LOCK_PORTS BIT(3)
322 /* port is not needed but we need to ensure they don't
323 * change in the middle of command
326 static int devlink_nl_pre_doit(const struct genl_ops *ops,
327 struct sk_buff *skb, struct genl_info *info)
329 struct devlink *devlink;
331 mutex_lock(&devlink_mutex);
332 devlink = devlink_get_from_info(info);
333 if (IS_ERR(devlink)) {
334 mutex_unlock(&devlink_mutex);
335 return PTR_ERR(devlink);
337 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) {
338 info->user_ptr[0] = devlink;
339 } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
340 struct devlink_port *devlink_port;
342 mutex_lock(&devlink_port_mutex);
343 devlink_port = devlink_port_get_from_info(devlink, info);
344 if (IS_ERR(devlink_port)) {
345 mutex_unlock(&devlink_port_mutex);
346 mutex_unlock(&devlink_mutex);
347 return PTR_ERR(devlink_port);
349 info->user_ptr[0] = devlink_port;
351 if (ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS) {
352 mutex_lock(&devlink_port_mutex);
354 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) {
355 struct devlink_sb *devlink_sb;
357 devlink_sb = devlink_sb_get_from_info(devlink, info);
358 if (IS_ERR(devlink_sb)) {
359 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT)
360 mutex_unlock(&devlink_port_mutex);
361 mutex_unlock(&devlink_mutex);
362 return PTR_ERR(devlink_sb);
364 info->user_ptr[1] = devlink_sb;
366 return 0;
369 static void devlink_nl_post_doit(const struct genl_ops *ops,
370 struct sk_buff *skb, struct genl_info *info)
372 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT ||
373 ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS)
374 mutex_unlock(&devlink_port_mutex);
375 mutex_unlock(&devlink_mutex);
378 static struct genl_family devlink_nl_family;
380 enum devlink_multicast_groups {
381 DEVLINK_MCGRP_CONFIG,
384 static const struct genl_multicast_group devlink_nl_mcgrps[] = {
385 [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
388 static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
390 if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
391 return -EMSGSIZE;
392 if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
393 return -EMSGSIZE;
394 return 0;
397 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
398 enum devlink_command cmd, u32 portid,
399 u32 seq, int flags)
401 void *hdr;
403 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
404 if (!hdr)
405 return -EMSGSIZE;
407 if (devlink_nl_put_handle(msg, devlink))
408 goto nla_put_failure;
410 genlmsg_end(msg, hdr);
411 return 0;
413 nla_put_failure:
414 genlmsg_cancel(msg, hdr);
415 return -EMSGSIZE;
418 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
420 struct sk_buff *msg;
421 int err;
423 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
425 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
426 if (!msg)
427 return;
429 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
430 if (err) {
431 nlmsg_free(msg);
432 return;
435 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
436 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
439 static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
440 struct devlink_port *devlink_port,
441 enum devlink_command cmd, u32 portid,
442 u32 seq, int flags)
444 void *hdr;
446 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
447 if (!hdr)
448 return -EMSGSIZE;
450 if (devlink_nl_put_handle(msg, devlink))
451 goto nla_put_failure;
452 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
453 goto nla_put_failure;
454 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
455 goto nla_put_failure;
456 if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
457 nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
458 devlink_port->desired_type))
459 goto nla_put_failure;
460 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
461 struct net_device *netdev = devlink_port->type_dev;
463 if (netdev &&
464 (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
465 netdev->ifindex) ||
466 nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
467 netdev->name)))
468 goto nla_put_failure;
470 if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
471 struct ib_device *ibdev = devlink_port->type_dev;
473 if (ibdev &&
474 nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
475 ibdev->name))
476 goto nla_put_failure;
478 if (devlink_port->split &&
479 nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
480 devlink_port->split_group))
481 goto nla_put_failure;
483 genlmsg_end(msg, hdr);
484 return 0;
486 nla_put_failure:
487 genlmsg_cancel(msg, hdr);
488 return -EMSGSIZE;
491 static void devlink_port_notify(struct devlink_port *devlink_port,
492 enum devlink_command cmd)
494 struct devlink *devlink = devlink_port->devlink;
495 struct sk_buff *msg;
496 int err;
498 if (!devlink_port->registered)
499 return;
501 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
503 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
504 if (!msg)
505 return;
507 err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);
508 if (err) {
509 nlmsg_free(msg);
510 return;
513 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
514 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
517 static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
519 struct devlink *devlink = info->user_ptr[0];
520 struct sk_buff *msg;
521 int err;
523 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
524 if (!msg)
525 return -ENOMEM;
527 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
528 info->snd_portid, info->snd_seq, 0);
529 if (err) {
530 nlmsg_free(msg);
531 return err;
534 return genlmsg_reply(msg, info);
537 static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
538 struct netlink_callback *cb)
540 struct devlink *devlink;
541 int start = cb->args[0];
542 int idx = 0;
543 int err;
545 mutex_lock(&devlink_mutex);
546 list_for_each_entry(devlink, &devlink_list, list) {
547 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
548 continue;
549 if (idx < start) {
550 idx++;
551 continue;
553 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
554 NETLINK_CB(cb->skb).portid,
555 cb->nlh->nlmsg_seq, NLM_F_MULTI);
556 if (err)
557 goto out;
558 idx++;
560 out:
561 mutex_unlock(&devlink_mutex);
563 cb->args[0] = idx;
564 return msg->len;
567 static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
568 struct genl_info *info)
570 struct devlink_port *devlink_port = info->user_ptr[0];
571 struct devlink *devlink = devlink_port->devlink;
572 struct sk_buff *msg;
573 int err;
575 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
576 if (!msg)
577 return -ENOMEM;
579 err = devlink_nl_port_fill(msg, devlink, devlink_port,
580 DEVLINK_CMD_PORT_NEW,
581 info->snd_portid, info->snd_seq, 0);
582 if (err) {
583 nlmsg_free(msg);
584 return err;
587 return genlmsg_reply(msg, info);
590 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
591 struct netlink_callback *cb)
593 struct devlink *devlink;
594 struct devlink_port *devlink_port;
595 int start = cb->args[0];
596 int idx = 0;
597 int err;
599 mutex_lock(&devlink_mutex);
600 mutex_lock(&devlink_port_mutex);
601 list_for_each_entry(devlink, &devlink_list, list) {
602 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
603 continue;
604 list_for_each_entry(devlink_port, &devlink->port_list, list) {
605 if (idx < start) {
606 idx++;
607 continue;
609 err = devlink_nl_port_fill(msg, devlink, devlink_port,
610 DEVLINK_CMD_NEW,
611 NETLINK_CB(cb->skb).portid,
612 cb->nlh->nlmsg_seq,
613 NLM_F_MULTI);
614 if (err)
615 goto out;
616 idx++;
619 out:
620 mutex_unlock(&devlink_port_mutex);
621 mutex_unlock(&devlink_mutex);
623 cb->args[0] = idx;
624 return msg->len;
627 static int devlink_port_type_set(struct devlink *devlink,
628 struct devlink_port *devlink_port,
629 enum devlink_port_type port_type)
632 int err;
634 if (devlink->ops && devlink->ops->port_type_set) {
635 if (port_type == DEVLINK_PORT_TYPE_NOTSET)
636 return -EINVAL;
637 if (port_type == devlink_port->type)
638 return 0;
639 err = devlink->ops->port_type_set(devlink_port, port_type);
640 if (err)
641 return err;
642 devlink_port->desired_type = port_type;
643 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
644 return 0;
646 return -EOPNOTSUPP;
649 static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
650 struct genl_info *info)
652 struct devlink_port *devlink_port = info->user_ptr[0];
653 struct devlink *devlink = devlink_port->devlink;
654 int err;
656 if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
657 enum devlink_port_type port_type;
659 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
660 err = devlink_port_type_set(devlink, devlink_port, port_type);
661 if (err)
662 return err;
664 return 0;
667 static int devlink_port_split(struct devlink *devlink,
668 u32 port_index, u32 count)
671 if (devlink->ops && devlink->ops->port_split)
672 return devlink->ops->port_split(devlink, port_index, count);
673 return -EOPNOTSUPP;
676 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
677 struct genl_info *info)
679 struct devlink *devlink = info->user_ptr[0];
680 u32 port_index;
681 u32 count;
683 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
684 !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
685 return -EINVAL;
687 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
688 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
689 return devlink_port_split(devlink, port_index, count);
692 static int devlink_port_unsplit(struct devlink *devlink, u32 port_index)
695 if (devlink->ops && devlink->ops->port_unsplit)
696 return devlink->ops->port_unsplit(devlink, port_index);
697 return -EOPNOTSUPP;
700 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
701 struct genl_info *info)
703 struct devlink *devlink = info->user_ptr[0];
704 u32 port_index;
706 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
707 return -EINVAL;
709 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
710 return devlink_port_unsplit(devlink, port_index);
713 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
714 struct devlink_sb *devlink_sb,
715 enum devlink_command cmd, u32 portid,
716 u32 seq, int flags)
718 void *hdr;
720 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
721 if (!hdr)
722 return -EMSGSIZE;
724 if (devlink_nl_put_handle(msg, devlink))
725 goto nla_put_failure;
726 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
727 goto nla_put_failure;
728 if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
729 goto nla_put_failure;
730 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
731 devlink_sb->ingress_pools_count))
732 goto nla_put_failure;
733 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
734 devlink_sb->egress_pools_count))
735 goto nla_put_failure;
736 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
737 devlink_sb->ingress_tc_count))
738 goto nla_put_failure;
739 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
740 devlink_sb->egress_tc_count))
741 goto nla_put_failure;
743 genlmsg_end(msg, hdr);
744 return 0;
746 nla_put_failure:
747 genlmsg_cancel(msg, hdr);
748 return -EMSGSIZE;
751 static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
752 struct genl_info *info)
754 struct devlink *devlink = info->user_ptr[0];
755 struct devlink_sb *devlink_sb = info->user_ptr[1];
756 struct sk_buff *msg;
757 int err;
759 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
760 if (!msg)
761 return -ENOMEM;
763 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
764 DEVLINK_CMD_SB_NEW,
765 info->snd_portid, info->snd_seq, 0);
766 if (err) {
767 nlmsg_free(msg);
768 return err;
771 return genlmsg_reply(msg, info);
774 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
775 struct netlink_callback *cb)
777 struct devlink *devlink;
778 struct devlink_sb *devlink_sb;
779 int start = cb->args[0];
780 int idx = 0;
781 int err;
783 mutex_lock(&devlink_mutex);
784 list_for_each_entry(devlink, &devlink_list, list) {
785 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
786 continue;
787 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
788 if (idx < start) {
789 idx++;
790 continue;
792 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
793 DEVLINK_CMD_SB_NEW,
794 NETLINK_CB(cb->skb).portid,
795 cb->nlh->nlmsg_seq,
796 NLM_F_MULTI);
797 if (err)
798 goto out;
799 idx++;
802 out:
803 mutex_unlock(&devlink_mutex);
805 cb->args[0] = idx;
806 return msg->len;
809 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
810 struct devlink_sb *devlink_sb,
811 u16 pool_index, enum devlink_command cmd,
812 u32 portid, u32 seq, int flags)
814 struct devlink_sb_pool_info pool_info;
815 void *hdr;
816 int err;
818 err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
819 pool_index, &pool_info);
820 if (err)
821 return err;
823 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
824 if (!hdr)
825 return -EMSGSIZE;
827 if (devlink_nl_put_handle(msg, devlink))
828 goto nla_put_failure;
829 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
830 goto nla_put_failure;
831 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
832 goto nla_put_failure;
833 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
834 goto nla_put_failure;
835 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
836 goto nla_put_failure;
837 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
838 pool_info.threshold_type))
839 goto nla_put_failure;
841 genlmsg_end(msg, hdr);
842 return 0;
844 nla_put_failure:
845 genlmsg_cancel(msg, hdr);
846 return -EMSGSIZE;
849 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
850 struct genl_info *info)
852 struct devlink *devlink = info->user_ptr[0];
853 struct devlink_sb *devlink_sb = info->user_ptr[1];
854 struct sk_buff *msg;
855 u16 pool_index;
856 int err;
858 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
859 &pool_index);
860 if (err)
861 return err;
863 if (!devlink->ops || !devlink->ops->sb_pool_get)
864 return -EOPNOTSUPP;
866 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
867 if (!msg)
868 return -ENOMEM;
870 err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
871 DEVLINK_CMD_SB_POOL_NEW,
872 info->snd_portid, info->snd_seq, 0);
873 if (err) {
874 nlmsg_free(msg);
875 return err;
878 return genlmsg_reply(msg, info);
881 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
882 struct devlink *devlink,
883 struct devlink_sb *devlink_sb,
884 u32 portid, u32 seq)
886 u16 pool_count = devlink_sb_pool_count(devlink_sb);
887 u16 pool_index;
888 int err;
890 for (pool_index = 0; pool_index < pool_count; pool_index++) {
891 if (*p_idx < start) {
892 (*p_idx)++;
893 continue;
895 err = devlink_nl_sb_pool_fill(msg, devlink,
896 devlink_sb,
897 pool_index,
898 DEVLINK_CMD_SB_POOL_NEW,
899 portid, seq, NLM_F_MULTI);
900 if (err)
901 return err;
902 (*p_idx)++;
904 return 0;
907 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
908 struct netlink_callback *cb)
910 struct devlink *devlink;
911 struct devlink_sb *devlink_sb;
912 int start = cb->args[0];
913 int idx = 0;
914 int err;
916 mutex_lock(&devlink_mutex);
917 list_for_each_entry(devlink, &devlink_list, list) {
918 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
919 !devlink->ops || !devlink->ops->sb_pool_get)
920 continue;
921 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
922 err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
923 devlink_sb,
924 NETLINK_CB(cb->skb).portid,
925 cb->nlh->nlmsg_seq);
926 if (err && err != -EOPNOTSUPP)
927 goto out;
930 out:
931 mutex_unlock(&devlink_mutex);
933 cb->args[0] = idx;
934 return msg->len;
937 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
938 u16 pool_index, u32 size,
939 enum devlink_sb_threshold_type threshold_type)
942 const struct devlink_ops *ops = devlink->ops;
944 if (ops && ops->sb_pool_set)
945 return ops->sb_pool_set(devlink, sb_index, pool_index,
946 size, threshold_type);
947 return -EOPNOTSUPP;
950 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
951 struct genl_info *info)
953 struct devlink *devlink = info->user_ptr[0];
954 struct devlink_sb *devlink_sb = info->user_ptr[1];
955 enum devlink_sb_threshold_type threshold_type;
956 u16 pool_index;
957 u32 size;
958 int err;
960 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
961 &pool_index);
962 if (err)
963 return err;
965 err = devlink_sb_th_type_get_from_info(info, &threshold_type);
966 if (err)
967 return err;
969 if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
970 return -EINVAL;
972 size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
973 return devlink_sb_pool_set(devlink, devlink_sb->index,
974 pool_index, size, threshold_type);
977 static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
978 struct devlink *devlink,
979 struct devlink_port *devlink_port,
980 struct devlink_sb *devlink_sb,
981 u16 pool_index,
982 enum devlink_command cmd,
983 u32 portid, u32 seq, int flags)
985 const struct devlink_ops *ops = devlink->ops;
986 u32 threshold;
987 void *hdr;
988 int err;
990 err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
991 pool_index, &threshold);
992 if (err)
993 return err;
995 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
996 if (!hdr)
997 return -EMSGSIZE;
999 if (devlink_nl_put_handle(msg, devlink))
1000 goto nla_put_failure;
1001 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1002 goto nla_put_failure;
1003 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1004 goto nla_put_failure;
1005 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1006 goto nla_put_failure;
1007 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1008 goto nla_put_failure;
1010 if (ops->sb_occ_port_pool_get) {
1011 u32 cur;
1012 u32 max;
1014 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
1015 pool_index, &cur, &max);
1016 if (err && err != -EOPNOTSUPP)
1017 return err;
1018 if (!err) {
1019 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1020 goto nla_put_failure;
1021 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1022 goto nla_put_failure;
1026 genlmsg_end(msg, hdr);
1027 return 0;
1029 nla_put_failure:
1030 genlmsg_cancel(msg, hdr);
1031 return -EMSGSIZE;
1034 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
1035 struct genl_info *info)
1037 struct devlink_port *devlink_port = info->user_ptr[0];
1038 struct devlink *devlink = devlink_port->devlink;
1039 struct devlink_sb *devlink_sb = info->user_ptr[1];
1040 struct sk_buff *msg;
1041 u16 pool_index;
1042 int err;
1044 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1045 &pool_index);
1046 if (err)
1047 return err;
1049 if (!devlink->ops || !devlink->ops->sb_port_pool_get)
1050 return -EOPNOTSUPP;
1052 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1053 if (!msg)
1054 return -ENOMEM;
1056 err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
1057 devlink_sb, pool_index,
1058 DEVLINK_CMD_SB_PORT_POOL_NEW,
1059 info->snd_portid, info->snd_seq, 0);
1060 if (err) {
1061 nlmsg_free(msg);
1062 return err;
1065 return genlmsg_reply(msg, info);
1068 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1069 struct devlink *devlink,
1070 struct devlink_sb *devlink_sb,
1071 u32 portid, u32 seq)
1073 struct devlink_port *devlink_port;
1074 u16 pool_count = devlink_sb_pool_count(devlink_sb);
1075 u16 pool_index;
1076 int err;
1078 list_for_each_entry(devlink_port, &devlink->port_list, list) {
1079 for (pool_index = 0; pool_index < pool_count; pool_index++) {
1080 if (*p_idx < start) {
1081 (*p_idx)++;
1082 continue;
1084 err = devlink_nl_sb_port_pool_fill(msg, devlink,
1085 devlink_port,
1086 devlink_sb,
1087 pool_index,
1088 DEVLINK_CMD_SB_PORT_POOL_NEW,
1089 portid, seq,
1090 NLM_F_MULTI);
1091 if (err)
1092 return err;
1093 (*p_idx)++;
1096 return 0;
1099 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
1100 struct netlink_callback *cb)
1102 struct devlink *devlink;
1103 struct devlink_sb *devlink_sb;
1104 int start = cb->args[0];
1105 int idx = 0;
1106 int err;
1108 mutex_lock(&devlink_mutex);
1109 mutex_lock(&devlink_port_mutex);
1110 list_for_each_entry(devlink, &devlink_list, list) {
1111 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1112 !devlink->ops || !devlink->ops->sb_port_pool_get)
1113 continue;
1114 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1115 err = __sb_port_pool_get_dumpit(msg, start, &idx,
1116 devlink, devlink_sb,
1117 NETLINK_CB(cb->skb).portid,
1118 cb->nlh->nlmsg_seq);
1119 if (err && err != -EOPNOTSUPP)
1120 goto out;
1123 out:
1124 mutex_unlock(&devlink_port_mutex);
1125 mutex_unlock(&devlink_mutex);
1127 cb->args[0] = idx;
1128 return msg->len;
1131 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
1132 unsigned int sb_index, u16 pool_index,
1133 u32 threshold)
1136 const struct devlink_ops *ops = devlink_port->devlink->ops;
1138 if (ops && ops->sb_port_pool_set)
1139 return ops->sb_port_pool_set(devlink_port, sb_index,
1140 pool_index, threshold);
1141 return -EOPNOTSUPP;
1144 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
1145 struct genl_info *info)
1147 struct devlink_port *devlink_port = info->user_ptr[0];
1148 struct devlink_sb *devlink_sb = info->user_ptr[1];
1149 u16 pool_index;
1150 u32 threshold;
1151 int err;
1153 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1154 &pool_index);
1155 if (err)
1156 return err;
1158 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1159 return -EINVAL;
1161 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1162 return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
1163 pool_index, threshold);
1166 static int
1167 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
1168 struct devlink_port *devlink_port,
1169 struct devlink_sb *devlink_sb, u16 tc_index,
1170 enum devlink_sb_pool_type pool_type,
1171 enum devlink_command cmd,
1172 u32 portid, u32 seq, int flags)
1174 const struct devlink_ops *ops = devlink->ops;
1175 u16 pool_index;
1176 u32 threshold;
1177 void *hdr;
1178 int err;
1180 err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
1181 tc_index, pool_type,
1182 &pool_index, &threshold);
1183 if (err)
1184 return err;
1186 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1187 if (!hdr)
1188 return -EMSGSIZE;
1190 if (devlink_nl_put_handle(msg, devlink))
1191 goto nla_put_failure;
1192 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1193 goto nla_put_failure;
1194 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1195 goto nla_put_failure;
1196 if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
1197 goto nla_put_failure;
1198 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
1199 goto nla_put_failure;
1200 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1201 goto nla_put_failure;
1202 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1203 goto nla_put_failure;
1205 if (ops->sb_occ_tc_port_bind_get) {
1206 u32 cur;
1207 u32 max;
1209 err = ops->sb_occ_tc_port_bind_get(devlink_port,
1210 devlink_sb->index,
1211 tc_index, pool_type,
1212 &cur, &max);
1213 if (err && err != -EOPNOTSUPP)
1214 return err;
1215 if (!err) {
1216 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1217 goto nla_put_failure;
1218 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1219 goto nla_put_failure;
1223 genlmsg_end(msg, hdr);
1224 return 0;
1226 nla_put_failure:
1227 genlmsg_cancel(msg, hdr);
1228 return -EMSGSIZE;
1231 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
1232 struct genl_info *info)
1234 struct devlink_port *devlink_port = info->user_ptr[0];
1235 struct devlink *devlink = devlink_port->devlink;
1236 struct devlink_sb *devlink_sb = info->user_ptr[1];
1237 struct sk_buff *msg;
1238 enum devlink_sb_pool_type pool_type;
1239 u16 tc_index;
1240 int err;
1242 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1243 if (err)
1244 return err;
1246 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1247 pool_type, &tc_index);
1248 if (err)
1249 return err;
1251 if (!devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
1252 return -EOPNOTSUPP;
1254 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1255 if (!msg)
1256 return -ENOMEM;
1258 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
1259 devlink_sb, tc_index, pool_type,
1260 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1261 info->snd_portid,
1262 info->snd_seq, 0);
1263 if (err) {
1264 nlmsg_free(msg);
1265 return err;
1268 return genlmsg_reply(msg, info);
1271 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1272 int start, int *p_idx,
1273 struct devlink *devlink,
1274 struct devlink_sb *devlink_sb,
1275 u32 portid, u32 seq)
1277 struct devlink_port *devlink_port;
1278 u16 tc_index;
1279 int err;
1281 list_for_each_entry(devlink_port, &devlink->port_list, list) {
1282 for (tc_index = 0;
1283 tc_index < devlink_sb->ingress_tc_count; tc_index++) {
1284 if (*p_idx < start) {
1285 (*p_idx)++;
1286 continue;
1288 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1289 devlink_port,
1290 devlink_sb,
1291 tc_index,
1292 DEVLINK_SB_POOL_TYPE_INGRESS,
1293 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1294 portid, seq,
1295 NLM_F_MULTI);
1296 if (err)
1297 return err;
1298 (*p_idx)++;
1300 for (tc_index = 0;
1301 tc_index < devlink_sb->egress_tc_count; tc_index++) {
1302 if (*p_idx < start) {
1303 (*p_idx)++;
1304 continue;
1306 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1307 devlink_port,
1308 devlink_sb,
1309 tc_index,
1310 DEVLINK_SB_POOL_TYPE_EGRESS,
1311 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1312 portid, seq,
1313 NLM_F_MULTI);
1314 if (err)
1315 return err;
1316 (*p_idx)++;
1319 return 0;
1322 static int
1323 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1324 struct netlink_callback *cb)
1326 struct devlink *devlink;
1327 struct devlink_sb *devlink_sb;
1328 int start = cb->args[0];
1329 int idx = 0;
1330 int err;
1332 mutex_lock(&devlink_mutex);
1333 mutex_lock(&devlink_port_mutex);
1334 list_for_each_entry(devlink, &devlink_list, list) {
1335 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1336 !devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
1337 continue;
1338 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1339 err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
1340 devlink,
1341 devlink_sb,
1342 NETLINK_CB(cb->skb).portid,
1343 cb->nlh->nlmsg_seq);
1344 if (err && err != -EOPNOTSUPP)
1345 goto out;
1348 out:
1349 mutex_unlock(&devlink_port_mutex);
1350 mutex_unlock(&devlink_mutex);
1352 cb->args[0] = idx;
1353 return msg->len;
1356 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
1357 unsigned int sb_index, u16 tc_index,
1358 enum devlink_sb_pool_type pool_type,
1359 u16 pool_index, u32 threshold)
1362 const struct devlink_ops *ops = devlink_port->devlink->ops;
1364 if (ops && ops->sb_tc_pool_bind_set)
1365 return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
1366 tc_index, pool_type,
1367 pool_index, threshold);
1368 return -EOPNOTSUPP;
1371 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
1372 struct genl_info *info)
1374 struct devlink_port *devlink_port = info->user_ptr[0];
1375 struct devlink_sb *devlink_sb = info->user_ptr[1];
1376 enum devlink_sb_pool_type pool_type;
1377 u16 tc_index;
1378 u16 pool_index;
1379 u32 threshold;
1380 int err;
1382 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1383 if (err)
1384 return err;
1386 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1387 pool_type, &tc_index);
1388 if (err)
1389 return err;
1391 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1392 &pool_index);
1393 if (err)
1394 return err;
1396 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1397 return -EINVAL;
1399 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1400 return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
1401 tc_index, pool_type,
1402 pool_index, threshold);
1405 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
1406 struct genl_info *info)
1408 struct devlink *devlink = info->user_ptr[0];
1409 struct devlink_sb *devlink_sb = info->user_ptr[1];
1410 const struct devlink_ops *ops = devlink->ops;
1412 if (ops && ops->sb_occ_snapshot)
1413 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
1414 return -EOPNOTSUPP;
1417 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
1418 struct genl_info *info)
1420 struct devlink *devlink = info->user_ptr[0];
1421 struct devlink_sb *devlink_sb = info->user_ptr[1];
1422 const struct devlink_ops *ops = devlink->ops;
1424 if (ops && ops->sb_occ_max_clear)
1425 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
1426 return -EOPNOTSUPP;
1429 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
1430 enum devlink_command cmd, u32 portid,
1431 u32 seq, int flags)
1433 const struct devlink_ops *ops = devlink->ops;
1434 u8 inline_mode, encap_mode;
1435 void *hdr;
1436 int err = 0;
1437 u16 mode;
1439 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1440 if (!hdr)
1441 return -EMSGSIZE;
1443 err = devlink_nl_put_handle(msg, devlink);
1444 if (err)
1445 goto nla_put_failure;
1447 if (ops->eswitch_mode_get) {
1448 err = ops->eswitch_mode_get(devlink, &mode);
1449 if (err)
1450 goto nla_put_failure;
1451 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
1452 if (err)
1453 goto nla_put_failure;
1456 if (ops->eswitch_inline_mode_get) {
1457 err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
1458 if (err)
1459 goto nla_put_failure;
1460 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
1461 inline_mode);
1462 if (err)
1463 goto nla_put_failure;
1466 if (ops->eswitch_encap_mode_get) {
1467 err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
1468 if (err)
1469 goto nla_put_failure;
1470 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
1471 if (err)
1472 goto nla_put_failure;
1475 genlmsg_end(msg, hdr);
1476 return 0;
1478 nla_put_failure:
1479 genlmsg_cancel(msg, hdr);
1480 return err;
1483 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
1484 struct genl_info *info)
1486 struct devlink *devlink = info->user_ptr[0];
1487 const struct devlink_ops *ops = devlink->ops;
1488 struct sk_buff *msg;
1489 int err;
1491 if (!ops)
1492 return -EOPNOTSUPP;
1494 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1495 if (!msg)
1496 return -ENOMEM;
1498 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
1499 info->snd_portid, info->snd_seq, 0);
1501 if (err) {
1502 nlmsg_free(msg);
1503 return err;
1506 return genlmsg_reply(msg, info);
1509 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
1510 struct genl_info *info)
1512 struct devlink *devlink = info->user_ptr[0];
1513 const struct devlink_ops *ops = devlink->ops;
1514 u8 inline_mode, encap_mode;
1515 int err = 0;
1516 u16 mode;
1518 if (!ops)
1519 return -EOPNOTSUPP;
1521 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
1522 if (!ops->eswitch_mode_set)
1523 return -EOPNOTSUPP;
1524 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1525 err = ops->eswitch_mode_set(devlink, mode);
1526 if (err)
1527 return err;
1530 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
1531 if (!ops->eswitch_inline_mode_set)
1532 return -EOPNOTSUPP;
1533 inline_mode = nla_get_u8(
1534 info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
1535 err = ops->eswitch_inline_mode_set(devlink, inline_mode);
1536 if (err)
1537 return err;
1540 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
1541 if (!ops->eswitch_encap_mode_set)
1542 return -EOPNOTSUPP;
1543 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
1544 err = ops->eswitch_encap_mode_set(devlink, encap_mode);
1545 if (err)
1546 return err;
1549 return 0;
1552 int devlink_dpipe_match_put(struct sk_buff *skb,
1553 struct devlink_dpipe_match *match)
1555 struct devlink_dpipe_header *header = match->header;
1556 struct devlink_dpipe_field *field = &header->fields[match->field_id];
1557 struct nlattr *match_attr;
1559 match_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_MATCH);
1560 if (!match_attr)
1561 return -EMSGSIZE;
1563 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
1564 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
1565 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1566 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1567 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1568 goto nla_put_failure;
1570 nla_nest_end(skb, match_attr);
1571 return 0;
1573 nla_put_failure:
1574 nla_nest_cancel(skb, match_attr);
1575 return -EMSGSIZE;
1577 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
1579 static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
1580 struct sk_buff *skb)
1582 struct nlattr *matches_attr;
1584 matches_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
1585 if (!matches_attr)
1586 return -EMSGSIZE;
1588 if (table->table_ops->matches_dump(table->priv, skb))
1589 goto nla_put_failure;
1591 nla_nest_end(skb, matches_attr);
1592 return 0;
1594 nla_put_failure:
1595 nla_nest_cancel(skb, matches_attr);
1596 return -EMSGSIZE;
1599 int devlink_dpipe_action_put(struct sk_buff *skb,
1600 struct devlink_dpipe_action *action)
1602 struct devlink_dpipe_header *header = action->header;
1603 struct devlink_dpipe_field *field = &header->fields[action->field_id];
1604 struct nlattr *action_attr;
1606 action_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_ACTION);
1607 if (!action_attr)
1608 return -EMSGSIZE;
1610 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
1611 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
1612 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1613 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1614 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1615 goto nla_put_failure;
1617 nla_nest_end(skb, action_attr);
1618 return 0;
1620 nla_put_failure:
1621 nla_nest_cancel(skb, action_attr);
1622 return -EMSGSIZE;
1624 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
1626 static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
1627 struct sk_buff *skb)
1629 struct nlattr *actions_attr;
1631 actions_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
1632 if (!actions_attr)
1633 return -EMSGSIZE;
1635 if (table->table_ops->actions_dump(table->priv, skb))
1636 goto nla_put_failure;
1638 nla_nest_end(skb, actions_attr);
1639 return 0;
1641 nla_put_failure:
1642 nla_nest_cancel(skb, actions_attr);
1643 return -EMSGSIZE;
1646 static int devlink_dpipe_table_put(struct sk_buff *skb,
1647 struct devlink_dpipe_table *table)
1649 struct nlattr *table_attr;
1650 u64 table_size;
1652 table_size = table->table_ops->size_get(table->priv);
1653 table_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE);
1654 if (!table_attr)
1655 return -EMSGSIZE;
1657 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
1658 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
1659 DEVLINK_ATTR_PAD))
1660 goto nla_put_failure;
1661 if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
1662 table->counters_enabled))
1663 goto nla_put_failure;
1665 if (devlink_dpipe_matches_put(table, skb))
1666 goto nla_put_failure;
1668 if (devlink_dpipe_actions_put(table, skb))
1669 goto nla_put_failure;
1671 nla_nest_end(skb, table_attr);
1672 return 0;
1674 nla_put_failure:
1675 nla_nest_cancel(skb, table_attr);
1676 return -EMSGSIZE;
1679 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
1680 struct genl_info *info)
1682 int err;
1684 if (*pskb) {
1685 err = genlmsg_reply(*pskb, info);
1686 if (err)
1687 return err;
1689 *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
1690 if (!*pskb)
1691 return -ENOMEM;
1692 return 0;
1695 static int devlink_dpipe_tables_fill(struct genl_info *info,
1696 enum devlink_command cmd, int flags,
1697 struct list_head *dpipe_tables,
1698 const char *table_name)
1700 struct devlink *devlink = info->user_ptr[0];
1701 struct devlink_dpipe_table *table;
1702 struct nlattr *tables_attr;
1703 struct sk_buff *skb = NULL;
1704 struct nlmsghdr *nlh;
1705 bool incomplete;
1706 void *hdr;
1707 int i;
1708 int err;
1710 table = list_first_entry(dpipe_tables,
1711 struct devlink_dpipe_table, list);
1712 start_again:
1713 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1714 if (err)
1715 return err;
1717 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
1718 &devlink_nl_family, NLM_F_MULTI, cmd);
1719 if (!hdr) {
1720 nlmsg_free(skb);
1721 return -EMSGSIZE;
1724 if (devlink_nl_put_handle(skb, devlink))
1725 goto nla_put_failure;
1726 tables_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLES);
1727 if (!tables_attr)
1728 goto nla_put_failure;
1730 i = 0;
1731 incomplete = false;
1732 list_for_each_entry_from(table, dpipe_tables, list) {
1733 if (!table_name) {
1734 err = devlink_dpipe_table_put(skb, table);
1735 if (err) {
1736 if (!i)
1737 goto err_table_put;
1738 incomplete = true;
1739 break;
1741 } else {
1742 if (!strcmp(table->name, table_name)) {
1743 err = devlink_dpipe_table_put(skb, table);
1744 if (err)
1745 break;
1748 i++;
1751 nla_nest_end(skb, tables_attr);
1752 genlmsg_end(skb, hdr);
1753 if (incomplete)
1754 goto start_again;
1756 send_done:
1757 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
1758 NLMSG_DONE, 0, flags | NLM_F_MULTI);
1759 if (!nlh) {
1760 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1761 if (err)
1762 goto err_skb_send_alloc;
1763 goto send_done;
1766 return genlmsg_reply(skb, info);
1768 nla_put_failure:
1769 err = -EMSGSIZE;
1770 err_table_put:
1771 err_skb_send_alloc:
1772 genlmsg_cancel(skb, hdr);
1773 nlmsg_free(skb);
1774 return err;
1777 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
1778 struct genl_info *info)
1780 struct devlink *devlink = info->user_ptr[0];
1781 const char *table_name = NULL;
1783 if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
1784 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
1786 return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
1787 &devlink->dpipe_table_list,
1788 table_name);
1791 static int devlink_dpipe_value_put(struct sk_buff *skb,
1792 struct devlink_dpipe_value *value)
1794 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
1795 value->value_size, value->value))
1796 return -EMSGSIZE;
1797 if (value->mask)
1798 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
1799 value->value_size, value->mask))
1800 return -EMSGSIZE;
1801 if (value->mapping_valid)
1802 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
1803 value->mapping_value))
1804 return -EMSGSIZE;
1805 return 0;
1808 static int devlink_dpipe_action_value_put(struct sk_buff *skb,
1809 struct devlink_dpipe_value *value)
1811 if (!value->action)
1812 return -EINVAL;
1813 if (devlink_dpipe_action_put(skb, value->action))
1814 return -EMSGSIZE;
1815 if (devlink_dpipe_value_put(skb, value))
1816 return -EMSGSIZE;
1817 return 0;
1820 static int devlink_dpipe_action_values_put(struct sk_buff *skb,
1821 struct devlink_dpipe_value *values,
1822 unsigned int values_count)
1824 struct nlattr *action_attr;
1825 int i;
1826 int err;
1828 for (i = 0; i < values_count; i++) {
1829 action_attr = nla_nest_start(skb,
1830 DEVLINK_ATTR_DPIPE_ACTION_VALUE);
1831 if (!action_attr)
1832 return -EMSGSIZE;
1833 err = devlink_dpipe_action_value_put(skb, &values[i]);
1834 if (err)
1835 goto err_action_value_put;
1836 nla_nest_end(skb, action_attr);
1838 return 0;
1840 err_action_value_put:
1841 nla_nest_cancel(skb, action_attr);
1842 return err;
1845 static int devlink_dpipe_match_value_put(struct sk_buff *skb,
1846 struct devlink_dpipe_value *value)
1848 if (!value->match)
1849 return -EINVAL;
1850 if (devlink_dpipe_match_put(skb, value->match))
1851 return -EMSGSIZE;
1852 if (devlink_dpipe_value_put(skb, value))
1853 return -EMSGSIZE;
1854 return 0;
1857 static int devlink_dpipe_match_values_put(struct sk_buff *skb,
1858 struct devlink_dpipe_value *values,
1859 unsigned int values_count)
1861 struct nlattr *match_attr;
1862 int i;
1863 int err;
1865 for (i = 0; i < values_count; i++) {
1866 match_attr = nla_nest_start(skb,
1867 DEVLINK_ATTR_DPIPE_MATCH_VALUE);
1868 if (!match_attr)
1869 return -EMSGSIZE;
1870 err = devlink_dpipe_match_value_put(skb, &values[i]);
1871 if (err)
1872 goto err_match_value_put;
1873 nla_nest_end(skb, match_attr);
1875 return 0;
1877 err_match_value_put:
1878 nla_nest_cancel(skb, match_attr);
1879 return err;
1882 static int devlink_dpipe_entry_put(struct sk_buff *skb,
1883 struct devlink_dpipe_entry *entry)
1885 struct nlattr *entry_attr, *matches_attr, *actions_attr;
1886 int err;
1888 entry_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_ENTRY);
1889 if (!entry_attr)
1890 return -EMSGSIZE;
1892 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
1893 DEVLINK_ATTR_PAD))
1894 goto nla_put_failure;
1895 if (entry->counter_valid)
1896 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
1897 entry->counter, DEVLINK_ATTR_PAD))
1898 goto nla_put_failure;
1900 matches_attr = nla_nest_start(skb,
1901 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
1902 if (!matches_attr)
1903 goto nla_put_failure;
1905 err = devlink_dpipe_match_values_put(skb, entry->match_values,
1906 entry->match_values_count);
1907 if (err) {
1908 nla_nest_cancel(skb, matches_attr);
1909 goto err_match_values_put;
1911 nla_nest_end(skb, matches_attr);
1913 actions_attr = nla_nest_start(skb,
1914 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
1915 if (!actions_attr)
1916 goto nla_put_failure;
1918 err = devlink_dpipe_action_values_put(skb, entry->action_values,
1919 entry->action_values_count);
1920 if (err) {
1921 nla_nest_cancel(skb, actions_attr);
1922 goto err_action_values_put;
1924 nla_nest_end(skb, actions_attr);
1926 nla_nest_end(skb, entry_attr);
1927 return 0;
1929 nla_put_failure:
1930 err = -EMSGSIZE;
1931 err_match_values_put:
1932 err_action_values_put:
1933 nla_nest_cancel(skb, entry_attr);
1934 return err;
1937 static struct devlink_dpipe_table *
1938 devlink_dpipe_table_find(struct list_head *dpipe_tables,
1939 const char *table_name)
1941 struct devlink_dpipe_table *table;
1943 list_for_each_entry_rcu(table, dpipe_tables, list) {
1944 if (!strcmp(table->name, table_name))
1945 return table;
1947 return NULL;
1950 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
1952 struct devlink *devlink;
1953 int err;
1955 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
1956 dump_ctx->info);
1957 if (err)
1958 return err;
1960 dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
1961 dump_ctx->info->snd_portid,
1962 dump_ctx->info->snd_seq,
1963 &devlink_nl_family, NLM_F_MULTI,
1964 dump_ctx->cmd);
1965 if (!dump_ctx->hdr)
1966 goto nla_put_failure;
1968 devlink = dump_ctx->info->user_ptr[0];
1969 if (devlink_nl_put_handle(dump_ctx->skb, devlink))
1970 goto nla_put_failure;
1971 dump_ctx->nest = nla_nest_start(dump_ctx->skb,
1972 DEVLINK_ATTR_DPIPE_ENTRIES);
1973 if (!dump_ctx->nest)
1974 goto nla_put_failure;
1975 return 0;
1977 nla_put_failure:
1978 genlmsg_cancel(dump_ctx->skb, dump_ctx->hdr);
1979 nlmsg_free(dump_ctx->skb);
1980 return -EMSGSIZE;
1982 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
1984 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
1985 struct devlink_dpipe_entry *entry)
1987 return devlink_dpipe_entry_put(dump_ctx->skb, entry);
1989 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
1991 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
1993 nla_nest_end(dump_ctx->skb, dump_ctx->nest);
1994 genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
1995 return 0;
1997 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
1999 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
2002 unsigned int value_count, value_index;
2003 struct devlink_dpipe_value *value;
2005 value = entry->action_values;
2006 value_count = entry->action_values_count;
2007 for (value_index = 0; value_index < value_count; value_index++) {
2008 kfree(value[value_index].value);
2009 kfree(value[value_index].mask);
2012 value = entry->match_values;
2013 value_count = entry->match_values_count;
2014 for (value_index = 0; value_index < value_count; value_index++) {
2015 kfree(value[value_index].value);
2016 kfree(value[value_index].mask);
2019 EXPORT_SYMBOL(devlink_dpipe_entry_clear);
2021 static int devlink_dpipe_entries_fill(struct genl_info *info,
2022 enum devlink_command cmd, int flags,
2023 struct devlink_dpipe_table *table)
2025 struct devlink_dpipe_dump_ctx dump_ctx;
2026 struct nlmsghdr *nlh;
2027 int err;
2029 dump_ctx.skb = NULL;
2030 dump_ctx.cmd = cmd;
2031 dump_ctx.info = info;
2033 err = table->table_ops->entries_dump(table->priv,
2034 table->counters_enabled,
2035 &dump_ctx);
2036 if (err)
2037 goto err_entries_dump;
2039 send_done:
2040 nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
2041 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2042 if (!nlh) {
2043 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
2044 if (err)
2045 goto err_skb_send_alloc;
2046 goto send_done;
2048 return genlmsg_reply(dump_ctx.skb, info);
2050 err_entries_dump:
2051 err_skb_send_alloc:
2052 genlmsg_cancel(dump_ctx.skb, dump_ctx.hdr);
2053 nlmsg_free(dump_ctx.skb);
2054 return err;
2057 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
2058 struct genl_info *info)
2060 struct devlink *devlink = info->user_ptr[0];
2061 struct devlink_dpipe_table *table;
2062 const char *table_name;
2064 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
2065 return -EINVAL;
2067 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2068 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2069 table_name);
2070 if (!table)
2071 return -EINVAL;
2073 if (!table->table_ops->entries_dump)
2074 return -EINVAL;
2076 return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
2077 0, table);
2080 static int devlink_dpipe_fields_put(struct sk_buff *skb,
2081 const struct devlink_dpipe_header *header)
2083 struct devlink_dpipe_field *field;
2084 struct nlattr *field_attr;
2085 int i;
2087 for (i = 0; i < header->fields_count; i++) {
2088 field = &header->fields[i];
2089 field_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_FIELD);
2090 if (!field_attr)
2091 return -EMSGSIZE;
2092 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
2093 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
2094 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
2095 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
2096 goto nla_put_failure;
2097 nla_nest_end(skb, field_attr);
2099 return 0;
2101 nla_put_failure:
2102 nla_nest_cancel(skb, field_attr);
2103 return -EMSGSIZE;
2106 static int devlink_dpipe_header_put(struct sk_buff *skb,
2107 struct devlink_dpipe_header *header)
2109 struct nlattr *fields_attr, *header_attr;
2110 int err;
2112 header_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER);
2113 if (!header_attr)
2114 return -EMSGSIZE;
2116 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
2117 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
2118 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
2119 goto nla_put_failure;
2121 fields_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
2122 if (!fields_attr)
2123 goto nla_put_failure;
2125 err = devlink_dpipe_fields_put(skb, header);
2126 if (err) {
2127 nla_nest_cancel(skb, fields_attr);
2128 goto nla_put_failure;
2130 nla_nest_end(skb, fields_attr);
2131 nla_nest_end(skb, header_attr);
2132 return 0;
2134 nla_put_failure:
2135 err = -EMSGSIZE;
2136 nla_nest_cancel(skb, header_attr);
2137 return err;
2140 static int devlink_dpipe_headers_fill(struct genl_info *info,
2141 enum devlink_command cmd, int flags,
2142 struct devlink_dpipe_headers *
2143 dpipe_headers)
2145 struct devlink *devlink = info->user_ptr[0];
2146 struct nlattr *headers_attr;
2147 struct sk_buff *skb = NULL;
2148 struct nlmsghdr *nlh;
2149 void *hdr;
2150 int i, j;
2151 int err;
2153 i = 0;
2154 start_again:
2155 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2156 if (err)
2157 return err;
2159 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2160 &devlink_nl_family, NLM_F_MULTI, cmd);
2161 if (!hdr) {
2162 nlmsg_free(skb);
2163 return -EMSGSIZE;
2166 if (devlink_nl_put_handle(skb, devlink))
2167 goto nla_put_failure;
2168 headers_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADERS);
2169 if (!headers_attr)
2170 goto nla_put_failure;
2172 j = 0;
2173 for (; i < dpipe_headers->headers_count; i++) {
2174 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
2175 if (err) {
2176 if (!j)
2177 goto err_table_put;
2178 break;
2180 j++;
2182 nla_nest_end(skb, headers_attr);
2183 genlmsg_end(skb, hdr);
2184 if (i != dpipe_headers->headers_count)
2185 goto start_again;
2187 send_done:
2188 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2189 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2190 if (!nlh) {
2191 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2192 if (err)
2193 goto err_skb_send_alloc;
2194 goto send_done;
2196 return genlmsg_reply(skb, info);
2198 nla_put_failure:
2199 err = -EMSGSIZE;
2200 err_table_put:
2201 err_skb_send_alloc:
2202 genlmsg_cancel(skb, hdr);
2203 nlmsg_free(skb);
2204 return err;
2207 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
2208 struct genl_info *info)
2210 struct devlink *devlink = info->user_ptr[0];
2212 if (!devlink->dpipe_headers)
2213 return -EOPNOTSUPP;
2214 return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
2215 0, devlink->dpipe_headers);
2218 static int devlink_dpipe_table_counters_set(struct devlink *devlink,
2219 const char *table_name,
2220 bool enable)
2222 struct devlink_dpipe_table *table;
2224 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2225 table_name);
2226 if (!table)
2227 return -EINVAL;
2229 if (table->counter_control_extern)
2230 return -EOPNOTSUPP;
2232 if (!(table->counters_enabled ^ enable))
2233 return 0;
2235 table->counters_enabled = enable;
2236 if (table->table_ops->counters_set_update)
2237 table->table_ops->counters_set_update(table->priv, enable);
2238 return 0;
2241 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
2242 struct genl_info *info)
2244 struct devlink *devlink = info->user_ptr[0];
2245 const char *table_name;
2246 bool counters_enable;
2248 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] ||
2249 !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED])
2250 return -EINVAL;
2252 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2253 counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
2255 return devlink_dpipe_table_counters_set(devlink, table_name,
2256 counters_enable);
2259 static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
2260 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
2261 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
2262 [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
2263 [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
2264 [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
2265 [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
2266 [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
2267 [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
2268 [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
2269 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
2270 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
2271 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
2272 [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
2273 [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
2274 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
2275 [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
2276 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
2279 static const struct genl_ops devlink_nl_ops[] = {
2281 .cmd = DEVLINK_CMD_GET,
2282 .doit = devlink_nl_cmd_get_doit,
2283 .dumpit = devlink_nl_cmd_get_dumpit,
2284 .policy = devlink_nl_policy,
2285 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2286 /* can be retrieved by unprivileged users */
2289 .cmd = DEVLINK_CMD_PORT_GET,
2290 .doit = devlink_nl_cmd_port_get_doit,
2291 .dumpit = devlink_nl_cmd_port_get_dumpit,
2292 .policy = devlink_nl_policy,
2293 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
2294 /* can be retrieved by unprivileged users */
2297 .cmd = DEVLINK_CMD_PORT_SET,
2298 .doit = devlink_nl_cmd_port_set_doit,
2299 .policy = devlink_nl_policy,
2300 .flags = GENL_ADMIN_PERM,
2301 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
2304 .cmd = DEVLINK_CMD_PORT_SPLIT,
2305 .doit = devlink_nl_cmd_port_split_doit,
2306 .policy = devlink_nl_policy,
2307 .flags = GENL_ADMIN_PERM,
2308 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2311 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
2312 .doit = devlink_nl_cmd_port_unsplit_doit,
2313 .policy = devlink_nl_policy,
2314 .flags = GENL_ADMIN_PERM,
2315 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2318 .cmd = DEVLINK_CMD_SB_GET,
2319 .doit = devlink_nl_cmd_sb_get_doit,
2320 .dumpit = devlink_nl_cmd_sb_get_dumpit,
2321 .policy = devlink_nl_policy,
2322 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2323 DEVLINK_NL_FLAG_NEED_SB,
2324 /* can be retrieved by unprivileged users */
2327 .cmd = DEVLINK_CMD_SB_POOL_GET,
2328 .doit = devlink_nl_cmd_sb_pool_get_doit,
2329 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
2330 .policy = devlink_nl_policy,
2331 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2332 DEVLINK_NL_FLAG_NEED_SB,
2333 /* can be retrieved by unprivileged users */
2336 .cmd = DEVLINK_CMD_SB_POOL_SET,
2337 .doit = devlink_nl_cmd_sb_pool_set_doit,
2338 .policy = devlink_nl_policy,
2339 .flags = GENL_ADMIN_PERM,
2340 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2341 DEVLINK_NL_FLAG_NEED_SB,
2344 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
2345 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
2346 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
2347 .policy = devlink_nl_policy,
2348 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2349 DEVLINK_NL_FLAG_NEED_SB,
2350 /* can be retrieved by unprivileged users */
2353 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
2354 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
2355 .policy = devlink_nl_policy,
2356 .flags = GENL_ADMIN_PERM,
2357 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2358 DEVLINK_NL_FLAG_NEED_SB,
2361 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
2362 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
2363 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
2364 .policy = devlink_nl_policy,
2365 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2366 DEVLINK_NL_FLAG_NEED_SB,
2367 /* can be retrieved by unprivileged users */
2370 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
2371 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
2372 .policy = devlink_nl_policy,
2373 .flags = GENL_ADMIN_PERM,
2374 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2375 DEVLINK_NL_FLAG_NEED_SB,
2378 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
2379 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
2380 .policy = devlink_nl_policy,
2381 .flags = GENL_ADMIN_PERM,
2382 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2383 DEVLINK_NL_FLAG_NEED_SB |
2384 DEVLINK_NL_FLAG_LOCK_PORTS,
2387 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
2388 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
2389 .policy = devlink_nl_policy,
2390 .flags = GENL_ADMIN_PERM,
2391 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2392 DEVLINK_NL_FLAG_NEED_SB |
2393 DEVLINK_NL_FLAG_LOCK_PORTS,
2396 .cmd = DEVLINK_CMD_ESWITCH_GET,
2397 .doit = devlink_nl_cmd_eswitch_get_doit,
2398 .policy = devlink_nl_policy,
2399 .flags = GENL_ADMIN_PERM,
2400 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2403 .cmd = DEVLINK_CMD_ESWITCH_SET,
2404 .doit = devlink_nl_cmd_eswitch_set_doit,
2405 .policy = devlink_nl_policy,
2406 .flags = GENL_ADMIN_PERM,
2407 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2410 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
2411 .doit = devlink_nl_cmd_dpipe_table_get,
2412 .policy = devlink_nl_policy,
2413 .flags = GENL_ADMIN_PERM,
2414 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2417 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
2418 .doit = devlink_nl_cmd_dpipe_entries_get,
2419 .policy = devlink_nl_policy,
2420 .flags = GENL_ADMIN_PERM,
2421 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2424 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
2425 .doit = devlink_nl_cmd_dpipe_headers_get,
2426 .policy = devlink_nl_policy,
2427 .flags = GENL_ADMIN_PERM,
2428 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2431 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
2432 .doit = devlink_nl_cmd_dpipe_table_counters_set,
2433 .policy = devlink_nl_policy,
2434 .flags = GENL_ADMIN_PERM,
2435 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2439 static struct genl_family devlink_nl_family __ro_after_init = {
2440 .name = DEVLINK_GENL_NAME,
2441 .version = DEVLINK_GENL_VERSION,
2442 .maxattr = DEVLINK_ATTR_MAX,
2443 .netnsok = true,
2444 .pre_doit = devlink_nl_pre_doit,
2445 .post_doit = devlink_nl_post_doit,
2446 .module = THIS_MODULE,
2447 .ops = devlink_nl_ops,
2448 .n_ops = ARRAY_SIZE(devlink_nl_ops),
2449 .mcgrps = devlink_nl_mcgrps,
2450 .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps),
2454 * devlink_alloc - Allocate new devlink instance resources
2456 * @ops: ops
2457 * @priv_size: size of user private data
2459 * Allocate new devlink instance resources, including devlink index
2460 * and name.
2462 struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
2464 struct devlink *devlink;
2466 devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
2467 if (!devlink)
2468 return NULL;
2469 devlink->ops = ops;
2470 devlink_net_set(devlink, &init_net);
2471 INIT_LIST_HEAD(&devlink->port_list);
2472 INIT_LIST_HEAD(&devlink->sb_list);
2473 INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
2474 return devlink;
2476 EXPORT_SYMBOL_GPL(devlink_alloc);
2479 * devlink_register - Register devlink instance
2481 * @devlink: devlink
2483 int devlink_register(struct devlink *devlink, struct device *dev)
2485 mutex_lock(&devlink_mutex);
2486 devlink->dev = dev;
2487 list_add_tail(&devlink->list, &devlink_list);
2488 devlink_notify(devlink, DEVLINK_CMD_NEW);
2489 mutex_unlock(&devlink_mutex);
2490 return 0;
2492 EXPORT_SYMBOL_GPL(devlink_register);
2495 * devlink_unregister - Unregister devlink instance
2497 * @devlink: devlink
2499 void devlink_unregister(struct devlink *devlink)
2501 mutex_lock(&devlink_mutex);
2502 devlink_notify(devlink, DEVLINK_CMD_DEL);
2503 list_del(&devlink->list);
2504 mutex_unlock(&devlink_mutex);
2506 EXPORT_SYMBOL_GPL(devlink_unregister);
2509 * devlink_free - Free devlink instance resources
2511 * @devlink: devlink
2513 void devlink_free(struct devlink *devlink)
2515 kfree(devlink);
2517 EXPORT_SYMBOL_GPL(devlink_free);
2520 * devlink_port_register - Register devlink port
2522 * @devlink: devlink
2523 * @devlink_port: devlink port
2524 * @port_index
2526 * Register devlink port with provided port index. User can use
2527 * any indexing, even hw-related one. devlink_port structure
2528 * is convenient to be embedded inside user driver private structure.
2529 * Note that the caller should take care of zeroing the devlink_port
2530 * structure.
2532 int devlink_port_register(struct devlink *devlink,
2533 struct devlink_port *devlink_port,
2534 unsigned int port_index)
2536 mutex_lock(&devlink_port_mutex);
2537 if (devlink_port_index_exists(devlink, port_index)) {
2538 mutex_unlock(&devlink_port_mutex);
2539 return -EEXIST;
2541 devlink_port->devlink = devlink;
2542 devlink_port->index = port_index;
2543 devlink_port->registered = true;
2544 list_add_tail(&devlink_port->list, &devlink->port_list);
2545 mutex_unlock(&devlink_port_mutex);
2546 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
2547 return 0;
2549 EXPORT_SYMBOL_GPL(devlink_port_register);
2552 * devlink_port_unregister - Unregister devlink port
2554 * @devlink_port: devlink port
2556 void devlink_port_unregister(struct devlink_port *devlink_port)
2558 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
2559 mutex_lock(&devlink_port_mutex);
2560 list_del(&devlink_port->list);
2561 mutex_unlock(&devlink_port_mutex);
2563 EXPORT_SYMBOL_GPL(devlink_port_unregister);
2565 static void __devlink_port_type_set(struct devlink_port *devlink_port,
2566 enum devlink_port_type type,
2567 void *type_dev)
2569 devlink_port->type = type;
2570 devlink_port->type_dev = type_dev;
2571 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
2575 * devlink_port_type_eth_set - Set port type to Ethernet
2577 * @devlink_port: devlink port
2578 * @netdev: related netdevice
2580 void devlink_port_type_eth_set(struct devlink_port *devlink_port,
2581 struct net_device *netdev)
2583 return __devlink_port_type_set(devlink_port,
2584 DEVLINK_PORT_TYPE_ETH, netdev);
2586 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
2589 * devlink_port_type_ib_set - Set port type to InfiniBand
2591 * @devlink_port: devlink port
2592 * @ibdev: related IB device
2594 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
2595 struct ib_device *ibdev)
2597 return __devlink_port_type_set(devlink_port,
2598 DEVLINK_PORT_TYPE_IB, ibdev);
2600 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
2603 * devlink_port_type_clear - Clear port type
2605 * @devlink_port: devlink port
2607 void devlink_port_type_clear(struct devlink_port *devlink_port)
2609 return __devlink_port_type_set(devlink_port,
2610 DEVLINK_PORT_TYPE_NOTSET, NULL);
2612 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
2615 * devlink_port_split_set - Set port is split
2617 * @devlink_port: devlink port
2618 * @split_group: split group - identifies group split port is part of
2620 void devlink_port_split_set(struct devlink_port *devlink_port,
2621 u32 split_group)
2623 devlink_port->split = true;
2624 devlink_port->split_group = split_group;
2625 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
2627 EXPORT_SYMBOL_GPL(devlink_port_split_set);
2629 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
2630 u32 size, u16 ingress_pools_count,
2631 u16 egress_pools_count, u16 ingress_tc_count,
2632 u16 egress_tc_count)
2634 struct devlink_sb *devlink_sb;
2635 int err = 0;
2637 mutex_lock(&devlink_mutex);
2638 if (devlink_sb_index_exists(devlink, sb_index)) {
2639 err = -EEXIST;
2640 goto unlock;
2643 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
2644 if (!devlink_sb) {
2645 err = -ENOMEM;
2646 goto unlock;
2648 devlink_sb->index = sb_index;
2649 devlink_sb->size = size;
2650 devlink_sb->ingress_pools_count = ingress_pools_count;
2651 devlink_sb->egress_pools_count = egress_pools_count;
2652 devlink_sb->ingress_tc_count = ingress_tc_count;
2653 devlink_sb->egress_tc_count = egress_tc_count;
2654 list_add_tail(&devlink_sb->list, &devlink->sb_list);
2655 unlock:
2656 mutex_unlock(&devlink_mutex);
2657 return err;
2659 EXPORT_SYMBOL_GPL(devlink_sb_register);
2661 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
2663 struct devlink_sb *devlink_sb;
2665 mutex_lock(&devlink_mutex);
2666 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
2667 WARN_ON(!devlink_sb);
2668 list_del(&devlink_sb->list);
2669 mutex_unlock(&devlink_mutex);
2670 kfree(devlink_sb);
2672 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
2675 * devlink_dpipe_headers_register - register dpipe headers
2677 * @devlink: devlink
2678 * @dpipe_headers: dpipe header array
2680 * Register the headers supported by hardware.
2682 int devlink_dpipe_headers_register(struct devlink *devlink,
2683 struct devlink_dpipe_headers *dpipe_headers)
2685 mutex_lock(&devlink_mutex);
2686 devlink->dpipe_headers = dpipe_headers;
2687 mutex_unlock(&devlink_mutex);
2688 return 0;
2690 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register);
2693 * devlink_dpipe_headers_unregister - unregister dpipe headers
2695 * @devlink: devlink
2697 * Unregister the headers supported by hardware.
2699 void devlink_dpipe_headers_unregister(struct devlink *devlink)
2701 mutex_lock(&devlink_mutex);
2702 devlink->dpipe_headers = NULL;
2703 mutex_unlock(&devlink_mutex);
2705 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister);
2708 * devlink_dpipe_table_counter_enabled - check if counter allocation
2709 * required
2710 * @devlink: devlink
2711 * @table_name: tables name
2713 * Used by driver to check if counter allocation is required.
2714 * After counter allocation is turned on the table entries
2715 * are updated to include counter statistics.
2717 * After that point on the driver must respect the counter
2718 * state so that each entry added to the table is added
2719 * with a counter.
2721 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
2722 const char *table_name)
2724 struct devlink_dpipe_table *table;
2725 bool enabled;
2727 rcu_read_lock();
2728 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2729 table_name);
2730 enabled = false;
2731 if (table)
2732 enabled = table->counters_enabled;
2733 rcu_read_unlock();
2734 return enabled;
2736 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
2739 * devlink_dpipe_table_register - register dpipe table
2741 * @devlink: devlink
2742 * @table_name: table name
2743 * @table_ops: table ops
2744 * @priv: priv
2745 * @counter_control_extern: external control for counters
2747 int devlink_dpipe_table_register(struct devlink *devlink,
2748 const char *table_name,
2749 struct devlink_dpipe_table_ops *table_ops,
2750 void *priv, bool counter_control_extern)
2752 struct devlink_dpipe_table *table;
2754 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name))
2755 return -EEXIST;
2757 if (WARN_ON(!table_ops->size_get))
2758 return -EINVAL;
2760 table = kzalloc(sizeof(*table), GFP_KERNEL);
2761 if (!table)
2762 return -ENOMEM;
2764 table->name = table_name;
2765 table->table_ops = table_ops;
2766 table->priv = priv;
2767 table->counter_control_extern = counter_control_extern;
2769 mutex_lock(&devlink_mutex);
2770 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
2771 mutex_unlock(&devlink_mutex);
2772 return 0;
2774 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register);
2777 * devlink_dpipe_table_unregister - unregister dpipe table
2779 * @devlink: devlink
2780 * @table_name: table name
2782 void devlink_dpipe_table_unregister(struct devlink *devlink,
2783 const char *table_name)
2785 struct devlink_dpipe_table *table;
2787 mutex_lock(&devlink_mutex);
2788 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2789 table_name);
2790 if (!table)
2791 goto unlock;
2792 list_del_rcu(&table->list);
2793 mutex_unlock(&devlink_mutex);
2794 kfree_rcu(table, rcu);
2795 return;
2796 unlock:
2797 mutex_unlock(&devlink_mutex);
2799 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
2801 static int __init devlink_module_init(void)
2803 return genl_register_family(&devlink_nl_family);
2806 static void __exit devlink_module_exit(void)
2808 genl_unregister_family(&devlink_nl_family);
2811 module_init(devlink_module_init);
2812 module_exit(devlink_module_exit);
2814 MODULE_LICENSE("GPL v2");
2815 MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
2816 MODULE_DESCRIPTION("Network physical device Netlink interface");
2817 MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);