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>
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
,
40 struct devlink_dpipe_header devlink_dpipe_header_ethernet
= {
42 .id
= DEVLINK_DPIPE_HEADER_ETHERNET
,
43 .fields
= devlink_dpipe_fields_ethernet
,
44 .fields_count
= ARRAY_SIZE(devlink_dpipe_fields_ethernet
),
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
,
57 struct devlink_dpipe_header devlink_dpipe_header_ipv4
= {
59 .id
= DEVLINK_DPIPE_HEADER_IPV4
,
60 .fields
= devlink_dpipe_fields_ipv4
,
61 .fields_count
= ARRAY_SIZE(devlink_dpipe_fields_ipv4
),
64 EXPORT_SYMBOL(devlink_dpipe_header_ipv4
);
66 static struct devlink_dpipe_field devlink_dpipe_fields_ipv6
[] = {
68 .name
= "destination ip",
69 .id
= DEVLINK_DPIPE_FIELD_IPV6_DST_IP
,
74 struct devlink_dpipe_header devlink_dpipe_header_ipv6
= {
76 .id
= DEVLINK_DPIPE_HEADER_IPV6
,
77 .fields
= devlink_dpipe_fields_ipv6
,
78 .fields_count
= ARRAY_SIZE(devlink_dpipe_fields_ipv6
),
81 EXPORT_SYMBOL(devlink_dpipe_header_ipv6
);
83 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg
);
85 static LIST_HEAD(devlink_list
);
89 * An overall lock guarding every operation coming from userspace.
90 * It also guards devlink devices list and it is taken when
91 * driver registers/unregisters it.
93 static DEFINE_MUTEX(devlink_mutex
);
95 static struct net
*devlink_net(const struct devlink
*devlink
)
97 return read_pnet(&devlink
->_net
);
100 static void devlink_net_set(struct devlink
*devlink
, struct net
*net
)
102 write_pnet(&devlink
->_net
, net
);
105 static struct devlink
*devlink_get_from_attrs(struct net
*net
,
106 struct nlattr
**attrs
)
108 struct devlink
*devlink
;
112 if (!attrs
[DEVLINK_ATTR_BUS_NAME
] || !attrs
[DEVLINK_ATTR_DEV_NAME
])
113 return ERR_PTR(-EINVAL
);
115 busname
= nla_data(attrs
[DEVLINK_ATTR_BUS_NAME
]);
116 devname
= nla_data(attrs
[DEVLINK_ATTR_DEV_NAME
]);
118 list_for_each_entry(devlink
, &devlink_list
, list
) {
119 if (strcmp(devlink
->dev
->bus
->name
, busname
) == 0 &&
120 strcmp(dev_name(devlink
->dev
), devname
) == 0 &&
121 net_eq(devlink_net(devlink
), net
))
125 return ERR_PTR(-ENODEV
);
128 static struct devlink
*devlink_get_from_info(struct genl_info
*info
)
130 return devlink_get_from_attrs(genl_info_net(info
), info
->attrs
);
133 static struct devlink_port
*devlink_port_get_by_index(struct devlink
*devlink
,
136 struct devlink_port
*devlink_port
;
138 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
139 if (devlink_port
->index
== port_index
)
145 static bool devlink_port_index_exists(struct devlink
*devlink
, int port_index
)
147 return devlink_port_get_by_index(devlink
, port_index
);
150 static struct devlink_port
*devlink_port_get_from_attrs(struct devlink
*devlink
,
151 struct nlattr
**attrs
)
153 if (attrs
[DEVLINK_ATTR_PORT_INDEX
]) {
154 u32 port_index
= nla_get_u32(attrs
[DEVLINK_ATTR_PORT_INDEX
]);
155 struct devlink_port
*devlink_port
;
157 devlink_port
= devlink_port_get_by_index(devlink
, port_index
);
159 return ERR_PTR(-ENODEV
);
162 return ERR_PTR(-EINVAL
);
165 static struct devlink_port
*devlink_port_get_from_info(struct devlink
*devlink
,
166 struct genl_info
*info
)
168 return devlink_port_get_from_attrs(devlink
, info
->attrs
);
172 struct list_head list
;
175 u16 ingress_pools_count
;
176 u16 egress_pools_count
;
177 u16 ingress_tc_count
;
181 static u16
devlink_sb_pool_count(struct devlink_sb
*devlink_sb
)
183 return devlink_sb
->ingress_pools_count
+ devlink_sb
->egress_pools_count
;
186 static struct devlink_sb
*devlink_sb_get_by_index(struct devlink
*devlink
,
187 unsigned int sb_index
)
189 struct devlink_sb
*devlink_sb
;
191 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
192 if (devlink_sb
->index
== sb_index
)
198 static bool devlink_sb_index_exists(struct devlink
*devlink
,
199 unsigned int sb_index
)
201 return devlink_sb_get_by_index(devlink
, sb_index
);
204 static struct devlink_sb
*devlink_sb_get_from_attrs(struct devlink
*devlink
,
205 struct nlattr
**attrs
)
207 if (attrs
[DEVLINK_ATTR_SB_INDEX
]) {
208 u32 sb_index
= nla_get_u32(attrs
[DEVLINK_ATTR_SB_INDEX
]);
209 struct devlink_sb
*devlink_sb
;
211 devlink_sb
= devlink_sb_get_by_index(devlink
, sb_index
);
213 return ERR_PTR(-ENODEV
);
216 return ERR_PTR(-EINVAL
);
219 static struct devlink_sb
*devlink_sb_get_from_info(struct devlink
*devlink
,
220 struct genl_info
*info
)
222 return devlink_sb_get_from_attrs(devlink
, info
->attrs
);
225 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb
*devlink_sb
,
226 struct nlattr
**attrs
,
231 if (!attrs
[DEVLINK_ATTR_SB_POOL_INDEX
])
234 val
= nla_get_u16(attrs
[DEVLINK_ATTR_SB_POOL_INDEX
]);
235 if (val
>= devlink_sb_pool_count(devlink_sb
))
241 static int devlink_sb_pool_index_get_from_info(struct devlink_sb
*devlink_sb
,
242 struct genl_info
*info
,
245 return devlink_sb_pool_index_get_from_attrs(devlink_sb
, info
->attrs
,
250 devlink_sb_pool_type_get_from_attrs(struct nlattr
**attrs
,
251 enum devlink_sb_pool_type
*p_pool_type
)
255 if (!attrs
[DEVLINK_ATTR_SB_POOL_TYPE
])
258 val
= nla_get_u8(attrs
[DEVLINK_ATTR_SB_POOL_TYPE
]);
259 if (val
!= DEVLINK_SB_POOL_TYPE_INGRESS
&&
260 val
!= DEVLINK_SB_POOL_TYPE_EGRESS
)
267 devlink_sb_pool_type_get_from_info(struct genl_info
*info
,
268 enum devlink_sb_pool_type
*p_pool_type
)
270 return devlink_sb_pool_type_get_from_attrs(info
->attrs
, p_pool_type
);
274 devlink_sb_th_type_get_from_attrs(struct nlattr
**attrs
,
275 enum devlink_sb_threshold_type
*p_th_type
)
279 if (!attrs
[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
])
282 val
= nla_get_u8(attrs
[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
]);
283 if (val
!= DEVLINK_SB_THRESHOLD_TYPE_STATIC
&&
284 val
!= DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC
)
291 devlink_sb_th_type_get_from_info(struct genl_info
*info
,
292 enum devlink_sb_threshold_type
*p_th_type
)
294 return devlink_sb_th_type_get_from_attrs(info
->attrs
, p_th_type
);
298 devlink_sb_tc_index_get_from_attrs(struct devlink_sb
*devlink_sb
,
299 struct nlattr
**attrs
,
300 enum devlink_sb_pool_type pool_type
,
305 if (!attrs
[DEVLINK_ATTR_SB_TC_INDEX
])
308 val
= nla_get_u16(attrs
[DEVLINK_ATTR_SB_TC_INDEX
]);
309 if (pool_type
== DEVLINK_SB_POOL_TYPE_INGRESS
&&
310 val
>= devlink_sb
->ingress_tc_count
)
312 if (pool_type
== DEVLINK_SB_POOL_TYPE_EGRESS
&&
313 val
>= devlink_sb
->egress_tc_count
)
320 devlink_sb_tc_index_get_from_info(struct devlink_sb
*devlink_sb
,
321 struct genl_info
*info
,
322 enum devlink_sb_pool_type pool_type
,
325 return devlink_sb_tc_index_get_from_attrs(devlink_sb
, info
->attrs
,
326 pool_type
, p_tc_index
);
329 #define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0)
330 #define DEVLINK_NL_FLAG_NEED_PORT BIT(1)
331 #define DEVLINK_NL_FLAG_NEED_SB BIT(2)
333 /* The per devlink instance lock is taken by default in the pre-doit
334 * operation, yet several commands do not require this. The global
335 * devlink lock is taken and protects from disruption by user-calls.
337 #define DEVLINK_NL_FLAG_NO_LOCK BIT(3)
339 static int devlink_nl_pre_doit(const struct genl_ops
*ops
,
340 struct sk_buff
*skb
, struct genl_info
*info
)
342 struct devlink
*devlink
;
345 mutex_lock(&devlink_mutex
);
346 devlink
= devlink_get_from_info(info
);
347 if (IS_ERR(devlink
)) {
348 mutex_unlock(&devlink_mutex
);
349 return PTR_ERR(devlink
);
351 if (~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
352 mutex_lock(&devlink
->lock
);
353 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_DEVLINK
) {
354 info
->user_ptr
[0] = devlink
;
355 } else if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_PORT
) {
356 struct devlink_port
*devlink_port
;
358 devlink_port
= devlink_port_get_from_info(devlink
, info
);
359 if (IS_ERR(devlink_port
)) {
360 err
= PTR_ERR(devlink_port
);
363 info
->user_ptr
[0] = devlink_port
;
365 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_SB
) {
366 struct devlink_sb
*devlink_sb
;
368 devlink_sb
= devlink_sb_get_from_info(devlink
, info
);
369 if (IS_ERR(devlink_sb
)) {
370 err
= PTR_ERR(devlink_sb
);
373 info
->user_ptr
[1] = devlink_sb
;
378 if (~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
379 mutex_unlock(&devlink
->lock
);
380 mutex_unlock(&devlink_mutex
);
384 static void devlink_nl_post_doit(const struct genl_ops
*ops
,
385 struct sk_buff
*skb
, struct genl_info
*info
)
387 struct devlink
*devlink
;
389 devlink
= devlink_get_from_info(info
);
390 if (~ops
->internal_flags
& DEVLINK_NL_FLAG_NO_LOCK
)
391 mutex_unlock(&devlink
->lock
);
392 mutex_unlock(&devlink_mutex
);
395 static struct genl_family devlink_nl_family
;
397 enum devlink_multicast_groups
{
398 DEVLINK_MCGRP_CONFIG
,
401 static const struct genl_multicast_group devlink_nl_mcgrps
[] = {
402 [DEVLINK_MCGRP_CONFIG
] = { .name
= DEVLINK_GENL_MCGRP_CONFIG_NAME
},
405 static int devlink_nl_put_handle(struct sk_buff
*msg
, struct devlink
*devlink
)
407 if (nla_put_string(msg
, DEVLINK_ATTR_BUS_NAME
, devlink
->dev
->bus
->name
))
409 if (nla_put_string(msg
, DEVLINK_ATTR_DEV_NAME
, dev_name(devlink
->dev
)))
414 static int devlink_nl_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
415 enum devlink_command cmd
, u32 portid
,
420 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
424 if (devlink_nl_put_handle(msg
, devlink
))
425 goto nla_put_failure
;
427 genlmsg_end(msg
, hdr
);
431 genlmsg_cancel(msg
, hdr
);
435 static void devlink_notify(struct devlink
*devlink
, enum devlink_command cmd
)
440 WARN_ON(cmd
!= DEVLINK_CMD_NEW
&& cmd
!= DEVLINK_CMD_DEL
);
442 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
446 err
= devlink_nl_fill(msg
, devlink
, cmd
, 0, 0, 0);
452 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
453 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
456 static int devlink_nl_port_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
457 struct devlink_port
*devlink_port
,
458 enum devlink_command cmd
, u32 portid
,
463 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
467 if (devlink_nl_put_handle(msg
, devlink
))
468 goto nla_put_failure
;
469 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
470 goto nla_put_failure
;
471 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_TYPE
, devlink_port
->type
))
472 goto nla_put_failure
;
473 if (devlink_port
->desired_type
!= DEVLINK_PORT_TYPE_NOTSET
&&
474 nla_put_u16(msg
, DEVLINK_ATTR_PORT_DESIRED_TYPE
,
475 devlink_port
->desired_type
))
476 goto nla_put_failure
;
477 if (devlink_port
->type
== DEVLINK_PORT_TYPE_ETH
) {
478 struct net_device
*netdev
= devlink_port
->type_dev
;
481 (nla_put_u32(msg
, DEVLINK_ATTR_PORT_NETDEV_IFINDEX
,
483 nla_put_string(msg
, DEVLINK_ATTR_PORT_NETDEV_NAME
,
485 goto nla_put_failure
;
487 if (devlink_port
->type
== DEVLINK_PORT_TYPE_IB
) {
488 struct ib_device
*ibdev
= devlink_port
->type_dev
;
491 nla_put_string(msg
, DEVLINK_ATTR_PORT_IBDEV_NAME
,
493 goto nla_put_failure
;
495 if (devlink_port
->split
&&
496 nla_put_u32(msg
, DEVLINK_ATTR_PORT_SPLIT_GROUP
,
497 devlink_port
->split_group
))
498 goto nla_put_failure
;
500 genlmsg_end(msg
, hdr
);
504 genlmsg_cancel(msg
, hdr
);
508 static void devlink_port_notify(struct devlink_port
*devlink_port
,
509 enum devlink_command cmd
)
511 struct devlink
*devlink
= devlink_port
->devlink
;
515 if (!devlink_port
->registered
)
518 WARN_ON(cmd
!= DEVLINK_CMD_PORT_NEW
&& cmd
!= DEVLINK_CMD_PORT_DEL
);
520 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
524 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
, cmd
, 0, 0, 0);
530 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
531 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
534 static int devlink_nl_cmd_get_doit(struct sk_buff
*skb
, struct genl_info
*info
)
536 struct devlink
*devlink
= info
->user_ptr
[0];
540 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
544 err
= devlink_nl_fill(msg
, devlink
, DEVLINK_CMD_NEW
,
545 info
->snd_portid
, info
->snd_seq
, 0);
551 return genlmsg_reply(msg
, info
);
554 static int devlink_nl_cmd_get_dumpit(struct sk_buff
*msg
,
555 struct netlink_callback
*cb
)
557 struct devlink
*devlink
;
558 int start
= cb
->args
[0];
562 mutex_lock(&devlink_mutex
);
563 list_for_each_entry(devlink
, &devlink_list
, list
) {
564 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
570 err
= devlink_nl_fill(msg
, devlink
, DEVLINK_CMD_NEW
,
571 NETLINK_CB(cb
->skb
).portid
,
572 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
);
578 mutex_unlock(&devlink_mutex
);
584 static int devlink_nl_cmd_port_get_doit(struct sk_buff
*skb
,
585 struct genl_info
*info
)
587 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
588 struct devlink
*devlink
= devlink_port
->devlink
;
592 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
596 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
,
597 DEVLINK_CMD_PORT_NEW
,
598 info
->snd_portid
, info
->snd_seq
, 0);
604 return genlmsg_reply(msg
, info
);
607 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff
*msg
,
608 struct netlink_callback
*cb
)
610 struct devlink
*devlink
;
611 struct devlink_port
*devlink_port
;
612 int start
= cb
->args
[0];
616 mutex_lock(&devlink_mutex
);
617 list_for_each_entry(devlink
, &devlink_list
, list
) {
618 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
620 mutex_lock(&devlink
->lock
);
621 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
626 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
,
628 NETLINK_CB(cb
->skb
).portid
,
632 mutex_unlock(&devlink
->lock
);
637 mutex_unlock(&devlink
->lock
);
640 mutex_unlock(&devlink_mutex
);
646 static int devlink_port_type_set(struct devlink
*devlink
,
647 struct devlink_port
*devlink_port
,
648 enum devlink_port_type port_type
)
653 if (devlink
->ops
&& devlink
->ops
->port_type_set
) {
654 if (port_type
== DEVLINK_PORT_TYPE_NOTSET
)
656 if (port_type
== devlink_port
->type
)
658 err
= devlink
->ops
->port_type_set(devlink_port
, port_type
);
661 devlink_port
->desired_type
= port_type
;
662 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
668 static int devlink_nl_cmd_port_set_doit(struct sk_buff
*skb
,
669 struct genl_info
*info
)
671 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
672 struct devlink
*devlink
= devlink_port
->devlink
;
675 if (info
->attrs
[DEVLINK_ATTR_PORT_TYPE
]) {
676 enum devlink_port_type port_type
;
678 port_type
= nla_get_u16(info
->attrs
[DEVLINK_ATTR_PORT_TYPE
]);
679 err
= devlink_port_type_set(devlink
, devlink_port
, port_type
);
686 static int devlink_port_split(struct devlink
*devlink
,
687 u32 port_index
, u32 count
)
690 if (devlink
->ops
&& devlink
->ops
->port_split
)
691 return devlink
->ops
->port_split(devlink
, port_index
, count
);
695 static int devlink_nl_cmd_port_split_doit(struct sk_buff
*skb
,
696 struct genl_info
*info
)
698 struct devlink
*devlink
= info
->user_ptr
[0];
702 if (!info
->attrs
[DEVLINK_ATTR_PORT_INDEX
] ||
703 !info
->attrs
[DEVLINK_ATTR_PORT_SPLIT_COUNT
])
706 port_index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
707 count
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_SPLIT_COUNT
]);
708 return devlink_port_split(devlink
, port_index
, count
);
711 static int devlink_port_unsplit(struct devlink
*devlink
, u32 port_index
)
714 if (devlink
->ops
&& devlink
->ops
->port_unsplit
)
715 return devlink
->ops
->port_unsplit(devlink
, port_index
);
719 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff
*skb
,
720 struct genl_info
*info
)
722 struct devlink
*devlink
= info
->user_ptr
[0];
725 if (!info
->attrs
[DEVLINK_ATTR_PORT_INDEX
])
728 port_index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
729 return devlink_port_unsplit(devlink
, port_index
);
732 static int devlink_nl_sb_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
733 struct devlink_sb
*devlink_sb
,
734 enum devlink_command cmd
, u32 portid
,
739 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
743 if (devlink_nl_put_handle(msg
, devlink
))
744 goto nla_put_failure
;
745 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
746 goto nla_put_failure
;
747 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_SIZE
, devlink_sb
->size
))
748 goto nla_put_failure
;
749 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT
,
750 devlink_sb
->ingress_pools_count
))
751 goto nla_put_failure
;
752 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT
,
753 devlink_sb
->egress_pools_count
))
754 goto nla_put_failure
;
755 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_INGRESS_TC_COUNT
,
756 devlink_sb
->ingress_tc_count
))
757 goto nla_put_failure
;
758 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_EGRESS_TC_COUNT
,
759 devlink_sb
->egress_tc_count
))
760 goto nla_put_failure
;
762 genlmsg_end(msg
, hdr
);
766 genlmsg_cancel(msg
, hdr
);
770 static int devlink_nl_cmd_sb_get_doit(struct sk_buff
*skb
,
771 struct genl_info
*info
)
773 struct devlink
*devlink
= info
->user_ptr
[0];
774 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
778 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
782 err
= devlink_nl_sb_fill(msg
, devlink
, devlink_sb
,
784 info
->snd_portid
, info
->snd_seq
, 0);
790 return genlmsg_reply(msg
, info
);
793 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff
*msg
,
794 struct netlink_callback
*cb
)
796 struct devlink
*devlink
;
797 struct devlink_sb
*devlink_sb
;
798 int start
= cb
->args
[0];
802 mutex_lock(&devlink_mutex
);
803 list_for_each_entry(devlink
, &devlink_list
, list
) {
804 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
806 mutex_lock(&devlink
->lock
);
807 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
812 err
= devlink_nl_sb_fill(msg
, devlink
, devlink_sb
,
814 NETLINK_CB(cb
->skb
).portid
,
818 mutex_unlock(&devlink
->lock
);
823 mutex_unlock(&devlink
->lock
);
826 mutex_unlock(&devlink_mutex
);
832 static int devlink_nl_sb_pool_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
833 struct devlink_sb
*devlink_sb
,
834 u16 pool_index
, enum devlink_command cmd
,
835 u32 portid
, u32 seq
, int flags
)
837 struct devlink_sb_pool_info pool_info
;
841 err
= devlink
->ops
->sb_pool_get(devlink
, devlink_sb
->index
,
842 pool_index
, &pool_info
);
846 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
850 if (devlink_nl_put_handle(msg
, devlink
))
851 goto nla_put_failure
;
852 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
853 goto nla_put_failure
;
854 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
855 goto nla_put_failure
;
856 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_TYPE
, pool_info
.pool_type
))
857 goto nla_put_failure
;
858 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_POOL_SIZE
, pool_info
.size
))
859 goto nla_put_failure
;
860 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
,
861 pool_info
.threshold_type
))
862 goto nla_put_failure
;
864 genlmsg_end(msg
, hdr
);
868 genlmsg_cancel(msg
, hdr
);
872 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff
*skb
,
873 struct genl_info
*info
)
875 struct devlink
*devlink
= info
->user_ptr
[0];
876 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
881 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
886 if (!devlink
->ops
|| !devlink
->ops
->sb_pool_get
)
889 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
893 err
= devlink_nl_sb_pool_fill(msg
, devlink
, devlink_sb
, pool_index
,
894 DEVLINK_CMD_SB_POOL_NEW
,
895 info
->snd_portid
, info
->snd_seq
, 0);
901 return genlmsg_reply(msg
, info
);
904 static int __sb_pool_get_dumpit(struct sk_buff
*msg
, int start
, int *p_idx
,
905 struct devlink
*devlink
,
906 struct devlink_sb
*devlink_sb
,
909 u16 pool_count
= devlink_sb_pool_count(devlink_sb
);
913 for (pool_index
= 0; pool_index
< pool_count
; pool_index
++) {
914 if (*p_idx
< start
) {
918 err
= devlink_nl_sb_pool_fill(msg
, devlink
,
921 DEVLINK_CMD_SB_POOL_NEW
,
922 portid
, seq
, NLM_F_MULTI
);
930 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff
*msg
,
931 struct netlink_callback
*cb
)
933 struct devlink
*devlink
;
934 struct devlink_sb
*devlink_sb
;
935 int start
= cb
->args
[0];
939 mutex_lock(&devlink_mutex
);
940 list_for_each_entry(devlink
, &devlink_list
, list
) {
941 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
942 !devlink
->ops
|| !devlink
->ops
->sb_pool_get
)
944 mutex_lock(&devlink
->lock
);
945 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
946 err
= __sb_pool_get_dumpit(msg
, start
, &idx
, devlink
,
948 NETLINK_CB(cb
->skb
).portid
,
950 if (err
&& err
!= -EOPNOTSUPP
) {
951 mutex_unlock(&devlink
->lock
);
955 mutex_unlock(&devlink
->lock
);
958 mutex_unlock(&devlink_mutex
);
964 static int devlink_sb_pool_set(struct devlink
*devlink
, unsigned int sb_index
,
965 u16 pool_index
, u32 size
,
966 enum devlink_sb_threshold_type threshold_type
)
969 const struct devlink_ops
*ops
= devlink
->ops
;
971 if (ops
&& ops
->sb_pool_set
)
972 return ops
->sb_pool_set(devlink
, sb_index
, pool_index
,
973 size
, threshold_type
);
977 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff
*skb
,
978 struct genl_info
*info
)
980 struct devlink
*devlink
= info
->user_ptr
[0];
981 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
982 enum devlink_sb_threshold_type threshold_type
;
987 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
992 err
= devlink_sb_th_type_get_from_info(info
, &threshold_type
);
996 if (!info
->attrs
[DEVLINK_ATTR_SB_POOL_SIZE
])
999 size
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_POOL_SIZE
]);
1000 return devlink_sb_pool_set(devlink
, devlink_sb
->index
,
1001 pool_index
, size
, threshold_type
);
1004 static int devlink_nl_sb_port_pool_fill(struct sk_buff
*msg
,
1005 struct devlink
*devlink
,
1006 struct devlink_port
*devlink_port
,
1007 struct devlink_sb
*devlink_sb
,
1009 enum devlink_command cmd
,
1010 u32 portid
, u32 seq
, int flags
)
1012 const struct devlink_ops
*ops
= devlink
->ops
;
1017 err
= ops
->sb_port_pool_get(devlink_port
, devlink_sb
->index
,
1018 pool_index
, &threshold
);
1022 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1026 if (devlink_nl_put_handle(msg
, devlink
))
1027 goto nla_put_failure
;
1028 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
1029 goto nla_put_failure
;
1030 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1031 goto nla_put_failure
;
1032 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1033 goto nla_put_failure
;
1034 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_THRESHOLD
, threshold
))
1035 goto nla_put_failure
;
1037 if (ops
->sb_occ_port_pool_get
) {
1041 err
= ops
->sb_occ_port_pool_get(devlink_port
, devlink_sb
->index
,
1042 pool_index
, &cur
, &max
);
1043 if (err
&& err
!= -EOPNOTSUPP
)
1046 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_CUR
, cur
))
1047 goto nla_put_failure
;
1048 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_MAX
, max
))
1049 goto nla_put_failure
;
1053 genlmsg_end(msg
, hdr
);
1057 genlmsg_cancel(msg
, hdr
);
1061 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff
*skb
,
1062 struct genl_info
*info
)
1064 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1065 struct devlink
*devlink
= devlink_port
->devlink
;
1066 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1067 struct sk_buff
*msg
;
1071 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1076 if (!devlink
->ops
|| !devlink
->ops
->sb_port_pool_get
)
1079 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1083 err
= devlink_nl_sb_port_pool_fill(msg
, devlink
, devlink_port
,
1084 devlink_sb
, pool_index
,
1085 DEVLINK_CMD_SB_PORT_POOL_NEW
,
1086 info
->snd_portid
, info
->snd_seq
, 0);
1092 return genlmsg_reply(msg
, info
);
1095 static int __sb_port_pool_get_dumpit(struct sk_buff
*msg
, int start
, int *p_idx
,
1096 struct devlink
*devlink
,
1097 struct devlink_sb
*devlink_sb
,
1098 u32 portid
, u32 seq
)
1100 struct devlink_port
*devlink_port
;
1101 u16 pool_count
= devlink_sb_pool_count(devlink_sb
);
1105 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
1106 for (pool_index
= 0; pool_index
< pool_count
; pool_index
++) {
1107 if (*p_idx
< start
) {
1111 err
= devlink_nl_sb_port_pool_fill(msg
, devlink
,
1115 DEVLINK_CMD_SB_PORT_POOL_NEW
,
1126 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff
*msg
,
1127 struct netlink_callback
*cb
)
1129 struct devlink
*devlink
;
1130 struct devlink_sb
*devlink_sb
;
1131 int start
= cb
->args
[0];
1135 mutex_lock(&devlink_mutex
);
1136 list_for_each_entry(devlink
, &devlink_list
, list
) {
1137 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1138 !devlink
->ops
|| !devlink
->ops
->sb_port_pool_get
)
1140 mutex_lock(&devlink
->lock
);
1141 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1142 err
= __sb_port_pool_get_dumpit(msg
, start
, &idx
,
1143 devlink
, devlink_sb
,
1144 NETLINK_CB(cb
->skb
).portid
,
1145 cb
->nlh
->nlmsg_seq
);
1146 if (err
&& err
!= -EOPNOTSUPP
) {
1147 mutex_unlock(&devlink
->lock
);
1151 mutex_unlock(&devlink
->lock
);
1154 mutex_unlock(&devlink_mutex
);
1160 static int devlink_sb_port_pool_set(struct devlink_port
*devlink_port
,
1161 unsigned int sb_index
, u16 pool_index
,
1165 const struct devlink_ops
*ops
= devlink_port
->devlink
->ops
;
1167 if (ops
&& ops
->sb_port_pool_set
)
1168 return ops
->sb_port_pool_set(devlink_port
, sb_index
,
1169 pool_index
, threshold
);
1173 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff
*skb
,
1174 struct genl_info
*info
)
1176 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1177 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1182 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1187 if (!info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
])
1190 threshold
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
]);
1191 return devlink_sb_port_pool_set(devlink_port
, devlink_sb
->index
,
1192 pool_index
, threshold
);
1196 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1197 struct devlink_port
*devlink_port
,
1198 struct devlink_sb
*devlink_sb
, u16 tc_index
,
1199 enum devlink_sb_pool_type pool_type
,
1200 enum devlink_command cmd
,
1201 u32 portid
, u32 seq
, int flags
)
1203 const struct devlink_ops
*ops
= devlink
->ops
;
1209 err
= ops
->sb_tc_pool_bind_get(devlink_port
, devlink_sb
->index
,
1210 tc_index
, pool_type
,
1211 &pool_index
, &threshold
);
1215 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1219 if (devlink_nl_put_handle(msg
, devlink
))
1220 goto nla_put_failure
;
1221 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
1222 goto nla_put_failure
;
1223 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1224 goto nla_put_failure
;
1225 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_TC_INDEX
, tc_index
))
1226 goto nla_put_failure
;
1227 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_TYPE
, pool_type
))
1228 goto nla_put_failure
;
1229 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1230 goto nla_put_failure
;
1231 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_THRESHOLD
, threshold
))
1232 goto nla_put_failure
;
1234 if (ops
->sb_occ_tc_port_bind_get
) {
1238 err
= ops
->sb_occ_tc_port_bind_get(devlink_port
,
1240 tc_index
, pool_type
,
1242 if (err
&& err
!= -EOPNOTSUPP
)
1245 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_CUR
, cur
))
1246 goto nla_put_failure
;
1247 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_MAX
, max
))
1248 goto nla_put_failure
;
1252 genlmsg_end(msg
, hdr
);
1256 genlmsg_cancel(msg
, hdr
);
1260 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff
*skb
,
1261 struct genl_info
*info
)
1263 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1264 struct devlink
*devlink
= devlink_port
->devlink
;
1265 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1266 struct sk_buff
*msg
;
1267 enum devlink_sb_pool_type pool_type
;
1271 err
= devlink_sb_pool_type_get_from_info(info
, &pool_type
);
1275 err
= devlink_sb_tc_index_get_from_info(devlink_sb
, info
,
1276 pool_type
, &tc_index
);
1280 if (!devlink
->ops
|| !devlink
->ops
->sb_tc_pool_bind_get
)
1283 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1287 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
, devlink_port
,
1288 devlink_sb
, tc_index
, pool_type
,
1289 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1297 return genlmsg_reply(msg
, info
);
1300 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff
*msg
,
1301 int start
, int *p_idx
,
1302 struct devlink
*devlink
,
1303 struct devlink_sb
*devlink_sb
,
1304 u32 portid
, u32 seq
)
1306 struct devlink_port
*devlink_port
;
1310 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
1312 tc_index
< devlink_sb
->ingress_tc_count
; tc_index
++) {
1313 if (*p_idx
< start
) {
1317 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
,
1321 DEVLINK_SB_POOL_TYPE_INGRESS
,
1322 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1330 tc_index
< devlink_sb
->egress_tc_count
; tc_index
++) {
1331 if (*p_idx
< start
) {
1335 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
,
1339 DEVLINK_SB_POOL_TYPE_EGRESS
,
1340 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1352 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff
*msg
,
1353 struct netlink_callback
*cb
)
1355 struct devlink
*devlink
;
1356 struct devlink_sb
*devlink_sb
;
1357 int start
= cb
->args
[0];
1361 mutex_lock(&devlink_mutex
);
1362 list_for_each_entry(devlink
, &devlink_list
, list
) {
1363 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1364 !devlink
->ops
|| !devlink
->ops
->sb_tc_pool_bind_get
)
1367 mutex_lock(&devlink
->lock
);
1368 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1369 err
= __sb_tc_pool_bind_get_dumpit(msg
, start
, &idx
,
1372 NETLINK_CB(cb
->skb
).portid
,
1373 cb
->nlh
->nlmsg_seq
);
1374 if (err
&& err
!= -EOPNOTSUPP
) {
1375 mutex_unlock(&devlink
->lock
);
1379 mutex_unlock(&devlink
->lock
);
1382 mutex_unlock(&devlink_mutex
);
1388 static int devlink_sb_tc_pool_bind_set(struct devlink_port
*devlink_port
,
1389 unsigned int sb_index
, u16 tc_index
,
1390 enum devlink_sb_pool_type pool_type
,
1391 u16 pool_index
, u32 threshold
)
1394 const struct devlink_ops
*ops
= devlink_port
->devlink
->ops
;
1396 if (ops
&& ops
->sb_tc_pool_bind_set
)
1397 return ops
->sb_tc_pool_bind_set(devlink_port
, sb_index
,
1398 tc_index
, pool_type
,
1399 pool_index
, threshold
);
1403 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff
*skb
,
1404 struct genl_info
*info
)
1406 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1407 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1408 enum devlink_sb_pool_type pool_type
;
1414 err
= devlink_sb_pool_type_get_from_info(info
, &pool_type
);
1418 err
= devlink_sb_tc_index_get_from_info(devlink_sb
, info
,
1419 pool_type
, &tc_index
);
1423 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1428 if (!info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
])
1431 threshold
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
]);
1432 return devlink_sb_tc_pool_bind_set(devlink_port
, devlink_sb
->index
,
1433 tc_index
, pool_type
,
1434 pool_index
, threshold
);
1437 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff
*skb
,
1438 struct genl_info
*info
)
1440 struct devlink
*devlink
= info
->user_ptr
[0];
1441 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1442 const struct devlink_ops
*ops
= devlink
->ops
;
1444 if (ops
&& ops
->sb_occ_snapshot
)
1445 return ops
->sb_occ_snapshot(devlink
, devlink_sb
->index
);
1449 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff
*skb
,
1450 struct genl_info
*info
)
1452 struct devlink
*devlink
= info
->user_ptr
[0];
1453 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1454 const struct devlink_ops
*ops
= devlink
->ops
;
1456 if (ops
&& ops
->sb_occ_max_clear
)
1457 return ops
->sb_occ_max_clear(devlink
, devlink_sb
->index
);
1461 static int devlink_nl_eswitch_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1462 enum devlink_command cmd
, u32 portid
,
1465 const struct devlink_ops
*ops
= devlink
->ops
;
1466 u8 inline_mode
, encap_mode
;
1471 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1475 err
= devlink_nl_put_handle(msg
, devlink
);
1477 goto nla_put_failure
;
1479 if (ops
->eswitch_mode_get
) {
1480 err
= ops
->eswitch_mode_get(devlink
, &mode
);
1482 goto nla_put_failure
;
1483 err
= nla_put_u16(msg
, DEVLINK_ATTR_ESWITCH_MODE
, mode
);
1485 goto nla_put_failure
;
1488 if (ops
->eswitch_inline_mode_get
) {
1489 err
= ops
->eswitch_inline_mode_get(devlink
, &inline_mode
);
1491 goto nla_put_failure
;
1492 err
= nla_put_u8(msg
, DEVLINK_ATTR_ESWITCH_INLINE_MODE
,
1495 goto nla_put_failure
;
1498 if (ops
->eswitch_encap_mode_get
) {
1499 err
= ops
->eswitch_encap_mode_get(devlink
, &encap_mode
);
1501 goto nla_put_failure
;
1502 err
= nla_put_u8(msg
, DEVLINK_ATTR_ESWITCH_ENCAP_MODE
, encap_mode
);
1504 goto nla_put_failure
;
1507 genlmsg_end(msg
, hdr
);
1511 genlmsg_cancel(msg
, hdr
);
1515 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff
*skb
,
1516 struct genl_info
*info
)
1518 struct devlink
*devlink
= info
->user_ptr
[0];
1519 const struct devlink_ops
*ops
= devlink
->ops
;
1520 struct sk_buff
*msg
;
1526 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1530 err
= devlink_nl_eswitch_fill(msg
, devlink
, DEVLINK_CMD_ESWITCH_GET
,
1531 info
->snd_portid
, info
->snd_seq
, 0);
1538 return genlmsg_reply(msg
, info
);
1541 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff
*skb
,
1542 struct genl_info
*info
)
1544 struct devlink
*devlink
= info
->user_ptr
[0];
1545 const struct devlink_ops
*ops
= devlink
->ops
;
1546 u8 inline_mode
, encap_mode
;
1553 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_MODE
]) {
1554 if (!ops
->eswitch_mode_set
)
1556 mode
= nla_get_u16(info
->attrs
[DEVLINK_ATTR_ESWITCH_MODE
]);
1557 err
= ops
->eswitch_mode_set(devlink
, mode
);
1562 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_INLINE_MODE
]) {
1563 if (!ops
->eswitch_inline_mode_set
)
1565 inline_mode
= nla_get_u8(
1566 info
->attrs
[DEVLINK_ATTR_ESWITCH_INLINE_MODE
]);
1567 err
= ops
->eswitch_inline_mode_set(devlink
, inline_mode
);
1572 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE
]) {
1573 if (!ops
->eswitch_encap_mode_set
)
1575 encap_mode
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE
]);
1576 err
= ops
->eswitch_encap_mode_set(devlink
, encap_mode
);
1584 int devlink_dpipe_match_put(struct sk_buff
*skb
,
1585 struct devlink_dpipe_match
*match
)
1587 struct devlink_dpipe_header
*header
= match
->header
;
1588 struct devlink_dpipe_field
*field
= &header
->fields
[match
->field_id
];
1589 struct nlattr
*match_attr
;
1591 match_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_MATCH
);
1595 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_MATCH_TYPE
, match
->type
) ||
1596 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, match
->header_index
) ||
1597 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
1598 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
1599 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
1600 goto nla_put_failure
;
1602 nla_nest_end(skb
, match_attr
);
1606 nla_nest_cancel(skb
, match_attr
);
1609 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put
);
1611 static int devlink_dpipe_matches_put(struct devlink_dpipe_table
*table
,
1612 struct sk_buff
*skb
)
1614 struct nlattr
*matches_attr
;
1616 matches_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_TABLE_MATCHES
);
1620 if (table
->table_ops
->matches_dump(table
->priv
, skb
))
1621 goto nla_put_failure
;
1623 nla_nest_end(skb
, matches_attr
);
1627 nla_nest_cancel(skb
, matches_attr
);
1631 int devlink_dpipe_action_put(struct sk_buff
*skb
,
1632 struct devlink_dpipe_action
*action
)
1634 struct devlink_dpipe_header
*header
= action
->header
;
1635 struct devlink_dpipe_field
*field
= &header
->fields
[action
->field_id
];
1636 struct nlattr
*action_attr
;
1638 action_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_ACTION
);
1642 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_ACTION_TYPE
, action
->type
) ||
1643 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, action
->header_index
) ||
1644 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
1645 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
1646 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
1647 goto nla_put_failure
;
1649 nla_nest_end(skb
, action_attr
);
1653 nla_nest_cancel(skb
, action_attr
);
1656 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put
);
1658 static int devlink_dpipe_actions_put(struct devlink_dpipe_table
*table
,
1659 struct sk_buff
*skb
)
1661 struct nlattr
*actions_attr
;
1663 actions_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_TABLE_ACTIONS
);
1667 if (table
->table_ops
->actions_dump(table
->priv
, skb
))
1668 goto nla_put_failure
;
1670 nla_nest_end(skb
, actions_attr
);
1674 nla_nest_cancel(skb
, actions_attr
);
1678 static int devlink_dpipe_table_put(struct sk_buff
*skb
,
1679 struct devlink_dpipe_table
*table
)
1681 struct nlattr
*table_attr
;
1684 table_size
= table
->table_ops
->size_get(table
->priv
);
1685 table_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_TABLE
);
1689 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_TABLE_NAME
, table
->name
) ||
1690 nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_SIZE
, table_size
,
1692 goto nla_put_failure
;
1693 if (nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
,
1694 table
->counters_enabled
))
1695 goto nla_put_failure
;
1697 if (table
->resource_valid
) {
1698 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID
,
1699 table
->resource_id
, DEVLINK_ATTR_PAD
) ||
1700 nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS
,
1701 table
->resource_units
, DEVLINK_ATTR_PAD
))
1702 goto nla_put_failure
;
1704 if (devlink_dpipe_matches_put(table
, skb
))
1705 goto nla_put_failure
;
1707 if (devlink_dpipe_actions_put(table
, skb
))
1708 goto nla_put_failure
;
1710 nla_nest_end(skb
, table_attr
);
1714 nla_nest_cancel(skb
, table_attr
);
1718 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff
**pskb
,
1719 struct genl_info
*info
)
1724 err
= genlmsg_reply(*pskb
, info
);
1728 *pskb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1734 static int devlink_dpipe_tables_fill(struct genl_info
*info
,
1735 enum devlink_command cmd
, int flags
,
1736 struct list_head
*dpipe_tables
,
1737 const char *table_name
)
1739 struct devlink
*devlink
= info
->user_ptr
[0];
1740 struct devlink_dpipe_table
*table
;
1741 struct nlattr
*tables_attr
;
1742 struct sk_buff
*skb
= NULL
;
1743 struct nlmsghdr
*nlh
;
1749 table
= list_first_entry(dpipe_tables
,
1750 struct devlink_dpipe_table
, list
);
1752 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
1756 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
1757 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
1763 if (devlink_nl_put_handle(skb
, devlink
))
1764 goto nla_put_failure
;
1765 tables_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_TABLES
);
1767 goto nla_put_failure
;
1771 list_for_each_entry_from(table
, dpipe_tables
, list
) {
1773 err
= devlink_dpipe_table_put(skb
, table
);
1781 if (!strcmp(table
->name
, table_name
)) {
1782 err
= devlink_dpipe_table_put(skb
, table
);
1790 nla_nest_end(skb
, tables_attr
);
1791 genlmsg_end(skb
, hdr
);
1796 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
1797 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
1799 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
1801 goto err_skb_send_alloc
;
1805 return genlmsg_reply(skb
, info
);
1811 genlmsg_cancel(skb
, hdr
);
1816 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff
*skb
,
1817 struct genl_info
*info
)
1819 struct devlink
*devlink
= info
->user_ptr
[0];
1820 const char *table_name
= NULL
;
1822 if (info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
1823 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
1825 return devlink_dpipe_tables_fill(info
, DEVLINK_CMD_DPIPE_TABLE_GET
, 0,
1826 &devlink
->dpipe_table_list
,
1830 static int devlink_dpipe_value_put(struct sk_buff
*skb
,
1831 struct devlink_dpipe_value
*value
)
1833 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE
,
1834 value
->value_size
, value
->value
))
1837 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE_MASK
,
1838 value
->value_size
, value
->mask
))
1840 if (value
->mapping_valid
)
1841 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_VALUE_MAPPING
,
1842 value
->mapping_value
))
1847 static int devlink_dpipe_action_value_put(struct sk_buff
*skb
,
1848 struct devlink_dpipe_value
*value
)
1852 if (devlink_dpipe_action_put(skb
, value
->action
))
1854 if (devlink_dpipe_value_put(skb
, value
))
1859 static int devlink_dpipe_action_values_put(struct sk_buff
*skb
,
1860 struct devlink_dpipe_value
*values
,
1861 unsigned int values_count
)
1863 struct nlattr
*action_attr
;
1867 for (i
= 0; i
< values_count
; i
++) {
1868 action_attr
= nla_nest_start(skb
,
1869 DEVLINK_ATTR_DPIPE_ACTION_VALUE
);
1872 err
= devlink_dpipe_action_value_put(skb
, &values
[i
]);
1874 goto err_action_value_put
;
1875 nla_nest_end(skb
, action_attr
);
1879 err_action_value_put
:
1880 nla_nest_cancel(skb
, action_attr
);
1884 static int devlink_dpipe_match_value_put(struct sk_buff
*skb
,
1885 struct devlink_dpipe_value
*value
)
1889 if (devlink_dpipe_match_put(skb
, value
->match
))
1891 if (devlink_dpipe_value_put(skb
, value
))
1896 static int devlink_dpipe_match_values_put(struct sk_buff
*skb
,
1897 struct devlink_dpipe_value
*values
,
1898 unsigned int values_count
)
1900 struct nlattr
*match_attr
;
1904 for (i
= 0; i
< values_count
; i
++) {
1905 match_attr
= nla_nest_start(skb
,
1906 DEVLINK_ATTR_DPIPE_MATCH_VALUE
);
1909 err
= devlink_dpipe_match_value_put(skb
, &values
[i
]);
1911 goto err_match_value_put
;
1912 nla_nest_end(skb
, match_attr
);
1916 err_match_value_put
:
1917 nla_nest_cancel(skb
, match_attr
);
1921 static int devlink_dpipe_entry_put(struct sk_buff
*skb
,
1922 struct devlink_dpipe_entry
*entry
)
1924 struct nlattr
*entry_attr
, *matches_attr
, *actions_attr
;
1927 entry_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_ENTRY
);
1931 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_INDEX
, entry
->index
,
1933 goto nla_put_failure
;
1934 if (entry
->counter_valid
)
1935 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER
,
1936 entry
->counter
, DEVLINK_ATTR_PAD
))
1937 goto nla_put_failure
;
1939 matches_attr
= nla_nest_start(skb
,
1940 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES
);
1942 goto nla_put_failure
;
1944 err
= devlink_dpipe_match_values_put(skb
, entry
->match_values
,
1945 entry
->match_values_count
);
1947 nla_nest_cancel(skb
, matches_attr
);
1948 goto err_match_values_put
;
1950 nla_nest_end(skb
, matches_attr
);
1952 actions_attr
= nla_nest_start(skb
,
1953 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES
);
1955 goto nla_put_failure
;
1957 err
= devlink_dpipe_action_values_put(skb
, entry
->action_values
,
1958 entry
->action_values_count
);
1960 nla_nest_cancel(skb
, actions_attr
);
1961 goto err_action_values_put
;
1963 nla_nest_end(skb
, actions_attr
);
1965 nla_nest_end(skb
, entry_attr
);
1970 err_match_values_put
:
1971 err_action_values_put
:
1972 nla_nest_cancel(skb
, entry_attr
);
1976 static struct devlink_dpipe_table
*
1977 devlink_dpipe_table_find(struct list_head
*dpipe_tables
,
1978 const char *table_name
)
1980 struct devlink_dpipe_table
*table
;
1982 list_for_each_entry_rcu(table
, dpipe_tables
, list
) {
1983 if (!strcmp(table
->name
, table_name
))
1989 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx
*dump_ctx
)
1991 struct devlink
*devlink
;
1994 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
->skb
,
1999 dump_ctx
->hdr
= genlmsg_put(dump_ctx
->skb
,
2000 dump_ctx
->info
->snd_portid
,
2001 dump_ctx
->info
->snd_seq
,
2002 &devlink_nl_family
, NLM_F_MULTI
,
2005 goto nla_put_failure
;
2007 devlink
= dump_ctx
->info
->user_ptr
[0];
2008 if (devlink_nl_put_handle(dump_ctx
->skb
, devlink
))
2009 goto nla_put_failure
;
2010 dump_ctx
->nest
= nla_nest_start(dump_ctx
->skb
,
2011 DEVLINK_ATTR_DPIPE_ENTRIES
);
2012 if (!dump_ctx
->nest
)
2013 goto nla_put_failure
;
2017 genlmsg_cancel(dump_ctx
->skb
, dump_ctx
->hdr
);
2018 nlmsg_free(dump_ctx
->skb
);
2021 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare
);
2023 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx
*dump_ctx
,
2024 struct devlink_dpipe_entry
*entry
)
2026 return devlink_dpipe_entry_put(dump_ctx
->skb
, entry
);
2028 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append
);
2030 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx
*dump_ctx
)
2032 nla_nest_end(dump_ctx
->skb
, dump_ctx
->nest
);
2033 genlmsg_end(dump_ctx
->skb
, dump_ctx
->hdr
);
2036 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close
);
2038 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry
*entry
)
2041 unsigned int value_count
, value_index
;
2042 struct devlink_dpipe_value
*value
;
2044 value
= entry
->action_values
;
2045 value_count
= entry
->action_values_count
;
2046 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2047 kfree(value
[value_index
].value
);
2048 kfree(value
[value_index
].mask
);
2051 value
= entry
->match_values
;
2052 value_count
= entry
->match_values_count
;
2053 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2054 kfree(value
[value_index
].value
);
2055 kfree(value
[value_index
].mask
);
2058 EXPORT_SYMBOL(devlink_dpipe_entry_clear
);
2060 static int devlink_dpipe_entries_fill(struct genl_info
*info
,
2061 enum devlink_command cmd
, int flags
,
2062 struct devlink_dpipe_table
*table
)
2064 struct devlink_dpipe_dump_ctx dump_ctx
;
2065 struct nlmsghdr
*nlh
;
2068 dump_ctx
.skb
= NULL
;
2070 dump_ctx
.info
= info
;
2072 err
= table
->table_ops
->entries_dump(table
->priv
,
2073 table
->counters_enabled
,
2076 goto err_entries_dump
;
2079 nlh
= nlmsg_put(dump_ctx
.skb
, info
->snd_portid
, info
->snd_seq
,
2080 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2082 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
.skb
, info
);
2084 goto err_skb_send_alloc
;
2087 return genlmsg_reply(dump_ctx
.skb
, info
);
2091 genlmsg_cancel(dump_ctx
.skb
, dump_ctx
.hdr
);
2092 nlmsg_free(dump_ctx
.skb
);
2096 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff
*skb
,
2097 struct genl_info
*info
)
2099 struct devlink
*devlink
= info
->user_ptr
[0];
2100 struct devlink_dpipe_table
*table
;
2101 const char *table_name
;
2103 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
2106 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2107 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2112 if (!table
->table_ops
->entries_dump
)
2115 return devlink_dpipe_entries_fill(info
, DEVLINK_CMD_DPIPE_ENTRIES_GET
,
2119 static int devlink_dpipe_fields_put(struct sk_buff
*skb
,
2120 const struct devlink_dpipe_header
*header
)
2122 struct devlink_dpipe_field
*field
;
2123 struct nlattr
*field_attr
;
2126 for (i
= 0; i
< header
->fields_count
; i
++) {
2127 field
= &header
->fields
[i
];
2128 field_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_FIELD
);
2131 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_FIELD_NAME
, field
->name
) ||
2132 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
2133 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH
, field
->bitwidth
) ||
2134 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE
, field
->mapping_type
))
2135 goto nla_put_failure
;
2136 nla_nest_end(skb
, field_attr
);
2141 nla_nest_cancel(skb
, field_attr
);
2145 static int devlink_dpipe_header_put(struct sk_buff
*skb
,
2146 struct devlink_dpipe_header
*header
)
2148 struct nlattr
*fields_attr
, *header_attr
;
2151 header_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_HEADER
);
2155 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_HEADER_NAME
, header
->name
) ||
2156 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
2157 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
2158 goto nla_put_failure
;
2160 fields_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_HEADER_FIELDS
);
2162 goto nla_put_failure
;
2164 err
= devlink_dpipe_fields_put(skb
, header
);
2166 nla_nest_cancel(skb
, fields_attr
);
2167 goto nla_put_failure
;
2169 nla_nest_end(skb
, fields_attr
);
2170 nla_nest_end(skb
, header_attr
);
2175 nla_nest_cancel(skb
, header_attr
);
2179 static int devlink_dpipe_headers_fill(struct genl_info
*info
,
2180 enum devlink_command cmd
, int flags
,
2181 struct devlink_dpipe_headers
*
2184 struct devlink
*devlink
= info
->user_ptr
[0];
2185 struct nlattr
*headers_attr
;
2186 struct sk_buff
*skb
= NULL
;
2187 struct nlmsghdr
*nlh
;
2194 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2198 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2199 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2205 if (devlink_nl_put_handle(skb
, devlink
))
2206 goto nla_put_failure
;
2207 headers_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_HEADERS
);
2209 goto nla_put_failure
;
2212 for (; i
< dpipe_headers
->headers_count
; i
++) {
2213 err
= devlink_dpipe_header_put(skb
, dpipe_headers
->headers
[i
]);
2221 nla_nest_end(skb
, headers_attr
);
2222 genlmsg_end(skb
, hdr
);
2223 if (i
!= dpipe_headers
->headers_count
)
2227 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2228 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2230 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2232 goto err_skb_send_alloc
;
2235 return genlmsg_reply(skb
, info
);
2241 genlmsg_cancel(skb
, hdr
);
2246 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff
*skb
,
2247 struct genl_info
*info
)
2249 struct devlink
*devlink
= info
->user_ptr
[0];
2251 if (!devlink
->dpipe_headers
)
2253 return devlink_dpipe_headers_fill(info
, DEVLINK_CMD_DPIPE_HEADERS_GET
,
2254 0, devlink
->dpipe_headers
);
2257 static int devlink_dpipe_table_counters_set(struct devlink
*devlink
,
2258 const char *table_name
,
2261 struct devlink_dpipe_table
*table
;
2263 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2268 if (table
->counter_control_extern
)
2271 if (!(table
->counters_enabled
^ enable
))
2274 table
->counters_enabled
= enable
;
2275 if (table
->table_ops
->counters_set_update
)
2276 table
->table_ops
->counters_set_update(table
->priv
, enable
);
2280 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff
*skb
,
2281 struct genl_info
*info
)
2283 struct devlink
*devlink
= info
->user_ptr
[0];
2284 const char *table_name
;
2285 bool counters_enable
;
2287 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
] ||
2288 !info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
])
2291 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2292 counters_enable
= !!nla_get_u8(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
]);
2294 return devlink_dpipe_table_counters_set(devlink
, table_name
,
2298 static struct devlink_resource
*
2299 devlink_resource_find(struct devlink
*devlink
,
2300 struct devlink_resource
*resource
, u64 resource_id
)
2302 struct list_head
*resource_list
;
2305 resource_list
= &resource
->resource_list
;
2307 resource_list
= &devlink
->resource_list
;
2309 list_for_each_entry(resource
, resource_list
, list
) {
2310 struct devlink_resource
*child_resource
;
2312 if (resource
->id
== resource_id
)
2315 child_resource
= devlink_resource_find(devlink
, resource
,
2318 return child_resource
;
2324 devlink_resource_validate_children(struct devlink_resource
*resource
)
2326 struct devlink_resource
*child_resource
;
2327 bool size_valid
= true;
2330 if (list_empty(&resource
->resource_list
))
2333 list_for_each_entry(child_resource
, &resource
->resource_list
, list
)
2334 parts_size
+= child_resource
->size_new
;
2336 if (parts_size
> resource
->size_new
)
2339 resource
->size_valid
= size_valid
;
2342 static int devlink_nl_cmd_resource_set(struct sk_buff
*skb
,
2343 struct genl_info
*info
)
2345 struct devlink
*devlink
= info
->user_ptr
[0];
2346 struct devlink_resource
*resource
;
2351 if (!info
->attrs
[DEVLINK_ATTR_RESOURCE_ID
] ||
2352 !info
->attrs
[DEVLINK_ATTR_RESOURCE_SIZE
])
2354 resource_id
= nla_get_u64(info
->attrs
[DEVLINK_ATTR_RESOURCE_ID
]);
2356 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
2360 if (!resource
->resource_ops
->size_validate
)
2363 size
= nla_get_u64(info
->attrs
[DEVLINK_ATTR_RESOURCE_SIZE
]);
2364 err
= resource
->resource_ops
->size_validate(devlink
, size
,
2369 resource
->size_new
= size
;
2370 devlink_resource_validate_children(resource
);
2371 if (resource
->parent
)
2372 devlink_resource_validate_children(resource
->parent
);
2377 devlink_resource_size_params_put(struct devlink_resource
*resource
,
2378 struct sk_buff
*skb
)
2380 struct devlink_resource_size_params
*size_params
;
2382 size_params
= &resource
->size_params
;
2383 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_GRAN
,
2384 size_params
->size_granularity
, DEVLINK_ATTR_PAD
) ||
2385 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_MAX
,
2386 size_params
->size_max
, DEVLINK_ATTR_PAD
) ||
2387 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_MIN
,
2388 size_params
->size_min
, DEVLINK_ATTR_PAD
) ||
2389 nla_put_u8(skb
, DEVLINK_ATTR_RESOURCE_UNIT
, size_params
->unit
))
2394 static int devlink_resource_put(struct devlink
*devlink
, struct sk_buff
*skb
,
2395 struct devlink_resource
*resource
)
2397 struct devlink_resource
*child_resource
;
2398 struct nlattr
*child_resource_attr
;
2399 struct nlattr
*resource_attr
;
2401 resource_attr
= nla_nest_start(skb
, DEVLINK_ATTR_RESOURCE
);
2405 if (nla_put_string(skb
, DEVLINK_ATTR_RESOURCE_NAME
, resource
->name
) ||
2406 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE
, resource
->size
,
2407 DEVLINK_ATTR_PAD
) ||
2408 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_ID
, resource
->id
,
2410 goto nla_put_failure
;
2411 if (resource
->size
!= resource
->size_new
)
2412 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_NEW
,
2413 resource
->size_new
, DEVLINK_ATTR_PAD
);
2414 if (resource
->resource_ops
&& resource
->resource_ops
->occ_get
)
2415 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_OCC
,
2416 resource
->resource_ops
->occ_get(devlink
),
2418 goto nla_put_failure
;
2419 if (devlink_resource_size_params_put(resource
, skb
))
2420 goto nla_put_failure
;
2421 if (list_empty(&resource
->resource_list
))
2424 if (nla_put_u8(skb
, DEVLINK_ATTR_RESOURCE_SIZE_VALID
,
2425 resource
->size_valid
))
2426 goto nla_put_failure
;
2428 child_resource_attr
= nla_nest_start(skb
, DEVLINK_ATTR_RESOURCE_LIST
);
2429 if (!child_resource_attr
)
2430 goto nla_put_failure
;
2432 list_for_each_entry(child_resource
, &resource
->resource_list
, list
) {
2433 if (devlink_resource_put(devlink
, skb
, child_resource
))
2434 goto resource_put_failure
;
2437 nla_nest_end(skb
, child_resource_attr
);
2439 nla_nest_end(skb
, resource_attr
);
2442 resource_put_failure
:
2443 nla_nest_cancel(skb
, child_resource_attr
);
2445 nla_nest_cancel(skb
, resource_attr
);
2449 static int devlink_resource_fill(struct genl_info
*info
,
2450 enum devlink_command cmd
, int flags
)
2452 struct devlink
*devlink
= info
->user_ptr
[0];
2453 struct devlink_resource
*resource
;
2454 struct nlattr
*resources_attr
;
2455 struct sk_buff
*skb
= NULL
;
2456 struct nlmsghdr
*nlh
;
2462 resource
= list_first_entry(&devlink
->resource_list
,
2463 struct devlink_resource
, list
);
2465 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2469 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2470 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2476 if (devlink_nl_put_handle(skb
, devlink
))
2477 goto nla_put_failure
;
2479 resources_attr
= nla_nest_start(skb
, DEVLINK_ATTR_RESOURCE_LIST
);
2480 if (!resources_attr
)
2481 goto nla_put_failure
;
2485 list_for_each_entry_from(resource
, &devlink
->resource_list
, list
) {
2486 err
= devlink_resource_put(devlink
, skb
, resource
);
2489 goto err_resource_put
;
2495 nla_nest_end(skb
, resources_attr
);
2496 genlmsg_end(skb
, hdr
);
2500 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2501 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2503 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2505 goto err_skb_send_alloc
;
2508 return genlmsg_reply(skb
, info
);
2514 genlmsg_cancel(skb
, hdr
);
2519 static int devlink_nl_cmd_resource_dump(struct sk_buff
*skb
,
2520 struct genl_info
*info
)
2522 struct devlink
*devlink
= info
->user_ptr
[0];
2524 if (list_empty(&devlink
->resource_list
))
2527 return devlink_resource_fill(info
, DEVLINK_CMD_RESOURCE_DUMP
, 0);
2531 devlink_resources_validate(struct devlink
*devlink
,
2532 struct devlink_resource
*resource
,
2533 struct genl_info
*info
)
2535 struct list_head
*resource_list
;
2539 resource_list
= &resource
->resource_list
;
2541 resource_list
= &devlink
->resource_list
;
2543 list_for_each_entry(resource
, resource_list
, list
) {
2544 if (!resource
->size_valid
)
2546 err
= devlink_resources_validate(devlink
, resource
, info
);
2553 static int devlink_nl_cmd_reload(struct sk_buff
*skb
, struct genl_info
*info
)
2555 struct devlink
*devlink
= info
->user_ptr
[0];
2558 if (!devlink
->ops
->reload
)
2561 err
= devlink_resources_validate(devlink
, NULL
, info
);
2563 NL_SET_ERR_MSG_MOD(info
->extack
, "resources size validation failed");
2566 return devlink
->ops
->reload(devlink
);
2569 static const struct nla_policy devlink_nl_policy
[DEVLINK_ATTR_MAX
+ 1] = {
2570 [DEVLINK_ATTR_BUS_NAME
] = { .type
= NLA_NUL_STRING
},
2571 [DEVLINK_ATTR_DEV_NAME
] = { .type
= NLA_NUL_STRING
},
2572 [DEVLINK_ATTR_PORT_INDEX
] = { .type
= NLA_U32
},
2573 [DEVLINK_ATTR_PORT_TYPE
] = { .type
= NLA_U16
},
2574 [DEVLINK_ATTR_PORT_SPLIT_COUNT
] = { .type
= NLA_U32
},
2575 [DEVLINK_ATTR_SB_INDEX
] = { .type
= NLA_U32
},
2576 [DEVLINK_ATTR_SB_POOL_INDEX
] = { .type
= NLA_U16
},
2577 [DEVLINK_ATTR_SB_POOL_TYPE
] = { .type
= NLA_U8
},
2578 [DEVLINK_ATTR_SB_POOL_SIZE
] = { .type
= NLA_U32
},
2579 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
] = { .type
= NLA_U8
},
2580 [DEVLINK_ATTR_SB_THRESHOLD
] = { .type
= NLA_U32
},
2581 [DEVLINK_ATTR_SB_TC_INDEX
] = { .type
= NLA_U16
},
2582 [DEVLINK_ATTR_ESWITCH_MODE
] = { .type
= NLA_U16
},
2583 [DEVLINK_ATTR_ESWITCH_INLINE_MODE
] = { .type
= NLA_U8
},
2584 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE
] = { .type
= NLA_U8
},
2585 [DEVLINK_ATTR_DPIPE_TABLE_NAME
] = { .type
= NLA_NUL_STRING
},
2586 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
] = { .type
= NLA_U8
},
2587 [DEVLINK_ATTR_RESOURCE_ID
] = { .type
= NLA_U64
},
2588 [DEVLINK_ATTR_RESOURCE_SIZE
] = { .type
= NLA_U64
},
2591 static const struct genl_ops devlink_nl_ops
[] = {
2593 .cmd
= DEVLINK_CMD_GET
,
2594 .doit
= devlink_nl_cmd_get_doit
,
2595 .dumpit
= devlink_nl_cmd_get_dumpit
,
2596 .policy
= devlink_nl_policy
,
2597 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2598 /* can be retrieved by unprivileged users */
2601 .cmd
= DEVLINK_CMD_PORT_GET
,
2602 .doit
= devlink_nl_cmd_port_get_doit
,
2603 .dumpit
= devlink_nl_cmd_port_get_dumpit
,
2604 .policy
= devlink_nl_policy
,
2605 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
2606 /* can be retrieved by unprivileged users */
2609 .cmd
= DEVLINK_CMD_PORT_SET
,
2610 .doit
= devlink_nl_cmd_port_set_doit
,
2611 .policy
= devlink_nl_policy
,
2612 .flags
= GENL_ADMIN_PERM
,
2613 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
2616 .cmd
= DEVLINK_CMD_PORT_SPLIT
,
2617 .doit
= devlink_nl_cmd_port_split_doit
,
2618 .policy
= devlink_nl_policy
,
2619 .flags
= GENL_ADMIN_PERM
,
2620 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2621 DEVLINK_NL_FLAG_NO_LOCK
,
2624 .cmd
= DEVLINK_CMD_PORT_UNSPLIT
,
2625 .doit
= devlink_nl_cmd_port_unsplit_doit
,
2626 .policy
= devlink_nl_policy
,
2627 .flags
= GENL_ADMIN_PERM
,
2628 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2629 DEVLINK_NL_FLAG_NO_LOCK
,
2632 .cmd
= DEVLINK_CMD_SB_GET
,
2633 .doit
= devlink_nl_cmd_sb_get_doit
,
2634 .dumpit
= devlink_nl_cmd_sb_get_dumpit
,
2635 .policy
= devlink_nl_policy
,
2636 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2637 DEVLINK_NL_FLAG_NEED_SB
,
2638 /* can be retrieved by unprivileged users */
2641 .cmd
= DEVLINK_CMD_SB_POOL_GET
,
2642 .doit
= devlink_nl_cmd_sb_pool_get_doit
,
2643 .dumpit
= devlink_nl_cmd_sb_pool_get_dumpit
,
2644 .policy
= devlink_nl_policy
,
2645 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2646 DEVLINK_NL_FLAG_NEED_SB
,
2647 /* can be retrieved by unprivileged users */
2650 .cmd
= DEVLINK_CMD_SB_POOL_SET
,
2651 .doit
= devlink_nl_cmd_sb_pool_set_doit
,
2652 .policy
= devlink_nl_policy
,
2653 .flags
= GENL_ADMIN_PERM
,
2654 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2655 DEVLINK_NL_FLAG_NEED_SB
,
2658 .cmd
= DEVLINK_CMD_SB_PORT_POOL_GET
,
2659 .doit
= devlink_nl_cmd_sb_port_pool_get_doit
,
2660 .dumpit
= devlink_nl_cmd_sb_port_pool_get_dumpit
,
2661 .policy
= devlink_nl_policy
,
2662 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
2663 DEVLINK_NL_FLAG_NEED_SB
,
2664 /* can be retrieved by unprivileged users */
2667 .cmd
= DEVLINK_CMD_SB_PORT_POOL_SET
,
2668 .doit
= devlink_nl_cmd_sb_port_pool_set_doit
,
2669 .policy
= devlink_nl_policy
,
2670 .flags
= GENL_ADMIN_PERM
,
2671 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
2672 DEVLINK_NL_FLAG_NEED_SB
,
2675 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_GET
,
2676 .doit
= devlink_nl_cmd_sb_tc_pool_bind_get_doit
,
2677 .dumpit
= devlink_nl_cmd_sb_tc_pool_bind_get_dumpit
,
2678 .policy
= devlink_nl_policy
,
2679 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
2680 DEVLINK_NL_FLAG_NEED_SB
,
2681 /* can be retrieved by unprivileged users */
2684 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_SET
,
2685 .doit
= devlink_nl_cmd_sb_tc_pool_bind_set_doit
,
2686 .policy
= devlink_nl_policy
,
2687 .flags
= GENL_ADMIN_PERM
,
2688 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
2689 DEVLINK_NL_FLAG_NEED_SB
,
2692 .cmd
= DEVLINK_CMD_SB_OCC_SNAPSHOT
,
2693 .doit
= devlink_nl_cmd_sb_occ_snapshot_doit
,
2694 .policy
= devlink_nl_policy
,
2695 .flags
= GENL_ADMIN_PERM
,
2696 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2697 DEVLINK_NL_FLAG_NEED_SB
,
2700 .cmd
= DEVLINK_CMD_SB_OCC_MAX_CLEAR
,
2701 .doit
= devlink_nl_cmd_sb_occ_max_clear_doit
,
2702 .policy
= devlink_nl_policy
,
2703 .flags
= GENL_ADMIN_PERM
,
2704 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2705 DEVLINK_NL_FLAG_NEED_SB
,
2708 .cmd
= DEVLINK_CMD_ESWITCH_GET
,
2709 .doit
= devlink_nl_cmd_eswitch_get_doit
,
2710 .policy
= devlink_nl_policy
,
2711 .flags
= GENL_ADMIN_PERM
,
2712 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2715 .cmd
= DEVLINK_CMD_ESWITCH_SET
,
2716 .doit
= devlink_nl_cmd_eswitch_set_doit
,
2717 .policy
= devlink_nl_policy
,
2718 .flags
= GENL_ADMIN_PERM
,
2719 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2722 .cmd
= DEVLINK_CMD_DPIPE_TABLE_GET
,
2723 .doit
= devlink_nl_cmd_dpipe_table_get
,
2724 .policy
= devlink_nl_policy
,
2725 .flags
= GENL_ADMIN_PERM
,
2726 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2729 .cmd
= DEVLINK_CMD_DPIPE_ENTRIES_GET
,
2730 .doit
= devlink_nl_cmd_dpipe_entries_get
,
2731 .policy
= devlink_nl_policy
,
2732 .flags
= GENL_ADMIN_PERM
,
2733 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2736 .cmd
= DEVLINK_CMD_DPIPE_HEADERS_GET
,
2737 .doit
= devlink_nl_cmd_dpipe_headers_get
,
2738 .policy
= devlink_nl_policy
,
2739 .flags
= GENL_ADMIN_PERM
,
2740 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2743 .cmd
= DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET
,
2744 .doit
= devlink_nl_cmd_dpipe_table_counters_set
,
2745 .policy
= devlink_nl_policy
,
2746 .flags
= GENL_ADMIN_PERM
,
2747 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2750 .cmd
= DEVLINK_CMD_RESOURCE_SET
,
2751 .doit
= devlink_nl_cmd_resource_set
,
2752 .policy
= devlink_nl_policy
,
2753 .flags
= GENL_ADMIN_PERM
,
2754 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2757 .cmd
= DEVLINK_CMD_RESOURCE_DUMP
,
2758 .doit
= devlink_nl_cmd_resource_dump
,
2759 .policy
= devlink_nl_policy
,
2760 .flags
= GENL_ADMIN_PERM
,
2761 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2764 .cmd
= DEVLINK_CMD_RELOAD
,
2765 .doit
= devlink_nl_cmd_reload
,
2766 .policy
= devlink_nl_policy
,
2767 .flags
= GENL_ADMIN_PERM
,
2768 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2769 DEVLINK_NL_FLAG_NO_LOCK
,
2773 static struct genl_family devlink_nl_family __ro_after_init
= {
2774 .name
= DEVLINK_GENL_NAME
,
2775 .version
= DEVLINK_GENL_VERSION
,
2776 .maxattr
= DEVLINK_ATTR_MAX
,
2778 .pre_doit
= devlink_nl_pre_doit
,
2779 .post_doit
= devlink_nl_post_doit
,
2780 .module
= THIS_MODULE
,
2781 .ops
= devlink_nl_ops
,
2782 .n_ops
= ARRAY_SIZE(devlink_nl_ops
),
2783 .mcgrps
= devlink_nl_mcgrps
,
2784 .n_mcgrps
= ARRAY_SIZE(devlink_nl_mcgrps
),
2788 * devlink_alloc - Allocate new devlink instance resources
2791 * @priv_size: size of user private data
2793 * Allocate new devlink instance resources, including devlink index
2796 struct devlink
*devlink_alloc(const struct devlink_ops
*ops
, size_t priv_size
)
2798 struct devlink
*devlink
;
2800 devlink
= kzalloc(sizeof(*devlink
) + priv_size
, GFP_KERNEL
);
2804 devlink_net_set(devlink
, &init_net
);
2805 INIT_LIST_HEAD(&devlink
->port_list
);
2806 INIT_LIST_HEAD(&devlink
->sb_list
);
2807 INIT_LIST_HEAD_RCU(&devlink
->dpipe_table_list
);
2808 INIT_LIST_HEAD(&devlink
->resource_list
);
2809 mutex_init(&devlink
->lock
);
2812 EXPORT_SYMBOL_GPL(devlink_alloc
);
2815 * devlink_register - Register devlink instance
2819 int devlink_register(struct devlink
*devlink
, struct device
*dev
)
2821 mutex_lock(&devlink_mutex
);
2823 list_add_tail(&devlink
->list
, &devlink_list
);
2824 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
2825 mutex_unlock(&devlink_mutex
);
2828 EXPORT_SYMBOL_GPL(devlink_register
);
2831 * devlink_unregister - Unregister devlink instance
2835 void devlink_unregister(struct devlink
*devlink
)
2837 mutex_lock(&devlink_mutex
);
2838 devlink_notify(devlink
, DEVLINK_CMD_DEL
);
2839 list_del(&devlink
->list
);
2840 mutex_unlock(&devlink_mutex
);
2842 EXPORT_SYMBOL_GPL(devlink_unregister
);
2845 * devlink_free - Free devlink instance resources
2849 void devlink_free(struct devlink
*devlink
)
2853 EXPORT_SYMBOL_GPL(devlink_free
);
2856 * devlink_port_register - Register devlink port
2859 * @devlink_port: devlink port
2862 * Register devlink port with provided port index. User can use
2863 * any indexing, even hw-related one. devlink_port structure
2864 * is convenient to be embedded inside user driver private structure.
2865 * Note that the caller should take care of zeroing the devlink_port
2868 int devlink_port_register(struct devlink
*devlink
,
2869 struct devlink_port
*devlink_port
,
2870 unsigned int port_index
)
2872 mutex_lock(&devlink
->lock
);
2873 if (devlink_port_index_exists(devlink
, port_index
)) {
2874 mutex_unlock(&devlink
->lock
);
2877 devlink_port
->devlink
= devlink
;
2878 devlink_port
->index
= port_index
;
2879 devlink_port
->registered
= true;
2880 list_add_tail(&devlink_port
->list
, &devlink
->port_list
);
2881 mutex_unlock(&devlink
->lock
);
2882 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
2885 EXPORT_SYMBOL_GPL(devlink_port_register
);
2888 * devlink_port_unregister - Unregister devlink port
2890 * @devlink_port: devlink port
2892 void devlink_port_unregister(struct devlink_port
*devlink_port
)
2894 struct devlink
*devlink
= devlink_port
->devlink
;
2896 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_DEL
);
2897 mutex_lock(&devlink
->lock
);
2898 list_del(&devlink_port
->list
);
2899 mutex_unlock(&devlink
->lock
);
2901 EXPORT_SYMBOL_GPL(devlink_port_unregister
);
2903 static void __devlink_port_type_set(struct devlink_port
*devlink_port
,
2904 enum devlink_port_type type
,
2907 devlink_port
->type
= type
;
2908 devlink_port
->type_dev
= type_dev
;
2909 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
2913 * devlink_port_type_eth_set - Set port type to Ethernet
2915 * @devlink_port: devlink port
2916 * @netdev: related netdevice
2918 void devlink_port_type_eth_set(struct devlink_port
*devlink_port
,
2919 struct net_device
*netdev
)
2921 return __devlink_port_type_set(devlink_port
,
2922 DEVLINK_PORT_TYPE_ETH
, netdev
);
2924 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set
);
2927 * devlink_port_type_ib_set - Set port type to InfiniBand
2929 * @devlink_port: devlink port
2930 * @ibdev: related IB device
2932 void devlink_port_type_ib_set(struct devlink_port
*devlink_port
,
2933 struct ib_device
*ibdev
)
2935 return __devlink_port_type_set(devlink_port
,
2936 DEVLINK_PORT_TYPE_IB
, ibdev
);
2938 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set
);
2941 * devlink_port_type_clear - Clear port type
2943 * @devlink_port: devlink port
2945 void devlink_port_type_clear(struct devlink_port
*devlink_port
)
2947 return __devlink_port_type_set(devlink_port
,
2948 DEVLINK_PORT_TYPE_NOTSET
, NULL
);
2950 EXPORT_SYMBOL_GPL(devlink_port_type_clear
);
2953 * devlink_port_split_set - Set port is split
2955 * @devlink_port: devlink port
2956 * @split_group: split group - identifies group split port is part of
2958 void devlink_port_split_set(struct devlink_port
*devlink_port
,
2961 devlink_port
->split
= true;
2962 devlink_port
->split_group
= split_group
;
2963 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
2965 EXPORT_SYMBOL_GPL(devlink_port_split_set
);
2967 int devlink_sb_register(struct devlink
*devlink
, unsigned int sb_index
,
2968 u32 size
, u16 ingress_pools_count
,
2969 u16 egress_pools_count
, u16 ingress_tc_count
,
2970 u16 egress_tc_count
)
2972 struct devlink_sb
*devlink_sb
;
2975 mutex_lock(&devlink
->lock
);
2976 if (devlink_sb_index_exists(devlink
, sb_index
)) {
2981 devlink_sb
= kzalloc(sizeof(*devlink_sb
), GFP_KERNEL
);
2986 devlink_sb
->index
= sb_index
;
2987 devlink_sb
->size
= size
;
2988 devlink_sb
->ingress_pools_count
= ingress_pools_count
;
2989 devlink_sb
->egress_pools_count
= egress_pools_count
;
2990 devlink_sb
->ingress_tc_count
= ingress_tc_count
;
2991 devlink_sb
->egress_tc_count
= egress_tc_count
;
2992 list_add_tail(&devlink_sb
->list
, &devlink
->sb_list
);
2994 mutex_unlock(&devlink
->lock
);
2997 EXPORT_SYMBOL_GPL(devlink_sb_register
);
2999 void devlink_sb_unregister(struct devlink
*devlink
, unsigned int sb_index
)
3001 struct devlink_sb
*devlink_sb
;
3003 mutex_lock(&devlink
->lock
);
3004 devlink_sb
= devlink_sb_get_by_index(devlink
, sb_index
);
3005 WARN_ON(!devlink_sb
);
3006 list_del(&devlink_sb
->list
);
3007 mutex_unlock(&devlink
->lock
);
3010 EXPORT_SYMBOL_GPL(devlink_sb_unregister
);
3013 * devlink_dpipe_headers_register - register dpipe headers
3016 * @dpipe_headers: dpipe header array
3018 * Register the headers supported by hardware.
3020 int devlink_dpipe_headers_register(struct devlink
*devlink
,
3021 struct devlink_dpipe_headers
*dpipe_headers
)
3023 mutex_lock(&devlink
->lock
);
3024 devlink
->dpipe_headers
= dpipe_headers
;
3025 mutex_unlock(&devlink
->lock
);
3028 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register
);
3031 * devlink_dpipe_headers_unregister - unregister dpipe headers
3035 * Unregister the headers supported by hardware.
3037 void devlink_dpipe_headers_unregister(struct devlink
*devlink
)
3039 mutex_lock(&devlink
->lock
);
3040 devlink
->dpipe_headers
= NULL
;
3041 mutex_unlock(&devlink
->lock
);
3043 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister
);
3046 * devlink_dpipe_table_counter_enabled - check if counter allocation
3049 * @table_name: tables name
3051 * Used by driver to check if counter allocation is required.
3052 * After counter allocation is turned on the table entries
3053 * are updated to include counter statistics.
3055 * After that point on the driver must respect the counter
3056 * state so that each entry added to the table is added
3059 bool devlink_dpipe_table_counter_enabled(struct devlink
*devlink
,
3060 const char *table_name
)
3062 struct devlink_dpipe_table
*table
;
3066 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
3070 enabled
= table
->counters_enabled
;
3074 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled
);
3077 * devlink_dpipe_table_register - register dpipe table
3080 * @table_name: table name
3081 * @table_ops: table ops
3083 * @counter_control_extern: external control for counters
3085 int devlink_dpipe_table_register(struct devlink
*devlink
,
3086 const char *table_name
,
3087 struct devlink_dpipe_table_ops
*table_ops
,
3088 void *priv
, bool counter_control_extern
)
3090 struct devlink_dpipe_table
*table
;
3092 if (devlink_dpipe_table_find(&devlink
->dpipe_table_list
, table_name
))
3095 if (WARN_ON(!table_ops
->size_get
))
3098 table
= kzalloc(sizeof(*table
), GFP_KERNEL
);
3102 table
->name
= table_name
;
3103 table
->table_ops
= table_ops
;
3105 table
->counter_control_extern
= counter_control_extern
;
3107 mutex_lock(&devlink
->lock
);
3108 list_add_tail_rcu(&table
->list
, &devlink
->dpipe_table_list
);
3109 mutex_unlock(&devlink
->lock
);
3112 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register
);
3115 * devlink_dpipe_table_unregister - unregister dpipe table
3118 * @table_name: table name
3120 void devlink_dpipe_table_unregister(struct devlink
*devlink
,
3121 const char *table_name
)
3123 struct devlink_dpipe_table
*table
;
3125 mutex_lock(&devlink
->lock
);
3126 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
3130 list_del_rcu(&table
->list
);
3131 mutex_unlock(&devlink
->lock
);
3132 kfree_rcu(table
, rcu
);
3135 mutex_unlock(&devlink
->lock
);
3137 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister
);
3140 * devlink_resource_register - devlink resource register
3143 * @resource_name: resource's name
3144 * @top_hierarchy: top hierarchy
3145 * @reload_required: reload is required for new configuration to
3147 * @resource_size: resource's size
3148 * @resource_id: resource's id
3149 * @parent_reosurce_id: resource's parent id
3150 * @size params: size parameters
3151 * @resource_ops: resource ops
3153 int devlink_resource_register(struct devlink
*devlink
,
3154 const char *resource_name
,
3158 u64 parent_resource_id
,
3159 const struct devlink_resource_size_params
*size_params
,
3160 const struct devlink_resource_ops
*resource_ops
)
3162 struct devlink_resource
*resource
;
3163 struct list_head
*resource_list
;
3166 mutex_lock(&devlink
->lock
);
3167 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
3173 resource
= kzalloc(sizeof(*resource
), GFP_KERNEL
);
3179 if (top_hierarchy
) {
3180 resource_list
= &devlink
->resource_list
;
3182 struct devlink_resource
*parent_resource
;
3184 parent_resource
= devlink_resource_find(devlink
, NULL
,
3185 parent_resource_id
);
3186 if (parent_resource
) {
3187 resource_list
= &parent_resource
->resource_list
;
3188 resource
->parent
= parent_resource
;
3196 resource
->name
= resource_name
;
3197 resource
->size
= resource_size
;
3198 resource
->size_new
= resource_size
;
3199 resource
->id
= resource_id
;
3200 resource
->resource_ops
= resource_ops
;
3201 resource
->size_valid
= true;
3202 memcpy(&resource
->size_params
, size_params
,
3203 sizeof(resource
->size_params
));
3204 INIT_LIST_HEAD(&resource
->resource_list
);
3205 list_add_tail(&resource
->list
, resource_list
);
3207 mutex_unlock(&devlink
->lock
);
3210 EXPORT_SYMBOL_GPL(devlink_resource_register
);
3213 * devlink_resources_unregister - free all resources
3216 * @resource: resource
3218 void devlink_resources_unregister(struct devlink
*devlink
,
3219 struct devlink_resource
*resource
)
3221 struct devlink_resource
*tmp
, *child_resource
;
3222 struct list_head
*resource_list
;
3225 resource_list
= &resource
->resource_list
;
3227 resource_list
= &devlink
->resource_list
;
3230 mutex_lock(&devlink
->lock
);
3232 list_for_each_entry_safe(child_resource
, tmp
, resource_list
, list
) {
3233 devlink_resources_unregister(devlink
, child_resource
);
3234 list_del(&child_resource
->list
);
3235 kfree(child_resource
);
3239 mutex_unlock(&devlink
->lock
);
3241 EXPORT_SYMBOL_GPL(devlink_resources_unregister
);
3244 * devlink_resource_size_get - get and update size
3247 * @resource_id: the requested resource id
3248 * @p_resource_size: ptr to update
3250 int devlink_resource_size_get(struct devlink
*devlink
,
3252 u64
*p_resource_size
)
3254 struct devlink_resource
*resource
;
3257 mutex_lock(&devlink
->lock
);
3258 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
3263 *p_resource_size
= resource
->size_new
;
3264 resource
->size
= resource
->size_new
;
3266 mutex_unlock(&devlink
->lock
);
3269 EXPORT_SYMBOL_GPL(devlink_resource_size_get
);
3272 * devlink_dpipe_table_resource_set - set the resource id
3275 * @table_name: table name
3276 * @resource_id: resource id
3277 * @resource_units: number of resource's units consumed per table's entry
3279 int devlink_dpipe_table_resource_set(struct devlink
*devlink
,
3280 const char *table_name
, u64 resource_id
,
3283 struct devlink_dpipe_table
*table
;
3286 mutex_lock(&devlink
->lock
);
3287 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
3293 table
->resource_id
= resource_id
;
3294 table
->resource_units
= resource_units
;
3295 table
->resource_valid
= true;
3297 mutex_unlock(&devlink
->lock
);
3300 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set
);
3302 static int __init
devlink_module_init(void)
3304 return genl_register_family(&devlink_nl_family
);
3307 static void __exit
devlink_module_exit(void)
3309 genl_unregister_family(&devlink_nl_family
);
3312 module_init(devlink_module_init
);
3313 module_exit(devlink_module_exit
);
3315 MODULE_LICENSE("GPL v2");
3316 MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
3317 MODULE_DESCRIPTION("Network physical device Netlink interface");
3318 MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME
);