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 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
);
1703 if (devlink_dpipe_matches_put(table
, skb
))
1704 goto nla_put_failure
;
1706 if (devlink_dpipe_actions_put(table
, skb
))
1707 goto nla_put_failure
;
1709 nla_nest_end(skb
, table_attr
);
1713 nla_nest_cancel(skb
, table_attr
);
1717 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff
**pskb
,
1718 struct genl_info
*info
)
1723 err
= genlmsg_reply(*pskb
, info
);
1727 *pskb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1733 static int devlink_dpipe_tables_fill(struct genl_info
*info
,
1734 enum devlink_command cmd
, int flags
,
1735 struct list_head
*dpipe_tables
,
1736 const char *table_name
)
1738 struct devlink
*devlink
= info
->user_ptr
[0];
1739 struct devlink_dpipe_table
*table
;
1740 struct nlattr
*tables_attr
;
1741 struct sk_buff
*skb
= NULL
;
1742 struct nlmsghdr
*nlh
;
1748 table
= list_first_entry(dpipe_tables
,
1749 struct devlink_dpipe_table
, list
);
1751 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
1755 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
1756 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
1762 if (devlink_nl_put_handle(skb
, devlink
))
1763 goto nla_put_failure
;
1764 tables_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_TABLES
);
1766 goto nla_put_failure
;
1770 list_for_each_entry_from(table
, dpipe_tables
, list
) {
1772 err
= devlink_dpipe_table_put(skb
, table
);
1780 if (!strcmp(table
->name
, table_name
)) {
1781 err
= devlink_dpipe_table_put(skb
, table
);
1789 nla_nest_end(skb
, tables_attr
);
1790 genlmsg_end(skb
, hdr
);
1795 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
1796 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
1798 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
1800 goto err_skb_send_alloc
;
1804 return genlmsg_reply(skb
, info
);
1810 genlmsg_cancel(skb
, hdr
);
1815 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff
*skb
,
1816 struct genl_info
*info
)
1818 struct devlink
*devlink
= info
->user_ptr
[0];
1819 const char *table_name
= NULL
;
1821 if (info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
1822 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
1824 return devlink_dpipe_tables_fill(info
, DEVLINK_CMD_DPIPE_TABLE_GET
, 0,
1825 &devlink
->dpipe_table_list
,
1829 static int devlink_dpipe_value_put(struct sk_buff
*skb
,
1830 struct devlink_dpipe_value
*value
)
1832 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE
,
1833 value
->value_size
, value
->value
))
1836 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE_MASK
,
1837 value
->value_size
, value
->mask
))
1839 if (value
->mapping_valid
)
1840 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_VALUE_MAPPING
,
1841 value
->mapping_value
))
1846 static int devlink_dpipe_action_value_put(struct sk_buff
*skb
,
1847 struct devlink_dpipe_value
*value
)
1851 if (devlink_dpipe_action_put(skb
, value
->action
))
1853 if (devlink_dpipe_value_put(skb
, value
))
1858 static int devlink_dpipe_action_values_put(struct sk_buff
*skb
,
1859 struct devlink_dpipe_value
*values
,
1860 unsigned int values_count
)
1862 struct nlattr
*action_attr
;
1866 for (i
= 0; i
< values_count
; i
++) {
1867 action_attr
= nla_nest_start(skb
,
1868 DEVLINK_ATTR_DPIPE_ACTION_VALUE
);
1871 err
= devlink_dpipe_action_value_put(skb
, &values
[i
]);
1873 goto err_action_value_put
;
1874 nla_nest_end(skb
, action_attr
);
1878 err_action_value_put
:
1879 nla_nest_cancel(skb
, action_attr
);
1883 static int devlink_dpipe_match_value_put(struct sk_buff
*skb
,
1884 struct devlink_dpipe_value
*value
)
1888 if (devlink_dpipe_match_put(skb
, value
->match
))
1890 if (devlink_dpipe_value_put(skb
, value
))
1895 static int devlink_dpipe_match_values_put(struct sk_buff
*skb
,
1896 struct devlink_dpipe_value
*values
,
1897 unsigned int values_count
)
1899 struct nlattr
*match_attr
;
1903 for (i
= 0; i
< values_count
; i
++) {
1904 match_attr
= nla_nest_start(skb
,
1905 DEVLINK_ATTR_DPIPE_MATCH_VALUE
);
1908 err
= devlink_dpipe_match_value_put(skb
, &values
[i
]);
1910 goto err_match_value_put
;
1911 nla_nest_end(skb
, match_attr
);
1915 err_match_value_put
:
1916 nla_nest_cancel(skb
, match_attr
);
1920 static int devlink_dpipe_entry_put(struct sk_buff
*skb
,
1921 struct devlink_dpipe_entry
*entry
)
1923 struct nlattr
*entry_attr
, *matches_attr
, *actions_attr
;
1926 entry_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_ENTRY
);
1930 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_INDEX
, entry
->index
,
1932 goto nla_put_failure
;
1933 if (entry
->counter_valid
)
1934 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER
,
1935 entry
->counter
, DEVLINK_ATTR_PAD
))
1936 goto nla_put_failure
;
1938 matches_attr
= nla_nest_start(skb
,
1939 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES
);
1941 goto nla_put_failure
;
1943 err
= devlink_dpipe_match_values_put(skb
, entry
->match_values
,
1944 entry
->match_values_count
);
1946 nla_nest_cancel(skb
, matches_attr
);
1947 goto err_match_values_put
;
1949 nla_nest_end(skb
, matches_attr
);
1951 actions_attr
= nla_nest_start(skb
,
1952 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES
);
1954 goto nla_put_failure
;
1956 err
= devlink_dpipe_action_values_put(skb
, entry
->action_values
,
1957 entry
->action_values_count
);
1959 nla_nest_cancel(skb
, actions_attr
);
1960 goto err_action_values_put
;
1962 nla_nest_end(skb
, actions_attr
);
1964 nla_nest_end(skb
, entry_attr
);
1969 err_match_values_put
:
1970 err_action_values_put
:
1971 nla_nest_cancel(skb
, entry_attr
);
1975 static struct devlink_dpipe_table
*
1976 devlink_dpipe_table_find(struct list_head
*dpipe_tables
,
1977 const char *table_name
)
1979 struct devlink_dpipe_table
*table
;
1981 list_for_each_entry_rcu(table
, dpipe_tables
, list
) {
1982 if (!strcmp(table
->name
, table_name
))
1988 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx
*dump_ctx
)
1990 struct devlink
*devlink
;
1993 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
->skb
,
1998 dump_ctx
->hdr
= genlmsg_put(dump_ctx
->skb
,
1999 dump_ctx
->info
->snd_portid
,
2000 dump_ctx
->info
->snd_seq
,
2001 &devlink_nl_family
, NLM_F_MULTI
,
2004 goto nla_put_failure
;
2006 devlink
= dump_ctx
->info
->user_ptr
[0];
2007 if (devlink_nl_put_handle(dump_ctx
->skb
, devlink
))
2008 goto nla_put_failure
;
2009 dump_ctx
->nest
= nla_nest_start(dump_ctx
->skb
,
2010 DEVLINK_ATTR_DPIPE_ENTRIES
);
2011 if (!dump_ctx
->nest
)
2012 goto nla_put_failure
;
2016 genlmsg_cancel(dump_ctx
->skb
, dump_ctx
->hdr
);
2017 nlmsg_free(dump_ctx
->skb
);
2020 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare
);
2022 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx
*dump_ctx
,
2023 struct devlink_dpipe_entry
*entry
)
2025 return devlink_dpipe_entry_put(dump_ctx
->skb
, entry
);
2027 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append
);
2029 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx
*dump_ctx
)
2031 nla_nest_end(dump_ctx
->skb
, dump_ctx
->nest
);
2032 genlmsg_end(dump_ctx
->skb
, dump_ctx
->hdr
);
2035 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close
);
2037 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry
*entry
)
2040 unsigned int value_count
, value_index
;
2041 struct devlink_dpipe_value
*value
;
2043 value
= entry
->action_values
;
2044 value_count
= entry
->action_values_count
;
2045 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2046 kfree(value
[value_index
].value
);
2047 kfree(value
[value_index
].mask
);
2050 value
= entry
->match_values
;
2051 value_count
= entry
->match_values_count
;
2052 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2053 kfree(value
[value_index
].value
);
2054 kfree(value
[value_index
].mask
);
2057 EXPORT_SYMBOL(devlink_dpipe_entry_clear
);
2059 static int devlink_dpipe_entries_fill(struct genl_info
*info
,
2060 enum devlink_command cmd
, int flags
,
2061 struct devlink_dpipe_table
*table
)
2063 struct devlink_dpipe_dump_ctx dump_ctx
;
2064 struct nlmsghdr
*nlh
;
2067 dump_ctx
.skb
= NULL
;
2069 dump_ctx
.info
= info
;
2071 err
= table
->table_ops
->entries_dump(table
->priv
,
2072 table
->counters_enabled
,
2075 goto err_entries_dump
;
2078 nlh
= nlmsg_put(dump_ctx
.skb
, info
->snd_portid
, info
->snd_seq
,
2079 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2081 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
.skb
, info
);
2083 goto err_skb_send_alloc
;
2086 return genlmsg_reply(dump_ctx
.skb
, info
);
2090 genlmsg_cancel(dump_ctx
.skb
, dump_ctx
.hdr
);
2091 nlmsg_free(dump_ctx
.skb
);
2095 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff
*skb
,
2096 struct genl_info
*info
)
2098 struct devlink
*devlink
= info
->user_ptr
[0];
2099 struct devlink_dpipe_table
*table
;
2100 const char *table_name
;
2102 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
2105 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2106 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2111 if (!table
->table_ops
->entries_dump
)
2114 return devlink_dpipe_entries_fill(info
, DEVLINK_CMD_DPIPE_ENTRIES_GET
,
2118 static int devlink_dpipe_fields_put(struct sk_buff
*skb
,
2119 const struct devlink_dpipe_header
*header
)
2121 struct devlink_dpipe_field
*field
;
2122 struct nlattr
*field_attr
;
2125 for (i
= 0; i
< header
->fields_count
; i
++) {
2126 field
= &header
->fields
[i
];
2127 field_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_FIELD
);
2130 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_FIELD_NAME
, field
->name
) ||
2131 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
2132 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH
, field
->bitwidth
) ||
2133 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE
, field
->mapping_type
))
2134 goto nla_put_failure
;
2135 nla_nest_end(skb
, field_attr
);
2140 nla_nest_cancel(skb
, field_attr
);
2144 static int devlink_dpipe_header_put(struct sk_buff
*skb
,
2145 struct devlink_dpipe_header
*header
)
2147 struct nlattr
*fields_attr
, *header_attr
;
2150 header_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_HEADER
);
2154 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_HEADER_NAME
, header
->name
) ||
2155 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
2156 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
2157 goto nla_put_failure
;
2159 fields_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_HEADER_FIELDS
);
2161 goto nla_put_failure
;
2163 err
= devlink_dpipe_fields_put(skb
, header
);
2165 nla_nest_cancel(skb
, fields_attr
);
2166 goto nla_put_failure
;
2168 nla_nest_end(skb
, fields_attr
);
2169 nla_nest_end(skb
, header_attr
);
2174 nla_nest_cancel(skb
, header_attr
);
2178 static int devlink_dpipe_headers_fill(struct genl_info
*info
,
2179 enum devlink_command cmd
, int flags
,
2180 struct devlink_dpipe_headers
*
2183 struct devlink
*devlink
= info
->user_ptr
[0];
2184 struct nlattr
*headers_attr
;
2185 struct sk_buff
*skb
= NULL
;
2186 struct nlmsghdr
*nlh
;
2193 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2197 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2198 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2204 if (devlink_nl_put_handle(skb
, devlink
))
2205 goto nla_put_failure
;
2206 headers_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_HEADERS
);
2208 goto nla_put_failure
;
2211 for (; i
< dpipe_headers
->headers_count
; i
++) {
2212 err
= devlink_dpipe_header_put(skb
, dpipe_headers
->headers
[i
]);
2220 nla_nest_end(skb
, headers_attr
);
2221 genlmsg_end(skb
, hdr
);
2222 if (i
!= dpipe_headers
->headers_count
)
2226 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2227 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2229 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2231 goto err_skb_send_alloc
;
2234 return genlmsg_reply(skb
, info
);
2240 genlmsg_cancel(skb
, hdr
);
2245 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff
*skb
,
2246 struct genl_info
*info
)
2248 struct devlink
*devlink
= info
->user_ptr
[0];
2250 if (!devlink
->dpipe_headers
)
2252 return devlink_dpipe_headers_fill(info
, DEVLINK_CMD_DPIPE_HEADERS_GET
,
2253 0, devlink
->dpipe_headers
);
2256 static int devlink_dpipe_table_counters_set(struct devlink
*devlink
,
2257 const char *table_name
,
2260 struct devlink_dpipe_table
*table
;
2262 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2267 if (table
->counter_control_extern
)
2270 if (!(table
->counters_enabled
^ enable
))
2273 table
->counters_enabled
= enable
;
2274 if (table
->table_ops
->counters_set_update
)
2275 table
->table_ops
->counters_set_update(table
->priv
, enable
);
2279 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff
*skb
,
2280 struct genl_info
*info
)
2282 struct devlink
*devlink
= info
->user_ptr
[0];
2283 const char *table_name
;
2284 bool counters_enable
;
2286 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
] ||
2287 !info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
])
2290 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2291 counters_enable
= !!nla_get_u8(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
]);
2293 return devlink_dpipe_table_counters_set(devlink
, table_name
,
2297 static struct devlink_resource
*
2298 devlink_resource_find(struct devlink
*devlink
,
2299 struct devlink_resource
*resource
, u64 resource_id
)
2301 struct list_head
*resource_list
;
2304 resource_list
= &resource
->resource_list
;
2306 resource_list
= &devlink
->resource_list
;
2308 list_for_each_entry(resource
, resource_list
, list
) {
2309 struct devlink_resource
*child_resource
;
2311 if (resource
->id
== resource_id
)
2314 child_resource
= devlink_resource_find(devlink
, resource
,
2317 return child_resource
;
2323 devlink_resource_validate_children(struct devlink_resource
*resource
)
2325 struct devlink_resource
*child_resource
;
2326 bool size_valid
= true;
2329 if (list_empty(&resource
->resource_list
))
2332 list_for_each_entry(child_resource
, &resource
->resource_list
, list
)
2333 parts_size
+= child_resource
->size_new
;
2335 if (parts_size
> resource
->size
)
2338 resource
->size_valid
= size_valid
;
2341 static int devlink_nl_cmd_resource_set(struct sk_buff
*skb
,
2342 struct genl_info
*info
)
2344 struct devlink
*devlink
= info
->user_ptr
[0];
2345 struct devlink_resource
*resource
;
2350 if (!info
->attrs
[DEVLINK_ATTR_RESOURCE_ID
] ||
2351 !info
->attrs
[DEVLINK_ATTR_RESOURCE_SIZE
])
2353 resource_id
= nla_get_u64(info
->attrs
[DEVLINK_ATTR_RESOURCE_ID
]);
2355 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
2359 if (!resource
->resource_ops
->size_validate
)
2362 size
= nla_get_u64(info
->attrs
[DEVLINK_ATTR_RESOURCE_SIZE
]);
2363 err
= resource
->resource_ops
->size_validate(devlink
, size
,
2368 resource
->size_new
= size
;
2369 devlink_resource_validate_children(resource
);
2370 if (resource
->parent
)
2371 devlink_resource_validate_children(resource
->parent
);
2376 devlink_resource_size_params_put(struct devlink_resource
*resource
,
2377 struct sk_buff
*skb
)
2379 struct devlink_resource_size_params
*size_params
;
2381 size_params
= resource
->size_params
;
2382 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_GRAN
,
2383 size_params
->size_granularity
, DEVLINK_ATTR_PAD
);
2384 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_MAX
,
2385 size_params
->size_max
, DEVLINK_ATTR_PAD
);
2386 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_MIN
,
2387 size_params
->size_min
, DEVLINK_ATTR_PAD
);
2388 nla_put_u8(skb
, DEVLINK_ATTR_RESOURCE_UNIT
, size_params
->unit
);
2391 static int devlink_resource_put(struct devlink
*devlink
, struct sk_buff
*skb
,
2392 struct devlink_resource
*resource
)
2394 struct devlink_resource
*child_resource
;
2395 struct nlattr
*child_resource_attr
;
2396 struct nlattr
*resource_attr
;
2398 resource_attr
= nla_nest_start(skb
, DEVLINK_ATTR_RESOURCE
);
2402 if (nla_put_string(skb
, DEVLINK_ATTR_RESOURCE_NAME
, resource
->name
) ||
2403 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE
, resource
->size
,
2404 DEVLINK_ATTR_PAD
) ||
2405 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_ID
, resource
->id
,
2407 goto nla_put_failure
;
2408 if (resource
->size
!= resource
->size_new
)
2409 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_SIZE_NEW
,
2410 resource
->size_new
, DEVLINK_ATTR_PAD
);
2411 if (resource
->resource_ops
&& resource
->resource_ops
->occ_get
)
2412 nla_put_u64_64bit(skb
, DEVLINK_ATTR_RESOURCE_OCC
,
2413 resource
->resource_ops
->occ_get(devlink
),
2415 devlink_resource_size_params_put(resource
, skb
);
2416 if (list_empty(&resource
->resource_list
))
2419 if (nla_put_u8(skb
, DEVLINK_ATTR_RESOURCE_SIZE_VALID
,
2420 resource
->size_valid
))
2421 goto nla_put_failure
;
2423 child_resource_attr
= nla_nest_start(skb
, DEVLINK_ATTR_RESOURCE_LIST
);
2424 if (!child_resource_attr
)
2425 goto nla_put_failure
;
2427 list_for_each_entry(child_resource
, &resource
->resource_list
, list
) {
2428 if (devlink_resource_put(devlink
, skb
, child_resource
))
2429 goto resource_put_failure
;
2432 nla_nest_end(skb
, child_resource_attr
);
2434 nla_nest_end(skb
, resource_attr
);
2437 resource_put_failure
:
2438 nla_nest_cancel(skb
, child_resource_attr
);
2440 nla_nest_cancel(skb
, resource_attr
);
2444 static int devlink_resource_fill(struct genl_info
*info
,
2445 enum devlink_command cmd
, int flags
)
2447 struct devlink
*devlink
= info
->user_ptr
[0];
2448 struct devlink_resource
*resource
;
2449 struct nlattr
*resources_attr
;
2450 struct sk_buff
*skb
= NULL
;
2451 struct nlmsghdr
*nlh
;
2457 resource
= list_first_entry(&devlink
->resource_list
,
2458 struct devlink_resource
, list
);
2460 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2464 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2465 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2471 if (devlink_nl_put_handle(skb
, devlink
))
2472 goto nla_put_failure
;
2474 resources_attr
= nla_nest_start(skb
, DEVLINK_ATTR_RESOURCE_LIST
);
2475 if (!resources_attr
)
2476 goto nla_put_failure
;
2480 list_for_each_entry_from(resource
, &devlink
->resource_list
, list
) {
2481 err
= devlink_resource_put(devlink
, skb
, resource
);
2484 goto err_resource_put
;
2490 nla_nest_end(skb
, resources_attr
);
2491 genlmsg_end(skb
, hdr
);
2495 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2496 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2498 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2500 goto err_skb_send_alloc
;
2503 return genlmsg_reply(skb
, info
);
2509 genlmsg_cancel(skb
, hdr
);
2514 static int devlink_nl_cmd_resource_dump(struct sk_buff
*skb
,
2515 struct genl_info
*info
)
2517 struct devlink
*devlink
= info
->user_ptr
[0];
2519 if (list_empty(&devlink
->resource_list
))
2522 return devlink_resource_fill(info
, DEVLINK_CMD_RESOURCE_DUMP
, 0);
2526 devlink_resources_validate(struct devlink
*devlink
,
2527 struct devlink_resource
*resource
,
2528 struct genl_info
*info
)
2530 struct list_head
*resource_list
;
2534 resource_list
= &resource
->resource_list
;
2536 resource_list
= &devlink
->resource_list
;
2538 list_for_each_entry(resource
, resource_list
, list
) {
2539 if (!resource
->size_valid
)
2541 err
= devlink_resources_validate(devlink
, resource
, info
);
2548 static int devlink_nl_cmd_reload(struct sk_buff
*skb
, struct genl_info
*info
)
2550 struct devlink
*devlink
= info
->user_ptr
[0];
2553 if (!devlink
->ops
->reload
)
2556 err
= devlink_resources_validate(devlink
, NULL
, info
);
2558 NL_SET_ERR_MSG_MOD(info
->extack
, "resources size validation failed");
2561 return devlink
->ops
->reload(devlink
);
2564 static const struct nla_policy devlink_nl_policy
[DEVLINK_ATTR_MAX
+ 1] = {
2565 [DEVLINK_ATTR_BUS_NAME
] = { .type
= NLA_NUL_STRING
},
2566 [DEVLINK_ATTR_DEV_NAME
] = { .type
= NLA_NUL_STRING
},
2567 [DEVLINK_ATTR_PORT_INDEX
] = { .type
= NLA_U32
},
2568 [DEVLINK_ATTR_PORT_TYPE
] = { .type
= NLA_U16
},
2569 [DEVLINK_ATTR_PORT_SPLIT_COUNT
] = { .type
= NLA_U32
},
2570 [DEVLINK_ATTR_SB_INDEX
] = { .type
= NLA_U32
},
2571 [DEVLINK_ATTR_SB_POOL_INDEX
] = { .type
= NLA_U16
},
2572 [DEVLINK_ATTR_SB_POOL_TYPE
] = { .type
= NLA_U8
},
2573 [DEVLINK_ATTR_SB_POOL_SIZE
] = { .type
= NLA_U32
},
2574 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
] = { .type
= NLA_U8
},
2575 [DEVLINK_ATTR_SB_THRESHOLD
] = { .type
= NLA_U32
},
2576 [DEVLINK_ATTR_SB_TC_INDEX
] = { .type
= NLA_U16
},
2577 [DEVLINK_ATTR_ESWITCH_MODE
] = { .type
= NLA_U16
},
2578 [DEVLINK_ATTR_ESWITCH_INLINE_MODE
] = { .type
= NLA_U8
},
2579 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE
] = { .type
= NLA_U8
},
2580 [DEVLINK_ATTR_DPIPE_TABLE_NAME
] = { .type
= NLA_NUL_STRING
},
2581 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
] = { .type
= NLA_U8
},
2582 [DEVLINK_ATTR_RESOURCE_ID
] = { .type
= NLA_U64
},
2583 [DEVLINK_ATTR_RESOURCE_SIZE
] = { .type
= NLA_U64
},
2586 static const struct genl_ops devlink_nl_ops
[] = {
2588 .cmd
= DEVLINK_CMD_GET
,
2589 .doit
= devlink_nl_cmd_get_doit
,
2590 .dumpit
= devlink_nl_cmd_get_dumpit
,
2591 .policy
= devlink_nl_policy
,
2592 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2593 /* can be retrieved by unprivileged users */
2596 .cmd
= DEVLINK_CMD_PORT_GET
,
2597 .doit
= devlink_nl_cmd_port_get_doit
,
2598 .dumpit
= devlink_nl_cmd_port_get_dumpit
,
2599 .policy
= devlink_nl_policy
,
2600 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
2601 /* can be retrieved by unprivileged users */
2604 .cmd
= DEVLINK_CMD_PORT_SET
,
2605 .doit
= devlink_nl_cmd_port_set_doit
,
2606 .policy
= devlink_nl_policy
,
2607 .flags
= GENL_ADMIN_PERM
,
2608 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
2611 .cmd
= DEVLINK_CMD_PORT_SPLIT
,
2612 .doit
= devlink_nl_cmd_port_split_doit
,
2613 .policy
= devlink_nl_policy
,
2614 .flags
= GENL_ADMIN_PERM
,
2615 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2616 DEVLINK_NL_FLAG_NO_LOCK
,
2619 .cmd
= DEVLINK_CMD_PORT_UNSPLIT
,
2620 .doit
= devlink_nl_cmd_port_unsplit_doit
,
2621 .policy
= devlink_nl_policy
,
2622 .flags
= GENL_ADMIN_PERM
,
2623 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2624 DEVLINK_NL_FLAG_NO_LOCK
,
2627 .cmd
= DEVLINK_CMD_SB_GET
,
2628 .doit
= devlink_nl_cmd_sb_get_doit
,
2629 .dumpit
= devlink_nl_cmd_sb_get_dumpit
,
2630 .policy
= devlink_nl_policy
,
2631 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2632 DEVLINK_NL_FLAG_NEED_SB
,
2633 /* can be retrieved by unprivileged users */
2636 .cmd
= DEVLINK_CMD_SB_POOL_GET
,
2637 .doit
= devlink_nl_cmd_sb_pool_get_doit
,
2638 .dumpit
= devlink_nl_cmd_sb_pool_get_dumpit
,
2639 .policy
= devlink_nl_policy
,
2640 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2641 DEVLINK_NL_FLAG_NEED_SB
,
2642 /* can be retrieved by unprivileged users */
2645 .cmd
= DEVLINK_CMD_SB_POOL_SET
,
2646 .doit
= devlink_nl_cmd_sb_pool_set_doit
,
2647 .policy
= devlink_nl_policy
,
2648 .flags
= GENL_ADMIN_PERM
,
2649 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2650 DEVLINK_NL_FLAG_NEED_SB
,
2653 .cmd
= DEVLINK_CMD_SB_PORT_POOL_GET
,
2654 .doit
= devlink_nl_cmd_sb_port_pool_get_doit
,
2655 .dumpit
= devlink_nl_cmd_sb_port_pool_get_dumpit
,
2656 .policy
= devlink_nl_policy
,
2657 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
2658 DEVLINK_NL_FLAG_NEED_SB
,
2659 /* can be retrieved by unprivileged users */
2662 .cmd
= DEVLINK_CMD_SB_PORT_POOL_SET
,
2663 .doit
= devlink_nl_cmd_sb_port_pool_set_doit
,
2664 .policy
= devlink_nl_policy
,
2665 .flags
= GENL_ADMIN_PERM
,
2666 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
2667 DEVLINK_NL_FLAG_NEED_SB
,
2670 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_GET
,
2671 .doit
= devlink_nl_cmd_sb_tc_pool_bind_get_doit
,
2672 .dumpit
= devlink_nl_cmd_sb_tc_pool_bind_get_dumpit
,
2673 .policy
= devlink_nl_policy
,
2674 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
2675 DEVLINK_NL_FLAG_NEED_SB
,
2676 /* can be retrieved by unprivileged users */
2679 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_SET
,
2680 .doit
= devlink_nl_cmd_sb_tc_pool_bind_set_doit
,
2681 .policy
= devlink_nl_policy
,
2682 .flags
= GENL_ADMIN_PERM
,
2683 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
2684 DEVLINK_NL_FLAG_NEED_SB
,
2687 .cmd
= DEVLINK_CMD_SB_OCC_SNAPSHOT
,
2688 .doit
= devlink_nl_cmd_sb_occ_snapshot_doit
,
2689 .policy
= devlink_nl_policy
,
2690 .flags
= GENL_ADMIN_PERM
,
2691 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2692 DEVLINK_NL_FLAG_NEED_SB
,
2695 .cmd
= DEVLINK_CMD_SB_OCC_MAX_CLEAR
,
2696 .doit
= devlink_nl_cmd_sb_occ_max_clear_doit
,
2697 .policy
= devlink_nl_policy
,
2698 .flags
= GENL_ADMIN_PERM
,
2699 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2700 DEVLINK_NL_FLAG_NEED_SB
,
2703 .cmd
= DEVLINK_CMD_ESWITCH_GET
,
2704 .doit
= devlink_nl_cmd_eswitch_get_doit
,
2705 .policy
= devlink_nl_policy
,
2706 .flags
= GENL_ADMIN_PERM
,
2707 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2710 .cmd
= DEVLINK_CMD_ESWITCH_SET
,
2711 .doit
= devlink_nl_cmd_eswitch_set_doit
,
2712 .policy
= devlink_nl_policy
,
2713 .flags
= GENL_ADMIN_PERM
,
2714 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2717 .cmd
= DEVLINK_CMD_DPIPE_TABLE_GET
,
2718 .doit
= devlink_nl_cmd_dpipe_table_get
,
2719 .policy
= devlink_nl_policy
,
2720 .flags
= GENL_ADMIN_PERM
,
2721 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2724 .cmd
= DEVLINK_CMD_DPIPE_ENTRIES_GET
,
2725 .doit
= devlink_nl_cmd_dpipe_entries_get
,
2726 .policy
= devlink_nl_policy
,
2727 .flags
= GENL_ADMIN_PERM
,
2728 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2731 .cmd
= DEVLINK_CMD_DPIPE_HEADERS_GET
,
2732 .doit
= devlink_nl_cmd_dpipe_headers_get
,
2733 .policy
= devlink_nl_policy
,
2734 .flags
= GENL_ADMIN_PERM
,
2735 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2738 .cmd
= DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET
,
2739 .doit
= devlink_nl_cmd_dpipe_table_counters_set
,
2740 .policy
= devlink_nl_policy
,
2741 .flags
= GENL_ADMIN_PERM
,
2742 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2745 .cmd
= DEVLINK_CMD_RESOURCE_SET
,
2746 .doit
= devlink_nl_cmd_resource_set
,
2747 .policy
= devlink_nl_policy
,
2748 .flags
= GENL_ADMIN_PERM
,
2749 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2752 .cmd
= DEVLINK_CMD_RESOURCE_DUMP
,
2753 .doit
= devlink_nl_cmd_resource_dump
,
2754 .policy
= devlink_nl_policy
,
2755 .flags
= GENL_ADMIN_PERM
,
2756 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2759 .cmd
= DEVLINK_CMD_RELOAD
,
2760 .doit
= devlink_nl_cmd_reload
,
2761 .policy
= devlink_nl_policy
,
2762 .flags
= GENL_ADMIN_PERM
,
2763 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2764 DEVLINK_NL_FLAG_NO_LOCK
,
2768 static struct genl_family devlink_nl_family __ro_after_init
= {
2769 .name
= DEVLINK_GENL_NAME
,
2770 .version
= DEVLINK_GENL_VERSION
,
2771 .maxattr
= DEVLINK_ATTR_MAX
,
2773 .pre_doit
= devlink_nl_pre_doit
,
2774 .post_doit
= devlink_nl_post_doit
,
2775 .module
= THIS_MODULE
,
2776 .ops
= devlink_nl_ops
,
2777 .n_ops
= ARRAY_SIZE(devlink_nl_ops
),
2778 .mcgrps
= devlink_nl_mcgrps
,
2779 .n_mcgrps
= ARRAY_SIZE(devlink_nl_mcgrps
),
2783 * devlink_alloc - Allocate new devlink instance resources
2786 * @priv_size: size of user private data
2788 * Allocate new devlink instance resources, including devlink index
2791 struct devlink
*devlink_alloc(const struct devlink_ops
*ops
, size_t priv_size
)
2793 struct devlink
*devlink
;
2795 devlink
= kzalloc(sizeof(*devlink
) + priv_size
, GFP_KERNEL
);
2799 devlink_net_set(devlink
, &init_net
);
2800 INIT_LIST_HEAD(&devlink
->port_list
);
2801 INIT_LIST_HEAD(&devlink
->sb_list
);
2802 INIT_LIST_HEAD_RCU(&devlink
->dpipe_table_list
);
2803 INIT_LIST_HEAD(&devlink
->resource_list
);
2804 mutex_init(&devlink
->lock
);
2807 EXPORT_SYMBOL_GPL(devlink_alloc
);
2810 * devlink_register - Register devlink instance
2814 int devlink_register(struct devlink
*devlink
, struct device
*dev
)
2816 mutex_lock(&devlink_mutex
);
2818 list_add_tail(&devlink
->list
, &devlink_list
);
2819 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
2820 mutex_unlock(&devlink_mutex
);
2823 EXPORT_SYMBOL_GPL(devlink_register
);
2826 * devlink_unregister - Unregister devlink instance
2830 void devlink_unregister(struct devlink
*devlink
)
2832 mutex_lock(&devlink_mutex
);
2833 devlink_notify(devlink
, DEVLINK_CMD_DEL
);
2834 list_del(&devlink
->list
);
2835 mutex_unlock(&devlink_mutex
);
2837 EXPORT_SYMBOL_GPL(devlink_unregister
);
2840 * devlink_free - Free devlink instance resources
2844 void devlink_free(struct devlink
*devlink
)
2848 EXPORT_SYMBOL_GPL(devlink_free
);
2851 * devlink_port_register - Register devlink port
2854 * @devlink_port: devlink port
2857 * Register devlink port with provided port index. User can use
2858 * any indexing, even hw-related one. devlink_port structure
2859 * is convenient to be embedded inside user driver private structure.
2860 * Note that the caller should take care of zeroing the devlink_port
2863 int devlink_port_register(struct devlink
*devlink
,
2864 struct devlink_port
*devlink_port
,
2865 unsigned int port_index
)
2867 mutex_lock(&devlink
->lock
);
2868 if (devlink_port_index_exists(devlink
, port_index
)) {
2869 mutex_unlock(&devlink
->lock
);
2872 devlink_port
->devlink
= devlink
;
2873 devlink_port
->index
= port_index
;
2874 devlink_port
->registered
= true;
2875 list_add_tail(&devlink_port
->list
, &devlink
->port_list
);
2876 mutex_unlock(&devlink
->lock
);
2877 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
2880 EXPORT_SYMBOL_GPL(devlink_port_register
);
2883 * devlink_port_unregister - Unregister devlink port
2885 * @devlink_port: devlink port
2887 void devlink_port_unregister(struct devlink_port
*devlink_port
)
2889 struct devlink
*devlink
= devlink_port
->devlink
;
2891 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_DEL
);
2892 mutex_lock(&devlink
->lock
);
2893 list_del(&devlink_port
->list
);
2894 mutex_unlock(&devlink
->lock
);
2896 EXPORT_SYMBOL_GPL(devlink_port_unregister
);
2898 static void __devlink_port_type_set(struct devlink_port
*devlink_port
,
2899 enum devlink_port_type type
,
2902 devlink_port
->type
= type
;
2903 devlink_port
->type_dev
= type_dev
;
2904 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
2908 * devlink_port_type_eth_set - Set port type to Ethernet
2910 * @devlink_port: devlink port
2911 * @netdev: related netdevice
2913 void devlink_port_type_eth_set(struct devlink_port
*devlink_port
,
2914 struct net_device
*netdev
)
2916 return __devlink_port_type_set(devlink_port
,
2917 DEVLINK_PORT_TYPE_ETH
, netdev
);
2919 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set
);
2922 * devlink_port_type_ib_set - Set port type to InfiniBand
2924 * @devlink_port: devlink port
2925 * @ibdev: related IB device
2927 void devlink_port_type_ib_set(struct devlink_port
*devlink_port
,
2928 struct ib_device
*ibdev
)
2930 return __devlink_port_type_set(devlink_port
,
2931 DEVLINK_PORT_TYPE_IB
, ibdev
);
2933 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set
);
2936 * devlink_port_type_clear - Clear port type
2938 * @devlink_port: devlink port
2940 void devlink_port_type_clear(struct devlink_port
*devlink_port
)
2942 return __devlink_port_type_set(devlink_port
,
2943 DEVLINK_PORT_TYPE_NOTSET
, NULL
);
2945 EXPORT_SYMBOL_GPL(devlink_port_type_clear
);
2948 * devlink_port_split_set - Set port is split
2950 * @devlink_port: devlink port
2951 * @split_group: split group - identifies group split port is part of
2953 void devlink_port_split_set(struct devlink_port
*devlink_port
,
2956 devlink_port
->split
= true;
2957 devlink_port
->split_group
= split_group
;
2958 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
2960 EXPORT_SYMBOL_GPL(devlink_port_split_set
);
2962 int devlink_sb_register(struct devlink
*devlink
, unsigned int sb_index
,
2963 u32 size
, u16 ingress_pools_count
,
2964 u16 egress_pools_count
, u16 ingress_tc_count
,
2965 u16 egress_tc_count
)
2967 struct devlink_sb
*devlink_sb
;
2970 mutex_lock(&devlink
->lock
);
2971 if (devlink_sb_index_exists(devlink
, sb_index
)) {
2976 devlink_sb
= kzalloc(sizeof(*devlink_sb
), GFP_KERNEL
);
2981 devlink_sb
->index
= sb_index
;
2982 devlink_sb
->size
= size
;
2983 devlink_sb
->ingress_pools_count
= ingress_pools_count
;
2984 devlink_sb
->egress_pools_count
= egress_pools_count
;
2985 devlink_sb
->ingress_tc_count
= ingress_tc_count
;
2986 devlink_sb
->egress_tc_count
= egress_tc_count
;
2987 list_add_tail(&devlink_sb
->list
, &devlink
->sb_list
);
2989 mutex_unlock(&devlink
->lock
);
2992 EXPORT_SYMBOL_GPL(devlink_sb_register
);
2994 void devlink_sb_unregister(struct devlink
*devlink
, unsigned int sb_index
)
2996 struct devlink_sb
*devlink_sb
;
2998 mutex_lock(&devlink
->lock
);
2999 devlink_sb
= devlink_sb_get_by_index(devlink
, sb_index
);
3000 WARN_ON(!devlink_sb
);
3001 list_del(&devlink_sb
->list
);
3002 mutex_unlock(&devlink
->lock
);
3005 EXPORT_SYMBOL_GPL(devlink_sb_unregister
);
3008 * devlink_dpipe_headers_register - register dpipe headers
3011 * @dpipe_headers: dpipe header array
3013 * Register the headers supported by hardware.
3015 int devlink_dpipe_headers_register(struct devlink
*devlink
,
3016 struct devlink_dpipe_headers
*dpipe_headers
)
3018 mutex_lock(&devlink
->lock
);
3019 devlink
->dpipe_headers
= dpipe_headers
;
3020 mutex_unlock(&devlink
->lock
);
3023 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register
);
3026 * devlink_dpipe_headers_unregister - unregister dpipe headers
3030 * Unregister the headers supported by hardware.
3032 void devlink_dpipe_headers_unregister(struct devlink
*devlink
)
3034 mutex_lock(&devlink
->lock
);
3035 devlink
->dpipe_headers
= NULL
;
3036 mutex_unlock(&devlink
->lock
);
3038 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister
);
3041 * devlink_dpipe_table_counter_enabled - check if counter allocation
3044 * @table_name: tables name
3046 * Used by driver to check if counter allocation is required.
3047 * After counter allocation is turned on the table entries
3048 * are updated to include counter statistics.
3050 * After that point on the driver must respect the counter
3051 * state so that each entry added to the table is added
3054 bool devlink_dpipe_table_counter_enabled(struct devlink
*devlink
,
3055 const char *table_name
)
3057 struct devlink_dpipe_table
*table
;
3061 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
3065 enabled
= table
->counters_enabled
;
3069 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled
);
3072 * devlink_dpipe_table_register - register dpipe table
3075 * @table_name: table name
3076 * @table_ops: table ops
3078 * @counter_control_extern: external control for counters
3080 int devlink_dpipe_table_register(struct devlink
*devlink
,
3081 const char *table_name
,
3082 struct devlink_dpipe_table_ops
*table_ops
,
3083 void *priv
, bool counter_control_extern
)
3085 struct devlink_dpipe_table
*table
;
3087 if (devlink_dpipe_table_find(&devlink
->dpipe_table_list
, table_name
))
3090 if (WARN_ON(!table_ops
->size_get
))
3093 table
= kzalloc(sizeof(*table
), GFP_KERNEL
);
3097 table
->name
= table_name
;
3098 table
->table_ops
= table_ops
;
3100 table
->counter_control_extern
= counter_control_extern
;
3102 mutex_lock(&devlink
->lock
);
3103 list_add_tail_rcu(&table
->list
, &devlink
->dpipe_table_list
);
3104 mutex_unlock(&devlink
->lock
);
3107 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register
);
3110 * devlink_dpipe_table_unregister - unregister dpipe table
3113 * @table_name: table name
3115 void devlink_dpipe_table_unregister(struct devlink
*devlink
,
3116 const char *table_name
)
3118 struct devlink_dpipe_table
*table
;
3120 mutex_lock(&devlink
->lock
);
3121 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
3125 list_del_rcu(&table
->list
);
3126 mutex_unlock(&devlink
->lock
);
3127 kfree_rcu(table
, rcu
);
3130 mutex_unlock(&devlink
->lock
);
3132 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister
);
3135 * devlink_resource_register - devlink resource register
3138 * @resource_name: resource's name
3139 * @top_hierarchy: top hierarchy
3140 * @reload_required: reload is required for new configuration to
3142 * @resource_size: resource's size
3143 * @resource_id: resource's id
3144 * @parent_reosurce_id: resource's parent id
3145 * @size params: size parameters
3146 * @resource_ops: resource ops
3148 int devlink_resource_register(struct devlink
*devlink
,
3149 const char *resource_name
,
3153 u64 parent_resource_id
,
3154 struct devlink_resource_size_params
*size_params
,
3155 const struct devlink_resource_ops
*resource_ops
)
3157 struct devlink_resource
*resource
;
3158 struct list_head
*resource_list
;
3161 mutex_lock(&devlink
->lock
);
3162 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
3168 resource
= kzalloc(sizeof(*resource
), GFP_KERNEL
);
3174 if (top_hierarchy
) {
3175 resource_list
= &devlink
->resource_list
;
3177 struct devlink_resource
*parent_resource
;
3179 parent_resource
= devlink_resource_find(devlink
, NULL
,
3180 parent_resource_id
);
3181 if (parent_resource
) {
3182 resource_list
= &parent_resource
->resource_list
;
3183 resource
->parent
= parent_resource
;
3191 resource
->name
= resource_name
;
3192 resource
->size
= resource_size
;
3193 resource
->size_new
= resource_size
;
3194 resource
->id
= resource_id
;
3195 resource
->resource_ops
= resource_ops
;
3196 resource
->size_valid
= true;
3197 resource
->size_params
= size_params
;
3198 INIT_LIST_HEAD(&resource
->resource_list
);
3199 list_add_tail(&resource
->list
, resource_list
);
3201 mutex_unlock(&devlink
->lock
);
3204 EXPORT_SYMBOL_GPL(devlink_resource_register
);
3207 * devlink_resources_unregister - free all resources
3210 * @resource: resource
3212 void devlink_resources_unregister(struct devlink
*devlink
,
3213 struct devlink_resource
*resource
)
3215 struct devlink_resource
*tmp
, *child_resource
;
3216 struct list_head
*resource_list
;
3219 resource_list
= &resource
->resource_list
;
3221 resource_list
= &devlink
->resource_list
;
3224 mutex_lock(&devlink
->lock
);
3226 list_for_each_entry_safe(child_resource
, tmp
, resource_list
, list
) {
3227 devlink_resources_unregister(devlink
, child_resource
);
3228 list_del(&child_resource
->list
);
3229 kfree(child_resource
);
3233 mutex_unlock(&devlink
->lock
);
3235 EXPORT_SYMBOL_GPL(devlink_resources_unregister
);
3238 * devlink_resource_size_get - get and update size
3241 * @resource_id: the requested resource id
3242 * @p_resource_size: ptr to update
3244 int devlink_resource_size_get(struct devlink
*devlink
,
3246 u64
*p_resource_size
)
3248 struct devlink_resource
*resource
;
3251 mutex_lock(&devlink
->lock
);
3252 resource
= devlink_resource_find(devlink
, NULL
, resource_id
);
3257 *p_resource_size
= resource
->size_new
;
3258 resource
->size
= resource
->size_new
;
3260 mutex_unlock(&devlink
->lock
);
3263 EXPORT_SYMBOL_GPL(devlink_resource_size_get
);
3266 * devlink_dpipe_table_resource_set - set the resource id
3269 * @table_name: table name
3270 * @resource_id: resource id
3271 * @resource_units: number of resource's units consumed per table's entry
3273 int devlink_dpipe_table_resource_set(struct devlink
*devlink
,
3274 const char *table_name
, u64 resource_id
,
3277 struct devlink_dpipe_table
*table
;
3280 mutex_lock(&devlink
->lock
);
3281 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
3287 table
->resource_id
= resource_id
;
3288 table
->resource_units
= resource_units
;
3289 table
->resource_valid
= true;
3291 mutex_unlock(&devlink
->lock
);
3294 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set
);
3296 static int __init
devlink_module_init(void)
3298 return genl_register_family(&devlink_nl_family
);
3301 static void __exit
devlink_module_exit(void)
3303 genl_unregister_family(&devlink_nl_family
);
3306 module_init(devlink_module_init
);
3307 module_exit(devlink_module_exit
);
3309 MODULE_LICENSE("GPL v2");
3310 MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
3311 MODULE_DESCRIPTION("Network physical device Netlink interface");
3312 MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME
);