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 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg
);
68 static LIST_HEAD(devlink_list
);
72 * An overall lock guarding every operation coming from userspace.
73 * It also guards devlink devices list and it is taken when
74 * driver registers/unregisters it.
76 static DEFINE_MUTEX(devlink_mutex
);
80 * Shared lock to guard lists of ports in all devlink devices.
82 static DEFINE_MUTEX(devlink_port_mutex
);
84 static struct net
*devlink_net(const struct devlink
*devlink
)
86 return read_pnet(&devlink
->_net
);
89 static void devlink_net_set(struct devlink
*devlink
, struct net
*net
)
91 write_pnet(&devlink
->_net
, net
);
94 static struct devlink
*devlink_get_from_attrs(struct net
*net
,
95 struct nlattr
**attrs
)
97 struct devlink
*devlink
;
101 if (!attrs
[DEVLINK_ATTR_BUS_NAME
] || !attrs
[DEVLINK_ATTR_DEV_NAME
])
102 return ERR_PTR(-EINVAL
);
104 busname
= nla_data(attrs
[DEVLINK_ATTR_BUS_NAME
]);
105 devname
= nla_data(attrs
[DEVLINK_ATTR_DEV_NAME
]);
107 list_for_each_entry(devlink
, &devlink_list
, list
) {
108 if (strcmp(devlink
->dev
->bus
->name
, busname
) == 0 &&
109 strcmp(dev_name(devlink
->dev
), devname
) == 0 &&
110 net_eq(devlink_net(devlink
), net
))
114 return ERR_PTR(-ENODEV
);
117 static struct devlink
*devlink_get_from_info(struct genl_info
*info
)
119 return devlink_get_from_attrs(genl_info_net(info
), info
->attrs
);
122 static struct devlink_port
*devlink_port_get_by_index(struct devlink
*devlink
,
125 struct devlink_port
*devlink_port
;
127 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
128 if (devlink_port
->index
== port_index
)
134 static bool devlink_port_index_exists(struct devlink
*devlink
, int port_index
)
136 return devlink_port_get_by_index(devlink
, port_index
);
139 static struct devlink_port
*devlink_port_get_from_attrs(struct devlink
*devlink
,
140 struct nlattr
**attrs
)
142 if (attrs
[DEVLINK_ATTR_PORT_INDEX
]) {
143 u32 port_index
= nla_get_u32(attrs
[DEVLINK_ATTR_PORT_INDEX
]);
144 struct devlink_port
*devlink_port
;
146 devlink_port
= devlink_port_get_by_index(devlink
, port_index
);
148 return ERR_PTR(-ENODEV
);
151 return ERR_PTR(-EINVAL
);
154 static struct devlink_port
*devlink_port_get_from_info(struct devlink
*devlink
,
155 struct genl_info
*info
)
157 return devlink_port_get_from_attrs(devlink
, info
->attrs
);
161 struct list_head list
;
164 u16 ingress_pools_count
;
165 u16 egress_pools_count
;
166 u16 ingress_tc_count
;
170 static u16
devlink_sb_pool_count(struct devlink_sb
*devlink_sb
)
172 return devlink_sb
->ingress_pools_count
+ devlink_sb
->egress_pools_count
;
175 static struct devlink_sb
*devlink_sb_get_by_index(struct devlink
*devlink
,
176 unsigned int sb_index
)
178 struct devlink_sb
*devlink_sb
;
180 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
181 if (devlink_sb
->index
== sb_index
)
187 static bool devlink_sb_index_exists(struct devlink
*devlink
,
188 unsigned int sb_index
)
190 return devlink_sb_get_by_index(devlink
, sb_index
);
193 static struct devlink_sb
*devlink_sb_get_from_attrs(struct devlink
*devlink
,
194 struct nlattr
**attrs
)
196 if (attrs
[DEVLINK_ATTR_SB_INDEX
]) {
197 u32 sb_index
= nla_get_u32(attrs
[DEVLINK_ATTR_SB_INDEX
]);
198 struct devlink_sb
*devlink_sb
;
200 devlink_sb
= devlink_sb_get_by_index(devlink
, sb_index
);
202 return ERR_PTR(-ENODEV
);
205 return ERR_PTR(-EINVAL
);
208 static struct devlink_sb
*devlink_sb_get_from_info(struct devlink
*devlink
,
209 struct genl_info
*info
)
211 return devlink_sb_get_from_attrs(devlink
, info
->attrs
);
214 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb
*devlink_sb
,
215 struct nlattr
**attrs
,
220 if (!attrs
[DEVLINK_ATTR_SB_POOL_INDEX
])
223 val
= nla_get_u16(attrs
[DEVLINK_ATTR_SB_POOL_INDEX
]);
224 if (val
>= devlink_sb_pool_count(devlink_sb
))
230 static int devlink_sb_pool_index_get_from_info(struct devlink_sb
*devlink_sb
,
231 struct genl_info
*info
,
234 return devlink_sb_pool_index_get_from_attrs(devlink_sb
, info
->attrs
,
239 devlink_sb_pool_type_get_from_attrs(struct nlattr
**attrs
,
240 enum devlink_sb_pool_type
*p_pool_type
)
244 if (!attrs
[DEVLINK_ATTR_SB_POOL_TYPE
])
247 val
= nla_get_u8(attrs
[DEVLINK_ATTR_SB_POOL_TYPE
]);
248 if (val
!= DEVLINK_SB_POOL_TYPE_INGRESS
&&
249 val
!= DEVLINK_SB_POOL_TYPE_EGRESS
)
256 devlink_sb_pool_type_get_from_info(struct genl_info
*info
,
257 enum devlink_sb_pool_type
*p_pool_type
)
259 return devlink_sb_pool_type_get_from_attrs(info
->attrs
, p_pool_type
);
263 devlink_sb_th_type_get_from_attrs(struct nlattr
**attrs
,
264 enum devlink_sb_threshold_type
*p_th_type
)
268 if (!attrs
[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
])
271 val
= nla_get_u8(attrs
[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
]);
272 if (val
!= DEVLINK_SB_THRESHOLD_TYPE_STATIC
&&
273 val
!= DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC
)
280 devlink_sb_th_type_get_from_info(struct genl_info
*info
,
281 enum devlink_sb_threshold_type
*p_th_type
)
283 return devlink_sb_th_type_get_from_attrs(info
->attrs
, p_th_type
);
287 devlink_sb_tc_index_get_from_attrs(struct devlink_sb
*devlink_sb
,
288 struct nlattr
**attrs
,
289 enum devlink_sb_pool_type pool_type
,
294 if (!attrs
[DEVLINK_ATTR_SB_TC_INDEX
])
297 val
= nla_get_u16(attrs
[DEVLINK_ATTR_SB_TC_INDEX
]);
298 if (pool_type
== DEVLINK_SB_POOL_TYPE_INGRESS
&&
299 val
>= devlink_sb
->ingress_tc_count
)
301 if (pool_type
== DEVLINK_SB_POOL_TYPE_EGRESS
&&
302 val
>= devlink_sb
->egress_tc_count
)
309 devlink_sb_tc_index_get_from_info(struct devlink_sb
*devlink_sb
,
310 struct genl_info
*info
,
311 enum devlink_sb_pool_type pool_type
,
314 return devlink_sb_tc_index_get_from_attrs(devlink_sb
, info
->attrs
,
315 pool_type
, p_tc_index
);
318 #define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0)
319 #define DEVLINK_NL_FLAG_NEED_PORT BIT(1)
320 #define DEVLINK_NL_FLAG_NEED_SB BIT(2)
321 #define DEVLINK_NL_FLAG_LOCK_PORTS BIT(3)
322 /* port is not needed but we need to ensure they don't
323 * change in the middle of command
326 static int devlink_nl_pre_doit(const struct genl_ops
*ops
,
327 struct sk_buff
*skb
, struct genl_info
*info
)
329 struct devlink
*devlink
;
331 mutex_lock(&devlink_mutex
);
332 devlink
= devlink_get_from_info(info
);
333 if (IS_ERR(devlink
)) {
334 mutex_unlock(&devlink_mutex
);
335 return PTR_ERR(devlink
);
337 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_DEVLINK
) {
338 info
->user_ptr
[0] = devlink
;
339 } else if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_PORT
) {
340 struct devlink_port
*devlink_port
;
342 mutex_lock(&devlink_port_mutex
);
343 devlink_port
= devlink_port_get_from_info(devlink
, info
);
344 if (IS_ERR(devlink_port
)) {
345 mutex_unlock(&devlink_port_mutex
);
346 mutex_unlock(&devlink_mutex
);
347 return PTR_ERR(devlink_port
);
349 info
->user_ptr
[0] = devlink_port
;
351 if (ops
->internal_flags
& DEVLINK_NL_FLAG_LOCK_PORTS
) {
352 mutex_lock(&devlink_port_mutex
);
354 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_SB
) {
355 struct devlink_sb
*devlink_sb
;
357 devlink_sb
= devlink_sb_get_from_info(devlink
, info
);
358 if (IS_ERR(devlink_sb
)) {
359 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_PORT
)
360 mutex_unlock(&devlink_port_mutex
);
361 mutex_unlock(&devlink_mutex
);
362 return PTR_ERR(devlink_sb
);
364 info
->user_ptr
[1] = devlink_sb
;
369 static void devlink_nl_post_doit(const struct genl_ops
*ops
,
370 struct sk_buff
*skb
, struct genl_info
*info
)
372 if (ops
->internal_flags
& DEVLINK_NL_FLAG_NEED_PORT
||
373 ops
->internal_flags
& DEVLINK_NL_FLAG_LOCK_PORTS
)
374 mutex_unlock(&devlink_port_mutex
);
375 mutex_unlock(&devlink_mutex
);
378 static struct genl_family devlink_nl_family
;
380 enum devlink_multicast_groups
{
381 DEVLINK_MCGRP_CONFIG
,
384 static const struct genl_multicast_group devlink_nl_mcgrps
[] = {
385 [DEVLINK_MCGRP_CONFIG
] = { .name
= DEVLINK_GENL_MCGRP_CONFIG_NAME
},
388 static int devlink_nl_put_handle(struct sk_buff
*msg
, struct devlink
*devlink
)
390 if (nla_put_string(msg
, DEVLINK_ATTR_BUS_NAME
, devlink
->dev
->bus
->name
))
392 if (nla_put_string(msg
, DEVLINK_ATTR_DEV_NAME
, dev_name(devlink
->dev
)))
397 static int devlink_nl_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
398 enum devlink_command cmd
, u32 portid
,
403 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
407 if (devlink_nl_put_handle(msg
, devlink
))
408 goto nla_put_failure
;
410 genlmsg_end(msg
, hdr
);
414 genlmsg_cancel(msg
, hdr
);
418 static void devlink_notify(struct devlink
*devlink
, enum devlink_command cmd
)
423 WARN_ON(cmd
!= DEVLINK_CMD_NEW
&& cmd
!= DEVLINK_CMD_DEL
);
425 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
429 err
= devlink_nl_fill(msg
, devlink
, cmd
, 0, 0, 0);
435 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
436 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
439 static int devlink_nl_port_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
440 struct devlink_port
*devlink_port
,
441 enum devlink_command cmd
, u32 portid
,
446 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
450 if (devlink_nl_put_handle(msg
, devlink
))
451 goto nla_put_failure
;
452 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
453 goto nla_put_failure
;
454 if (nla_put_u16(msg
, DEVLINK_ATTR_PORT_TYPE
, devlink_port
->type
))
455 goto nla_put_failure
;
456 if (devlink_port
->desired_type
!= DEVLINK_PORT_TYPE_NOTSET
&&
457 nla_put_u16(msg
, DEVLINK_ATTR_PORT_DESIRED_TYPE
,
458 devlink_port
->desired_type
))
459 goto nla_put_failure
;
460 if (devlink_port
->type
== DEVLINK_PORT_TYPE_ETH
) {
461 struct net_device
*netdev
= devlink_port
->type_dev
;
464 (nla_put_u32(msg
, DEVLINK_ATTR_PORT_NETDEV_IFINDEX
,
466 nla_put_string(msg
, DEVLINK_ATTR_PORT_NETDEV_NAME
,
468 goto nla_put_failure
;
470 if (devlink_port
->type
== DEVLINK_PORT_TYPE_IB
) {
471 struct ib_device
*ibdev
= devlink_port
->type_dev
;
474 nla_put_string(msg
, DEVLINK_ATTR_PORT_IBDEV_NAME
,
476 goto nla_put_failure
;
478 if (devlink_port
->split
&&
479 nla_put_u32(msg
, DEVLINK_ATTR_PORT_SPLIT_GROUP
,
480 devlink_port
->split_group
))
481 goto nla_put_failure
;
483 genlmsg_end(msg
, hdr
);
487 genlmsg_cancel(msg
, hdr
);
491 static void devlink_port_notify(struct devlink_port
*devlink_port
,
492 enum devlink_command cmd
)
494 struct devlink
*devlink
= devlink_port
->devlink
;
498 if (!devlink_port
->registered
)
501 WARN_ON(cmd
!= DEVLINK_CMD_PORT_NEW
&& cmd
!= DEVLINK_CMD_PORT_DEL
);
503 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
507 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
, cmd
, 0, 0, 0);
513 genlmsg_multicast_netns(&devlink_nl_family
, devlink_net(devlink
),
514 msg
, 0, DEVLINK_MCGRP_CONFIG
, GFP_KERNEL
);
517 static int devlink_nl_cmd_get_doit(struct sk_buff
*skb
, struct genl_info
*info
)
519 struct devlink
*devlink
= info
->user_ptr
[0];
523 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
527 err
= devlink_nl_fill(msg
, devlink
, DEVLINK_CMD_NEW
,
528 info
->snd_portid
, info
->snd_seq
, 0);
534 return genlmsg_reply(msg
, info
);
537 static int devlink_nl_cmd_get_dumpit(struct sk_buff
*msg
,
538 struct netlink_callback
*cb
)
540 struct devlink
*devlink
;
541 int start
= cb
->args
[0];
545 mutex_lock(&devlink_mutex
);
546 list_for_each_entry(devlink
, &devlink_list
, list
) {
547 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
553 err
= devlink_nl_fill(msg
, devlink
, DEVLINK_CMD_NEW
,
554 NETLINK_CB(cb
->skb
).portid
,
555 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
);
561 mutex_unlock(&devlink_mutex
);
567 static int devlink_nl_cmd_port_get_doit(struct sk_buff
*skb
,
568 struct genl_info
*info
)
570 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
571 struct devlink
*devlink
= devlink_port
->devlink
;
575 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
579 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
,
580 DEVLINK_CMD_PORT_NEW
,
581 info
->snd_portid
, info
->snd_seq
, 0);
587 return genlmsg_reply(msg
, info
);
590 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff
*msg
,
591 struct netlink_callback
*cb
)
593 struct devlink
*devlink
;
594 struct devlink_port
*devlink_port
;
595 int start
= cb
->args
[0];
599 mutex_lock(&devlink_mutex
);
600 mutex_lock(&devlink_port_mutex
);
601 list_for_each_entry(devlink
, &devlink_list
, list
) {
602 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
604 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
609 err
= devlink_nl_port_fill(msg
, devlink
, devlink_port
,
611 NETLINK_CB(cb
->skb
).portid
,
620 mutex_unlock(&devlink_port_mutex
);
621 mutex_unlock(&devlink_mutex
);
627 static int devlink_port_type_set(struct devlink
*devlink
,
628 struct devlink_port
*devlink_port
,
629 enum devlink_port_type port_type
)
634 if (devlink
->ops
&& devlink
->ops
->port_type_set
) {
635 if (port_type
== DEVLINK_PORT_TYPE_NOTSET
)
637 if (port_type
== devlink_port
->type
)
639 err
= devlink
->ops
->port_type_set(devlink_port
, port_type
);
642 devlink_port
->desired_type
= port_type
;
643 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
649 static int devlink_nl_cmd_port_set_doit(struct sk_buff
*skb
,
650 struct genl_info
*info
)
652 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
653 struct devlink
*devlink
= devlink_port
->devlink
;
656 if (info
->attrs
[DEVLINK_ATTR_PORT_TYPE
]) {
657 enum devlink_port_type port_type
;
659 port_type
= nla_get_u16(info
->attrs
[DEVLINK_ATTR_PORT_TYPE
]);
660 err
= devlink_port_type_set(devlink
, devlink_port
, port_type
);
667 static int devlink_port_split(struct devlink
*devlink
,
668 u32 port_index
, u32 count
)
671 if (devlink
->ops
&& devlink
->ops
->port_split
)
672 return devlink
->ops
->port_split(devlink
, port_index
, count
);
676 static int devlink_nl_cmd_port_split_doit(struct sk_buff
*skb
,
677 struct genl_info
*info
)
679 struct devlink
*devlink
= info
->user_ptr
[0];
683 if (!info
->attrs
[DEVLINK_ATTR_PORT_INDEX
] ||
684 !info
->attrs
[DEVLINK_ATTR_PORT_SPLIT_COUNT
])
687 port_index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
688 count
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_SPLIT_COUNT
]);
689 return devlink_port_split(devlink
, port_index
, count
);
692 static int devlink_port_unsplit(struct devlink
*devlink
, u32 port_index
)
695 if (devlink
->ops
&& devlink
->ops
->port_unsplit
)
696 return devlink
->ops
->port_unsplit(devlink
, port_index
);
700 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff
*skb
,
701 struct genl_info
*info
)
703 struct devlink
*devlink
= info
->user_ptr
[0];
706 if (!info
->attrs
[DEVLINK_ATTR_PORT_INDEX
])
709 port_index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
710 return devlink_port_unsplit(devlink
, port_index
);
713 static int devlink_nl_sb_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
714 struct devlink_sb
*devlink_sb
,
715 enum devlink_command cmd
, u32 portid
,
720 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
724 if (devlink_nl_put_handle(msg
, devlink
))
725 goto nla_put_failure
;
726 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
727 goto nla_put_failure
;
728 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_SIZE
, devlink_sb
->size
))
729 goto nla_put_failure
;
730 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT
,
731 devlink_sb
->ingress_pools_count
))
732 goto nla_put_failure
;
733 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT
,
734 devlink_sb
->egress_pools_count
))
735 goto nla_put_failure
;
736 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_INGRESS_TC_COUNT
,
737 devlink_sb
->ingress_tc_count
))
738 goto nla_put_failure
;
739 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_EGRESS_TC_COUNT
,
740 devlink_sb
->egress_tc_count
))
741 goto nla_put_failure
;
743 genlmsg_end(msg
, hdr
);
747 genlmsg_cancel(msg
, hdr
);
751 static int devlink_nl_cmd_sb_get_doit(struct sk_buff
*skb
,
752 struct genl_info
*info
)
754 struct devlink
*devlink
= info
->user_ptr
[0];
755 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
759 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
763 err
= devlink_nl_sb_fill(msg
, devlink
, devlink_sb
,
765 info
->snd_portid
, info
->snd_seq
, 0);
771 return genlmsg_reply(msg
, info
);
774 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff
*msg
,
775 struct netlink_callback
*cb
)
777 struct devlink
*devlink
;
778 struct devlink_sb
*devlink_sb
;
779 int start
= cb
->args
[0];
783 mutex_lock(&devlink_mutex
);
784 list_for_each_entry(devlink
, &devlink_list
, list
) {
785 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)))
787 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
792 err
= devlink_nl_sb_fill(msg
, devlink
, devlink_sb
,
794 NETLINK_CB(cb
->skb
).portid
,
803 mutex_unlock(&devlink_mutex
);
809 static int devlink_nl_sb_pool_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
810 struct devlink_sb
*devlink_sb
,
811 u16 pool_index
, enum devlink_command cmd
,
812 u32 portid
, u32 seq
, int flags
)
814 struct devlink_sb_pool_info pool_info
;
818 err
= devlink
->ops
->sb_pool_get(devlink
, devlink_sb
->index
,
819 pool_index
, &pool_info
);
823 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
827 if (devlink_nl_put_handle(msg
, devlink
))
828 goto nla_put_failure
;
829 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
830 goto nla_put_failure
;
831 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
832 goto nla_put_failure
;
833 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_TYPE
, pool_info
.pool_type
))
834 goto nla_put_failure
;
835 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_POOL_SIZE
, pool_info
.size
))
836 goto nla_put_failure
;
837 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
,
838 pool_info
.threshold_type
))
839 goto nla_put_failure
;
841 genlmsg_end(msg
, hdr
);
845 genlmsg_cancel(msg
, hdr
);
849 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff
*skb
,
850 struct genl_info
*info
)
852 struct devlink
*devlink
= info
->user_ptr
[0];
853 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
858 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
863 if (!devlink
->ops
|| !devlink
->ops
->sb_pool_get
)
866 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
870 err
= devlink_nl_sb_pool_fill(msg
, devlink
, devlink_sb
, pool_index
,
871 DEVLINK_CMD_SB_POOL_NEW
,
872 info
->snd_portid
, info
->snd_seq
, 0);
878 return genlmsg_reply(msg
, info
);
881 static int __sb_pool_get_dumpit(struct sk_buff
*msg
, int start
, int *p_idx
,
882 struct devlink
*devlink
,
883 struct devlink_sb
*devlink_sb
,
886 u16 pool_count
= devlink_sb_pool_count(devlink_sb
);
890 for (pool_index
= 0; pool_index
< pool_count
; pool_index
++) {
891 if (*p_idx
< start
) {
895 err
= devlink_nl_sb_pool_fill(msg
, devlink
,
898 DEVLINK_CMD_SB_POOL_NEW
,
899 portid
, seq
, NLM_F_MULTI
);
907 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff
*msg
,
908 struct netlink_callback
*cb
)
910 struct devlink
*devlink
;
911 struct devlink_sb
*devlink_sb
;
912 int start
= cb
->args
[0];
916 mutex_lock(&devlink_mutex
);
917 list_for_each_entry(devlink
, &devlink_list
, list
) {
918 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
919 !devlink
->ops
|| !devlink
->ops
->sb_pool_get
)
921 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
922 err
= __sb_pool_get_dumpit(msg
, start
, &idx
, devlink
,
924 NETLINK_CB(cb
->skb
).portid
,
926 if (err
&& err
!= -EOPNOTSUPP
)
931 mutex_unlock(&devlink_mutex
);
937 static int devlink_sb_pool_set(struct devlink
*devlink
, unsigned int sb_index
,
938 u16 pool_index
, u32 size
,
939 enum devlink_sb_threshold_type threshold_type
)
942 const struct devlink_ops
*ops
= devlink
->ops
;
944 if (ops
&& ops
->sb_pool_set
)
945 return ops
->sb_pool_set(devlink
, sb_index
, pool_index
,
946 size
, threshold_type
);
950 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff
*skb
,
951 struct genl_info
*info
)
953 struct devlink
*devlink
= info
->user_ptr
[0];
954 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
955 enum devlink_sb_threshold_type threshold_type
;
960 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
965 err
= devlink_sb_th_type_get_from_info(info
, &threshold_type
);
969 if (!info
->attrs
[DEVLINK_ATTR_SB_POOL_SIZE
])
972 size
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_POOL_SIZE
]);
973 return devlink_sb_pool_set(devlink
, devlink_sb
->index
,
974 pool_index
, size
, threshold_type
);
977 static int devlink_nl_sb_port_pool_fill(struct sk_buff
*msg
,
978 struct devlink
*devlink
,
979 struct devlink_port
*devlink_port
,
980 struct devlink_sb
*devlink_sb
,
982 enum devlink_command cmd
,
983 u32 portid
, u32 seq
, int flags
)
985 const struct devlink_ops
*ops
= devlink
->ops
;
990 err
= ops
->sb_port_pool_get(devlink_port
, devlink_sb
->index
,
991 pool_index
, &threshold
);
995 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
999 if (devlink_nl_put_handle(msg
, devlink
))
1000 goto nla_put_failure
;
1001 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
1002 goto nla_put_failure
;
1003 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1004 goto nla_put_failure
;
1005 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1006 goto nla_put_failure
;
1007 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_THRESHOLD
, threshold
))
1008 goto nla_put_failure
;
1010 if (ops
->sb_occ_port_pool_get
) {
1014 err
= ops
->sb_occ_port_pool_get(devlink_port
, devlink_sb
->index
,
1015 pool_index
, &cur
, &max
);
1016 if (err
&& err
!= -EOPNOTSUPP
)
1019 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_CUR
, cur
))
1020 goto nla_put_failure
;
1021 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_MAX
, max
))
1022 goto nla_put_failure
;
1026 genlmsg_end(msg
, hdr
);
1030 genlmsg_cancel(msg
, hdr
);
1034 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff
*skb
,
1035 struct genl_info
*info
)
1037 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1038 struct devlink
*devlink
= devlink_port
->devlink
;
1039 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1040 struct sk_buff
*msg
;
1044 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1049 if (!devlink
->ops
|| !devlink
->ops
->sb_port_pool_get
)
1052 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1056 err
= devlink_nl_sb_port_pool_fill(msg
, devlink
, devlink_port
,
1057 devlink_sb
, pool_index
,
1058 DEVLINK_CMD_SB_PORT_POOL_NEW
,
1059 info
->snd_portid
, info
->snd_seq
, 0);
1065 return genlmsg_reply(msg
, info
);
1068 static int __sb_port_pool_get_dumpit(struct sk_buff
*msg
, int start
, int *p_idx
,
1069 struct devlink
*devlink
,
1070 struct devlink_sb
*devlink_sb
,
1071 u32 portid
, u32 seq
)
1073 struct devlink_port
*devlink_port
;
1074 u16 pool_count
= devlink_sb_pool_count(devlink_sb
);
1078 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
1079 for (pool_index
= 0; pool_index
< pool_count
; pool_index
++) {
1080 if (*p_idx
< start
) {
1084 err
= devlink_nl_sb_port_pool_fill(msg
, devlink
,
1088 DEVLINK_CMD_SB_PORT_POOL_NEW
,
1099 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff
*msg
,
1100 struct netlink_callback
*cb
)
1102 struct devlink
*devlink
;
1103 struct devlink_sb
*devlink_sb
;
1104 int start
= cb
->args
[0];
1108 mutex_lock(&devlink_mutex
);
1109 mutex_lock(&devlink_port_mutex
);
1110 list_for_each_entry(devlink
, &devlink_list
, list
) {
1111 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1112 !devlink
->ops
|| !devlink
->ops
->sb_port_pool_get
)
1114 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1115 err
= __sb_port_pool_get_dumpit(msg
, start
, &idx
,
1116 devlink
, devlink_sb
,
1117 NETLINK_CB(cb
->skb
).portid
,
1118 cb
->nlh
->nlmsg_seq
);
1119 if (err
&& err
!= -EOPNOTSUPP
)
1124 mutex_unlock(&devlink_port_mutex
);
1125 mutex_unlock(&devlink_mutex
);
1131 static int devlink_sb_port_pool_set(struct devlink_port
*devlink_port
,
1132 unsigned int sb_index
, u16 pool_index
,
1136 const struct devlink_ops
*ops
= devlink_port
->devlink
->ops
;
1138 if (ops
&& ops
->sb_port_pool_set
)
1139 return ops
->sb_port_pool_set(devlink_port
, sb_index
,
1140 pool_index
, threshold
);
1144 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff
*skb
,
1145 struct genl_info
*info
)
1147 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1148 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1153 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1158 if (!info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
])
1161 threshold
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
]);
1162 return devlink_sb_port_pool_set(devlink_port
, devlink_sb
->index
,
1163 pool_index
, threshold
);
1167 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1168 struct devlink_port
*devlink_port
,
1169 struct devlink_sb
*devlink_sb
, u16 tc_index
,
1170 enum devlink_sb_pool_type pool_type
,
1171 enum devlink_command cmd
,
1172 u32 portid
, u32 seq
, int flags
)
1174 const struct devlink_ops
*ops
= devlink
->ops
;
1180 err
= ops
->sb_tc_pool_bind_get(devlink_port
, devlink_sb
->index
,
1181 tc_index
, pool_type
,
1182 &pool_index
, &threshold
);
1186 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1190 if (devlink_nl_put_handle(msg
, devlink
))
1191 goto nla_put_failure
;
1192 if (nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
, devlink_port
->index
))
1193 goto nla_put_failure
;
1194 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_INDEX
, devlink_sb
->index
))
1195 goto nla_put_failure
;
1196 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_TC_INDEX
, tc_index
))
1197 goto nla_put_failure
;
1198 if (nla_put_u8(msg
, DEVLINK_ATTR_SB_POOL_TYPE
, pool_type
))
1199 goto nla_put_failure
;
1200 if (nla_put_u16(msg
, DEVLINK_ATTR_SB_POOL_INDEX
, pool_index
))
1201 goto nla_put_failure
;
1202 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_THRESHOLD
, threshold
))
1203 goto nla_put_failure
;
1205 if (ops
->sb_occ_tc_port_bind_get
) {
1209 err
= ops
->sb_occ_tc_port_bind_get(devlink_port
,
1211 tc_index
, pool_type
,
1213 if (err
&& err
!= -EOPNOTSUPP
)
1216 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_CUR
, cur
))
1217 goto nla_put_failure
;
1218 if (nla_put_u32(msg
, DEVLINK_ATTR_SB_OCC_MAX
, max
))
1219 goto nla_put_failure
;
1223 genlmsg_end(msg
, hdr
);
1227 genlmsg_cancel(msg
, hdr
);
1231 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff
*skb
,
1232 struct genl_info
*info
)
1234 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1235 struct devlink
*devlink
= devlink_port
->devlink
;
1236 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1237 struct sk_buff
*msg
;
1238 enum devlink_sb_pool_type pool_type
;
1242 err
= devlink_sb_pool_type_get_from_info(info
, &pool_type
);
1246 err
= devlink_sb_tc_index_get_from_info(devlink_sb
, info
,
1247 pool_type
, &tc_index
);
1251 if (!devlink
->ops
|| !devlink
->ops
->sb_tc_pool_bind_get
)
1254 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1258 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
, devlink_port
,
1259 devlink_sb
, tc_index
, pool_type
,
1260 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1268 return genlmsg_reply(msg
, info
);
1271 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff
*msg
,
1272 int start
, int *p_idx
,
1273 struct devlink
*devlink
,
1274 struct devlink_sb
*devlink_sb
,
1275 u32 portid
, u32 seq
)
1277 struct devlink_port
*devlink_port
;
1281 list_for_each_entry(devlink_port
, &devlink
->port_list
, list
) {
1283 tc_index
< devlink_sb
->ingress_tc_count
; tc_index
++) {
1284 if (*p_idx
< start
) {
1288 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
,
1292 DEVLINK_SB_POOL_TYPE_INGRESS
,
1293 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1301 tc_index
< devlink_sb
->egress_tc_count
; tc_index
++) {
1302 if (*p_idx
< start
) {
1306 err
= devlink_nl_sb_tc_pool_bind_fill(msg
, devlink
,
1310 DEVLINK_SB_POOL_TYPE_EGRESS
,
1311 DEVLINK_CMD_SB_TC_POOL_BIND_NEW
,
1323 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff
*msg
,
1324 struct netlink_callback
*cb
)
1326 struct devlink
*devlink
;
1327 struct devlink_sb
*devlink_sb
;
1328 int start
= cb
->args
[0];
1332 mutex_lock(&devlink_mutex
);
1333 mutex_lock(&devlink_port_mutex
);
1334 list_for_each_entry(devlink
, &devlink_list
, list
) {
1335 if (!net_eq(devlink_net(devlink
), sock_net(msg
->sk
)) ||
1336 !devlink
->ops
|| !devlink
->ops
->sb_tc_pool_bind_get
)
1338 list_for_each_entry(devlink_sb
, &devlink
->sb_list
, list
) {
1339 err
= __sb_tc_pool_bind_get_dumpit(msg
, start
, &idx
,
1342 NETLINK_CB(cb
->skb
).portid
,
1343 cb
->nlh
->nlmsg_seq
);
1344 if (err
&& err
!= -EOPNOTSUPP
)
1349 mutex_unlock(&devlink_port_mutex
);
1350 mutex_unlock(&devlink_mutex
);
1356 static int devlink_sb_tc_pool_bind_set(struct devlink_port
*devlink_port
,
1357 unsigned int sb_index
, u16 tc_index
,
1358 enum devlink_sb_pool_type pool_type
,
1359 u16 pool_index
, u32 threshold
)
1362 const struct devlink_ops
*ops
= devlink_port
->devlink
->ops
;
1364 if (ops
&& ops
->sb_tc_pool_bind_set
)
1365 return ops
->sb_tc_pool_bind_set(devlink_port
, sb_index
,
1366 tc_index
, pool_type
,
1367 pool_index
, threshold
);
1371 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff
*skb
,
1372 struct genl_info
*info
)
1374 struct devlink_port
*devlink_port
= info
->user_ptr
[0];
1375 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1376 enum devlink_sb_pool_type pool_type
;
1382 err
= devlink_sb_pool_type_get_from_info(info
, &pool_type
);
1386 err
= devlink_sb_tc_index_get_from_info(devlink_sb
, info
,
1387 pool_type
, &tc_index
);
1391 err
= devlink_sb_pool_index_get_from_info(devlink_sb
, info
,
1396 if (!info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
])
1399 threshold
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_SB_THRESHOLD
]);
1400 return devlink_sb_tc_pool_bind_set(devlink_port
, devlink_sb
->index
,
1401 tc_index
, pool_type
,
1402 pool_index
, threshold
);
1405 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff
*skb
,
1406 struct genl_info
*info
)
1408 struct devlink
*devlink
= info
->user_ptr
[0];
1409 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1410 const struct devlink_ops
*ops
= devlink
->ops
;
1412 if (ops
&& ops
->sb_occ_snapshot
)
1413 return ops
->sb_occ_snapshot(devlink
, devlink_sb
->index
);
1417 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff
*skb
,
1418 struct genl_info
*info
)
1420 struct devlink
*devlink
= info
->user_ptr
[0];
1421 struct devlink_sb
*devlink_sb
= info
->user_ptr
[1];
1422 const struct devlink_ops
*ops
= devlink
->ops
;
1424 if (ops
&& ops
->sb_occ_max_clear
)
1425 return ops
->sb_occ_max_clear(devlink
, devlink_sb
->index
);
1429 static int devlink_nl_eswitch_fill(struct sk_buff
*msg
, struct devlink
*devlink
,
1430 enum devlink_command cmd
, u32 portid
,
1433 const struct devlink_ops
*ops
= devlink
->ops
;
1434 u8 inline_mode
, encap_mode
;
1439 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, flags
, cmd
);
1443 err
= devlink_nl_put_handle(msg
, devlink
);
1445 goto nla_put_failure
;
1447 if (ops
->eswitch_mode_get
) {
1448 err
= ops
->eswitch_mode_get(devlink
, &mode
);
1450 goto nla_put_failure
;
1451 err
= nla_put_u16(msg
, DEVLINK_ATTR_ESWITCH_MODE
, mode
);
1453 goto nla_put_failure
;
1456 if (ops
->eswitch_inline_mode_get
) {
1457 err
= ops
->eswitch_inline_mode_get(devlink
, &inline_mode
);
1459 goto nla_put_failure
;
1460 err
= nla_put_u8(msg
, DEVLINK_ATTR_ESWITCH_INLINE_MODE
,
1463 goto nla_put_failure
;
1466 if (ops
->eswitch_encap_mode_get
) {
1467 err
= ops
->eswitch_encap_mode_get(devlink
, &encap_mode
);
1469 goto nla_put_failure
;
1470 err
= nla_put_u8(msg
, DEVLINK_ATTR_ESWITCH_ENCAP_MODE
, encap_mode
);
1472 goto nla_put_failure
;
1475 genlmsg_end(msg
, hdr
);
1479 genlmsg_cancel(msg
, hdr
);
1483 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff
*skb
,
1484 struct genl_info
*info
)
1486 struct devlink
*devlink
= info
->user_ptr
[0];
1487 const struct devlink_ops
*ops
= devlink
->ops
;
1488 struct sk_buff
*msg
;
1494 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1498 err
= devlink_nl_eswitch_fill(msg
, devlink
, DEVLINK_CMD_ESWITCH_GET
,
1499 info
->snd_portid
, info
->snd_seq
, 0);
1506 return genlmsg_reply(msg
, info
);
1509 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff
*skb
,
1510 struct genl_info
*info
)
1512 struct devlink
*devlink
= info
->user_ptr
[0];
1513 const struct devlink_ops
*ops
= devlink
->ops
;
1514 u8 inline_mode
, encap_mode
;
1521 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_MODE
]) {
1522 if (!ops
->eswitch_mode_set
)
1524 mode
= nla_get_u16(info
->attrs
[DEVLINK_ATTR_ESWITCH_MODE
]);
1525 err
= ops
->eswitch_mode_set(devlink
, mode
);
1530 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_INLINE_MODE
]) {
1531 if (!ops
->eswitch_inline_mode_set
)
1533 inline_mode
= nla_get_u8(
1534 info
->attrs
[DEVLINK_ATTR_ESWITCH_INLINE_MODE
]);
1535 err
= ops
->eswitch_inline_mode_set(devlink
, inline_mode
);
1540 if (info
->attrs
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE
]) {
1541 if (!ops
->eswitch_encap_mode_set
)
1543 encap_mode
= nla_get_u8(info
->attrs
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE
]);
1544 err
= ops
->eswitch_encap_mode_set(devlink
, encap_mode
);
1552 int devlink_dpipe_match_put(struct sk_buff
*skb
,
1553 struct devlink_dpipe_match
*match
)
1555 struct devlink_dpipe_header
*header
= match
->header
;
1556 struct devlink_dpipe_field
*field
= &header
->fields
[match
->field_id
];
1557 struct nlattr
*match_attr
;
1559 match_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_MATCH
);
1563 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_MATCH_TYPE
, match
->type
) ||
1564 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, match
->header_index
) ||
1565 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
1566 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
1567 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
1568 goto nla_put_failure
;
1570 nla_nest_end(skb
, match_attr
);
1574 nla_nest_cancel(skb
, match_attr
);
1577 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put
);
1579 static int devlink_dpipe_matches_put(struct devlink_dpipe_table
*table
,
1580 struct sk_buff
*skb
)
1582 struct nlattr
*matches_attr
;
1584 matches_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_TABLE_MATCHES
);
1588 if (table
->table_ops
->matches_dump(table
->priv
, skb
))
1589 goto nla_put_failure
;
1591 nla_nest_end(skb
, matches_attr
);
1595 nla_nest_cancel(skb
, matches_attr
);
1599 int devlink_dpipe_action_put(struct sk_buff
*skb
,
1600 struct devlink_dpipe_action
*action
)
1602 struct devlink_dpipe_header
*header
= action
->header
;
1603 struct devlink_dpipe_field
*field
= &header
->fields
[action
->field_id
];
1604 struct nlattr
*action_attr
;
1606 action_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_ACTION
);
1610 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_ACTION_TYPE
, action
->type
) ||
1611 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_INDEX
, action
->header_index
) ||
1612 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
1613 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
1614 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
1615 goto nla_put_failure
;
1617 nla_nest_end(skb
, action_attr
);
1621 nla_nest_cancel(skb
, action_attr
);
1624 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put
);
1626 static int devlink_dpipe_actions_put(struct devlink_dpipe_table
*table
,
1627 struct sk_buff
*skb
)
1629 struct nlattr
*actions_attr
;
1631 actions_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_TABLE_ACTIONS
);
1635 if (table
->table_ops
->actions_dump(table
->priv
, skb
))
1636 goto nla_put_failure
;
1638 nla_nest_end(skb
, actions_attr
);
1642 nla_nest_cancel(skb
, actions_attr
);
1646 static int devlink_dpipe_table_put(struct sk_buff
*skb
,
1647 struct devlink_dpipe_table
*table
)
1649 struct nlattr
*table_attr
;
1652 table_size
= table
->table_ops
->size_get(table
->priv
);
1653 table_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_TABLE
);
1657 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_TABLE_NAME
, table
->name
) ||
1658 nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_TABLE_SIZE
, table_size
,
1660 goto nla_put_failure
;
1661 if (nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
,
1662 table
->counters_enabled
))
1663 goto nla_put_failure
;
1665 if (devlink_dpipe_matches_put(table
, skb
))
1666 goto nla_put_failure
;
1668 if (devlink_dpipe_actions_put(table
, skb
))
1669 goto nla_put_failure
;
1671 nla_nest_end(skb
, table_attr
);
1675 nla_nest_cancel(skb
, table_attr
);
1679 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff
**pskb
,
1680 struct genl_info
*info
)
1685 err
= genlmsg_reply(*pskb
, info
);
1689 *pskb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1695 static int devlink_dpipe_tables_fill(struct genl_info
*info
,
1696 enum devlink_command cmd
, int flags
,
1697 struct list_head
*dpipe_tables
,
1698 const char *table_name
)
1700 struct devlink
*devlink
= info
->user_ptr
[0];
1701 struct devlink_dpipe_table
*table
;
1702 struct nlattr
*tables_attr
;
1703 struct sk_buff
*skb
= NULL
;
1704 struct nlmsghdr
*nlh
;
1710 table
= list_first_entry(dpipe_tables
,
1711 struct devlink_dpipe_table
, list
);
1713 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
1717 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
1718 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
1724 if (devlink_nl_put_handle(skb
, devlink
))
1725 goto nla_put_failure
;
1726 tables_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_TABLES
);
1728 goto nla_put_failure
;
1732 list_for_each_entry_from(table
, dpipe_tables
, list
) {
1734 err
= devlink_dpipe_table_put(skb
, table
);
1742 if (!strcmp(table
->name
, table_name
)) {
1743 err
= devlink_dpipe_table_put(skb
, table
);
1751 nla_nest_end(skb
, tables_attr
);
1752 genlmsg_end(skb
, hdr
);
1757 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
1758 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
1760 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
1762 goto err_skb_send_alloc
;
1766 return genlmsg_reply(skb
, info
);
1772 genlmsg_cancel(skb
, hdr
);
1777 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff
*skb
,
1778 struct genl_info
*info
)
1780 struct devlink
*devlink
= info
->user_ptr
[0];
1781 const char *table_name
= NULL
;
1783 if (info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
1784 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
1786 return devlink_dpipe_tables_fill(info
, DEVLINK_CMD_DPIPE_TABLE_GET
, 0,
1787 &devlink
->dpipe_table_list
,
1791 static int devlink_dpipe_value_put(struct sk_buff
*skb
,
1792 struct devlink_dpipe_value
*value
)
1794 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE
,
1795 value
->value_size
, value
->value
))
1798 if (nla_put(skb
, DEVLINK_ATTR_DPIPE_VALUE_MASK
,
1799 value
->value_size
, value
->mask
))
1801 if (value
->mapping_valid
)
1802 if (nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_VALUE_MAPPING
,
1803 value
->mapping_value
))
1808 static int devlink_dpipe_action_value_put(struct sk_buff
*skb
,
1809 struct devlink_dpipe_value
*value
)
1813 if (devlink_dpipe_action_put(skb
, value
->action
))
1815 if (devlink_dpipe_value_put(skb
, value
))
1820 static int devlink_dpipe_action_values_put(struct sk_buff
*skb
,
1821 struct devlink_dpipe_value
*values
,
1822 unsigned int values_count
)
1824 struct nlattr
*action_attr
;
1828 for (i
= 0; i
< values_count
; i
++) {
1829 action_attr
= nla_nest_start(skb
,
1830 DEVLINK_ATTR_DPIPE_ACTION_VALUE
);
1833 err
= devlink_dpipe_action_value_put(skb
, &values
[i
]);
1835 goto err_action_value_put
;
1836 nla_nest_end(skb
, action_attr
);
1840 err_action_value_put
:
1841 nla_nest_cancel(skb
, action_attr
);
1845 static int devlink_dpipe_match_value_put(struct sk_buff
*skb
,
1846 struct devlink_dpipe_value
*value
)
1850 if (devlink_dpipe_match_put(skb
, value
->match
))
1852 if (devlink_dpipe_value_put(skb
, value
))
1857 static int devlink_dpipe_match_values_put(struct sk_buff
*skb
,
1858 struct devlink_dpipe_value
*values
,
1859 unsigned int values_count
)
1861 struct nlattr
*match_attr
;
1865 for (i
= 0; i
< values_count
; i
++) {
1866 match_attr
= nla_nest_start(skb
,
1867 DEVLINK_ATTR_DPIPE_MATCH_VALUE
);
1870 err
= devlink_dpipe_match_value_put(skb
, &values
[i
]);
1872 goto err_match_value_put
;
1873 nla_nest_end(skb
, match_attr
);
1877 err_match_value_put
:
1878 nla_nest_cancel(skb
, match_attr
);
1882 static int devlink_dpipe_entry_put(struct sk_buff
*skb
,
1883 struct devlink_dpipe_entry
*entry
)
1885 struct nlattr
*entry_attr
, *matches_attr
, *actions_attr
;
1888 entry_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_ENTRY
);
1892 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_INDEX
, entry
->index
,
1894 goto nla_put_failure
;
1895 if (entry
->counter_valid
)
1896 if (nla_put_u64_64bit(skb
, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER
,
1897 entry
->counter
, DEVLINK_ATTR_PAD
))
1898 goto nla_put_failure
;
1900 matches_attr
= nla_nest_start(skb
,
1901 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES
);
1903 goto nla_put_failure
;
1905 err
= devlink_dpipe_match_values_put(skb
, entry
->match_values
,
1906 entry
->match_values_count
);
1908 nla_nest_cancel(skb
, matches_attr
);
1909 goto err_match_values_put
;
1911 nla_nest_end(skb
, matches_attr
);
1913 actions_attr
= nla_nest_start(skb
,
1914 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES
);
1916 goto nla_put_failure
;
1918 err
= devlink_dpipe_action_values_put(skb
, entry
->action_values
,
1919 entry
->action_values_count
);
1921 nla_nest_cancel(skb
, actions_attr
);
1922 goto err_action_values_put
;
1924 nla_nest_end(skb
, actions_attr
);
1926 nla_nest_end(skb
, entry_attr
);
1931 err_match_values_put
:
1932 err_action_values_put
:
1933 nla_nest_cancel(skb
, entry_attr
);
1937 static struct devlink_dpipe_table
*
1938 devlink_dpipe_table_find(struct list_head
*dpipe_tables
,
1939 const char *table_name
)
1941 struct devlink_dpipe_table
*table
;
1943 list_for_each_entry_rcu(table
, dpipe_tables
, list
) {
1944 if (!strcmp(table
->name
, table_name
))
1950 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx
*dump_ctx
)
1952 struct devlink
*devlink
;
1955 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
->skb
,
1960 dump_ctx
->hdr
= genlmsg_put(dump_ctx
->skb
,
1961 dump_ctx
->info
->snd_portid
,
1962 dump_ctx
->info
->snd_seq
,
1963 &devlink_nl_family
, NLM_F_MULTI
,
1966 goto nla_put_failure
;
1968 devlink
= dump_ctx
->info
->user_ptr
[0];
1969 if (devlink_nl_put_handle(dump_ctx
->skb
, devlink
))
1970 goto nla_put_failure
;
1971 dump_ctx
->nest
= nla_nest_start(dump_ctx
->skb
,
1972 DEVLINK_ATTR_DPIPE_ENTRIES
);
1973 if (!dump_ctx
->nest
)
1974 goto nla_put_failure
;
1978 genlmsg_cancel(dump_ctx
->skb
, dump_ctx
->hdr
);
1979 nlmsg_free(dump_ctx
->skb
);
1982 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare
);
1984 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx
*dump_ctx
,
1985 struct devlink_dpipe_entry
*entry
)
1987 return devlink_dpipe_entry_put(dump_ctx
->skb
, entry
);
1989 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append
);
1991 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx
*dump_ctx
)
1993 nla_nest_end(dump_ctx
->skb
, dump_ctx
->nest
);
1994 genlmsg_end(dump_ctx
->skb
, dump_ctx
->hdr
);
1997 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close
);
1999 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry
*entry
)
2002 unsigned int value_count
, value_index
;
2003 struct devlink_dpipe_value
*value
;
2005 value
= entry
->action_values
;
2006 value_count
= entry
->action_values_count
;
2007 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2008 kfree(value
[value_index
].value
);
2009 kfree(value
[value_index
].mask
);
2012 value
= entry
->match_values
;
2013 value_count
= entry
->match_values_count
;
2014 for (value_index
= 0; value_index
< value_count
; value_index
++) {
2015 kfree(value
[value_index
].value
);
2016 kfree(value
[value_index
].mask
);
2019 EXPORT_SYMBOL(devlink_dpipe_entry_clear
);
2021 static int devlink_dpipe_entries_fill(struct genl_info
*info
,
2022 enum devlink_command cmd
, int flags
,
2023 struct devlink_dpipe_table
*table
)
2025 struct devlink_dpipe_dump_ctx dump_ctx
;
2026 struct nlmsghdr
*nlh
;
2029 dump_ctx
.skb
= NULL
;
2031 dump_ctx
.info
= info
;
2033 err
= table
->table_ops
->entries_dump(table
->priv
,
2034 table
->counters_enabled
,
2037 goto err_entries_dump
;
2040 nlh
= nlmsg_put(dump_ctx
.skb
, info
->snd_portid
, info
->snd_seq
,
2041 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2043 err
= devlink_dpipe_send_and_alloc_skb(&dump_ctx
.skb
, info
);
2045 goto err_skb_send_alloc
;
2048 return genlmsg_reply(dump_ctx
.skb
, info
);
2052 genlmsg_cancel(dump_ctx
.skb
, dump_ctx
.hdr
);
2053 nlmsg_free(dump_ctx
.skb
);
2057 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff
*skb
,
2058 struct genl_info
*info
)
2060 struct devlink
*devlink
= info
->user_ptr
[0];
2061 struct devlink_dpipe_table
*table
;
2062 const char *table_name
;
2064 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
])
2067 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2068 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2073 if (!table
->table_ops
->entries_dump
)
2076 return devlink_dpipe_entries_fill(info
, DEVLINK_CMD_DPIPE_ENTRIES_GET
,
2080 static int devlink_dpipe_fields_put(struct sk_buff
*skb
,
2081 const struct devlink_dpipe_header
*header
)
2083 struct devlink_dpipe_field
*field
;
2084 struct nlattr
*field_attr
;
2087 for (i
= 0; i
< header
->fields_count
; i
++) {
2088 field
= &header
->fields
[i
];
2089 field_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_FIELD
);
2092 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_FIELD_NAME
, field
->name
) ||
2093 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_ID
, field
->id
) ||
2094 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH
, field
->bitwidth
) ||
2095 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE
, field
->mapping_type
))
2096 goto nla_put_failure
;
2097 nla_nest_end(skb
, field_attr
);
2102 nla_nest_cancel(skb
, field_attr
);
2106 static int devlink_dpipe_header_put(struct sk_buff
*skb
,
2107 struct devlink_dpipe_header
*header
)
2109 struct nlattr
*fields_attr
, *header_attr
;
2112 header_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_HEADER
);
2116 if (nla_put_string(skb
, DEVLINK_ATTR_DPIPE_HEADER_NAME
, header
->name
) ||
2117 nla_put_u32(skb
, DEVLINK_ATTR_DPIPE_HEADER_ID
, header
->id
) ||
2118 nla_put_u8(skb
, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL
, header
->global
))
2119 goto nla_put_failure
;
2121 fields_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_HEADER_FIELDS
);
2123 goto nla_put_failure
;
2125 err
= devlink_dpipe_fields_put(skb
, header
);
2127 nla_nest_cancel(skb
, fields_attr
);
2128 goto nla_put_failure
;
2130 nla_nest_end(skb
, fields_attr
);
2131 nla_nest_end(skb
, header_attr
);
2136 nla_nest_cancel(skb
, header_attr
);
2140 static int devlink_dpipe_headers_fill(struct genl_info
*info
,
2141 enum devlink_command cmd
, int flags
,
2142 struct devlink_dpipe_headers
*
2145 struct devlink
*devlink
= info
->user_ptr
[0];
2146 struct nlattr
*headers_attr
;
2147 struct sk_buff
*skb
= NULL
;
2148 struct nlmsghdr
*nlh
;
2155 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2159 hdr
= genlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2160 &devlink_nl_family
, NLM_F_MULTI
, cmd
);
2166 if (devlink_nl_put_handle(skb
, devlink
))
2167 goto nla_put_failure
;
2168 headers_attr
= nla_nest_start(skb
, DEVLINK_ATTR_DPIPE_HEADERS
);
2170 goto nla_put_failure
;
2173 for (; i
< dpipe_headers
->headers_count
; i
++) {
2174 err
= devlink_dpipe_header_put(skb
, dpipe_headers
->headers
[i
]);
2182 nla_nest_end(skb
, headers_attr
);
2183 genlmsg_end(skb
, hdr
);
2184 if (i
!= dpipe_headers
->headers_count
)
2188 nlh
= nlmsg_put(skb
, info
->snd_portid
, info
->snd_seq
,
2189 NLMSG_DONE
, 0, flags
| NLM_F_MULTI
);
2191 err
= devlink_dpipe_send_and_alloc_skb(&skb
, info
);
2193 goto err_skb_send_alloc
;
2196 return genlmsg_reply(skb
, info
);
2202 genlmsg_cancel(skb
, hdr
);
2207 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff
*skb
,
2208 struct genl_info
*info
)
2210 struct devlink
*devlink
= info
->user_ptr
[0];
2212 if (!devlink
->dpipe_headers
)
2214 return devlink_dpipe_headers_fill(info
, DEVLINK_CMD_DPIPE_HEADERS_GET
,
2215 0, devlink
->dpipe_headers
);
2218 static int devlink_dpipe_table_counters_set(struct devlink
*devlink
,
2219 const char *table_name
,
2222 struct devlink_dpipe_table
*table
;
2224 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2229 if (table
->counter_control_extern
)
2232 if (!(table
->counters_enabled
^ enable
))
2235 table
->counters_enabled
= enable
;
2236 if (table
->table_ops
->counters_set_update
)
2237 table
->table_ops
->counters_set_update(table
->priv
, enable
);
2241 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff
*skb
,
2242 struct genl_info
*info
)
2244 struct devlink
*devlink
= info
->user_ptr
[0];
2245 const char *table_name
;
2246 bool counters_enable
;
2248 if (!info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
] ||
2249 !info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
])
2252 table_name
= nla_data(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_NAME
]);
2253 counters_enable
= !!nla_get_u8(info
->attrs
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
]);
2255 return devlink_dpipe_table_counters_set(devlink
, table_name
,
2259 static const struct nla_policy devlink_nl_policy
[DEVLINK_ATTR_MAX
+ 1] = {
2260 [DEVLINK_ATTR_BUS_NAME
] = { .type
= NLA_NUL_STRING
},
2261 [DEVLINK_ATTR_DEV_NAME
] = { .type
= NLA_NUL_STRING
},
2262 [DEVLINK_ATTR_PORT_INDEX
] = { .type
= NLA_U32
},
2263 [DEVLINK_ATTR_PORT_TYPE
] = { .type
= NLA_U16
},
2264 [DEVLINK_ATTR_PORT_SPLIT_COUNT
] = { .type
= NLA_U32
},
2265 [DEVLINK_ATTR_SB_INDEX
] = { .type
= NLA_U32
},
2266 [DEVLINK_ATTR_SB_POOL_INDEX
] = { .type
= NLA_U16
},
2267 [DEVLINK_ATTR_SB_POOL_TYPE
] = { .type
= NLA_U8
},
2268 [DEVLINK_ATTR_SB_POOL_SIZE
] = { .type
= NLA_U32
},
2269 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE
] = { .type
= NLA_U8
},
2270 [DEVLINK_ATTR_SB_THRESHOLD
] = { .type
= NLA_U32
},
2271 [DEVLINK_ATTR_SB_TC_INDEX
] = { .type
= NLA_U16
},
2272 [DEVLINK_ATTR_ESWITCH_MODE
] = { .type
= NLA_U16
},
2273 [DEVLINK_ATTR_ESWITCH_INLINE_MODE
] = { .type
= NLA_U8
},
2274 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE
] = { .type
= NLA_U8
},
2275 [DEVLINK_ATTR_DPIPE_TABLE_NAME
] = { .type
= NLA_NUL_STRING
},
2276 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED
] = { .type
= NLA_U8
},
2279 static const struct genl_ops devlink_nl_ops
[] = {
2281 .cmd
= DEVLINK_CMD_GET
,
2282 .doit
= devlink_nl_cmd_get_doit
,
2283 .dumpit
= devlink_nl_cmd_get_dumpit
,
2284 .policy
= devlink_nl_policy
,
2285 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2286 /* can be retrieved by unprivileged users */
2289 .cmd
= DEVLINK_CMD_PORT_GET
,
2290 .doit
= devlink_nl_cmd_port_get_doit
,
2291 .dumpit
= devlink_nl_cmd_port_get_dumpit
,
2292 .policy
= devlink_nl_policy
,
2293 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
2294 /* can be retrieved by unprivileged users */
2297 .cmd
= DEVLINK_CMD_PORT_SET
,
2298 .doit
= devlink_nl_cmd_port_set_doit
,
2299 .policy
= devlink_nl_policy
,
2300 .flags
= GENL_ADMIN_PERM
,
2301 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
,
2304 .cmd
= DEVLINK_CMD_PORT_SPLIT
,
2305 .doit
= devlink_nl_cmd_port_split_doit
,
2306 .policy
= devlink_nl_policy
,
2307 .flags
= GENL_ADMIN_PERM
,
2308 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2311 .cmd
= DEVLINK_CMD_PORT_UNSPLIT
,
2312 .doit
= devlink_nl_cmd_port_unsplit_doit
,
2313 .policy
= devlink_nl_policy
,
2314 .flags
= GENL_ADMIN_PERM
,
2315 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2318 .cmd
= DEVLINK_CMD_SB_GET
,
2319 .doit
= devlink_nl_cmd_sb_get_doit
,
2320 .dumpit
= devlink_nl_cmd_sb_get_dumpit
,
2321 .policy
= devlink_nl_policy
,
2322 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2323 DEVLINK_NL_FLAG_NEED_SB
,
2324 /* can be retrieved by unprivileged users */
2327 .cmd
= DEVLINK_CMD_SB_POOL_GET
,
2328 .doit
= devlink_nl_cmd_sb_pool_get_doit
,
2329 .dumpit
= devlink_nl_cmd_sb_pool_get_dumpit
,
2330 .policy
= devlink_nl_policy
,
2331 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2332 DEVLINK_NL_FLAG_NEED_SB
,
2333 /* can be retrieved by unprivileged users */
2336 .cmd
= DEVLINK_CMD_SB_POOL_SET
,
2337 .doit
= devlink_nl_cmd_sb_pool_set_doit
,
2338 .policy
= devlink_nl_policy
,
2339 .flags
= GENL_ADMIN_PERM
,
2340 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2341 DEVLINK_NL_FLAG_NEED_SB
,
2344 .cmd
= DEVLINK_CMD_SB_PORT_POOL_GET
,
2345 .doit
= devlink_nl_cmd_sb_port_pool_get_doit
,
2346 .dumpit
= devlink_nl_cmd_sb_port_pool_get_dumpit
,
2347 .policy
= devlink_nl_policy
,
2348 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
2349 DEVLINK_NL_FLAG_NEED_SB
,
2350 /* can be retrieved by unprivileged users */
2353 .cmd
= DEVLINK_CMD_SB_PORT_POOL_SET
,
2354 .doit
= devlink_nl_cmd_sb_port_pool_set_doit
,
2355 .policy
= devlink_nl_policy
,
2356 .flags
= GENL_ADMIN_PERM
,
2357 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
2358 DEVLINK_NL_FLAG_NEED_SB
,
2361 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_GET
,
2362 .doit
= devlink_nl_cmd_sb_tc_pool_bind_get_doit
,
2363 .dumpit
= devlink_nl_cmd_sb_tc_pool_bind_get_dumpit
,
2364 .policy
= devlink_nl_policy
,
2365 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
2366 DEVLINK_NL_FLAG_NEED_SB
,
2367 /* can be retrieved by unprivileged users */
2370 .cmd
= DEVLINK_CMD_SB_TC_POOL_BIND_SET
,
2371 .doit
= devlink_nl_cmd_sb_tc_pool_bind_set_doit
,
2372 .policy
= devlink_nl_policy
,
2373 .flags
= GENL_ADMIN_PERM
,
2374 .internal_flags
= DEVLINK_NL_FLAG_NEED_PORT
|
2375 DEVLINK_NL_FLAG_NEED_SB
,
2378 .cmd
= DEVLINK_CMD_SB_OCC_SNAPSHOT
,
2379 .doit
= devlink_nl_cmd_sb_occ_snapshot_doit
,
2380 .policy
= devlink_nl_policy
,
2381 .flags
= GENL_ADMIN_PERM
,
2382 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2383 DEVLINK_NL_FLAG_NEED_SB
|
2384 DEVLINK_NL_FLAG_LOCK_PORTS
,
2387 .cmd
= DEVLINK_CMD_SB_OCC_MAX_CLEAR
,
2388 .doit
= devlink_nl_cmd_sb_occ_max_clear_doit
,
2389 .policy
= devlink_nl_policy
,
2390 .flags
= GENL_ADMIN_PERM
,
2391 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
|
2392 DEVLINK_NL_FLAG_NEED_SB
|
2393 DEVLINK_NL_FLAG_LOCK_PORTS
,
2396 .cmd
= DEVLINK_CMD_ESWITCH_GET
,
2397 .doit
= devlink_nl_cmd_eswitch_get_doit
,
2398 .policy
= devlink_nl_policy
,
2399 .flags
= GENL_ADMIN_PERM
,
2400 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2403 .cmd
= DEVLINK_CMD_ESWITCH_SET
,
2404 .doit
= devlink_nl_cmd_eswitch_set_doit
,
2405 .policy
= devlink_nl_policy
,
2406 .flags
= GENL_ADMIN_PERM
,
2407 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2410 .cmd
= DEVLINK_CMD_DPIPE_TABLE_GET
,
2411 .doit
= devlink_nl_cmd_dpipe_table_get
,
2412 .policy
= devlink_nl_policy
,
2413 .flags
= GENL_ADMIN_PERM
,
2414 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2417 .cmd
= DEVLINK_CMD_DPIPE_ENTRIES_GET
,
2418 .doit
= devlink_nl_cmd_dpipe_entries_get
,
2419 .policy
= devlink_nl_policy
,
2420 .flags
= GENL_ADMIN_PERM
,
2421 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2424 .cmd
= DEVLINK_CMD_DPIPE_HEADERS_GET
,
2425 .doit
= devlink_nl_cmd_dpipe_headers_get
,
2426 .policy
= devlink_nl_policy
,
2427 .flags
= GENL_ADMIN_PERM
,
2428 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2431 .cmd
= DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET
,
2432 .doit
= devlink_nl_cmd_dpipe_table_counters_set
,
2433 .policy
= devlink_nl_policy
,
2434 .flags
= GENL_ADMIN_PERM
,
2435 .internal_flags
= DEVLINK_NL_FLAG_NEED_DEVLINK
,
2439 static struct genl_family devlink_nl_family __ro_after_init
= {
2440 .name
= DEVLINK_GENL_NAME
,
2441 .version
= DEVLINK_GENL_VERSION
,
2442 .maxattr
= DEVLINK_ATTR_MAX
,
2444 .pre_doit
= devlink_nl_pre_doit
,
2445 .post_doit
= devlink_nl_post_doit
,
2446 .module
= THIS_MODULE
,
2447 .ops
= devlink_nl_ops
,
2448 .n_ops
= ARRAY_SIZE(devlink_nl_ops
),
2449 .mcgrps
= devlink_nl_mcgrps
,
2450 .n_mcgrps
= ARRAY_SIZE(devlink_nl_mcgrps
),
2454 * devlink_alloc - Allocate new devlink instance resources
2457 * @priv_size: size of user private data
2459 * Allocate new devlink instance resources, including devlink index
2462 struct devlink
*devlink_alloc(const struct devlink_ops
*ops
, size_t priv_size
)
2464 struct devlink
*devlink
;
2466 devlink
= kzalloc(sizeof(*devlink
) + priv_size
, GFP_KERNEL
);
2470 devlink_net_set(devlink
, &init_net
);
2471 INIT_LIST_HEAD(&devlink
->port_list
);
2472 INIT_LIST_HEAD(&devlink
->sb_list
);
2473 INIT_LIST_HEAD_RCU(&devlink
->dpipe_table_list
);
2476 EXPORT_SYMBOL_GPL(devlink_alloc
);
2479 * devlink_register - Register devlink instance
2483 int devlink_register(struct devlink
*devlink
, struct device
*dev
)
2485 mutex_lock(&devlink_mutex
);
2487 list_add_tail(&devlink
->list
, &devlink_list
);
2488 devlink_notify(devlink
, DEVLINK_CMD_NEW
);
2489 mutex_unlock(&devlink_mutex
);
2492 EXPORT_SYMBOL_GPL(devlink_register
);
2495 * devlink_unregister - Unregister devlink instance
2499 void devlink_unregister(struct devlink
*devlink
)
2501 mutex_lock(&devlink_mutex
);
2502 devlink_notify(devlink
, DEVLINK_CMD_DEL
);
2503 list_del(&devlink
->list
);
2504 mutex_unlock(&devlink_mutex
);
2506 EXPORT_SYMBOL_GPL(devlink_unregister
);
2509 * devlink_free - Free devlink instance resources
2513 void devlink_free(struct devlink
*devlink
)
2517 EXPORT_SYMBOL_GPL(devlink_free
);
2520 * devlink_port_register - Register devlink port
2523 * @devlink_port: devlink port
2526 * Register devlink port with provided port index. User can use
2527 * any indexing, even hw-related one. devlink_port structure
2528 * is convenient to be embedded inside user driver private structure.
2529 * Note that the caller should take care of zeroing the devlink_port
2532 int devlink_port_register(struct devlink
*devlink
,
2533 struct devlink_port
*devlink_port
,
2534 unsigned int port_index
)
2536 mutex_lock(&devlink_port_mutex
);
2537 if (devlink_port_index_exists(devlink
, port_index
)) {
2538 mutex_unlock(&devlink_port_mutex
);
2541 devlink_port
->devlink
= devlink
;
2542 devlink_port
->index
= port_index
;
2543 devlink_port
->registered
= true;
2544 list_add_tail(&devlink_port
->list
, &devlink
->port_list
);
2545 mutex_unlock(&devlink_port_mutex
);
2546 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
2549 EXPORT_SYMBOL_GPL(devlink_port_register
);
2552 * devlink_port_unregister - Unregister devlink port
2554 * @devlink_port: devlink port
2556 void devlink_port_unregister(struct devlink_port
*devlink_port
)
2558 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_DEL
);
2559 mutex_lock(&devlink_port_mutex
);
2560 list_del(&devlink_port
->list
);
2561 mutex_unlock(&devlink_port_mutex
);
2563 EXPORT_SYMBOL_GPL(devlink_port_unregister
);
2565 static void __devlink_port_type_set(struct devlink_port
*devlink_port
,
2566 enum devlink_port_type type
,
2569 devlink_port
->type
= type
;
2570 devlink_port
->type_dev
= type_dev
;
2571 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
2575 * devlink_port_type_eth_set - Set port type to Ethernet
2577 * @devlink_port: devlink port
2578 * @netdev: related netdevice
2580 void devlink_port_type_eth_set(struct devlink_port
*devlink_port
,
2581 struct net_device
*netdev
)
2583 return __devlink_port_type_set(devlink_port
,
2584 DEVLINK_PORT_TYPE_ETH
, netdev
);
2586 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set
);
2589 * devlink_port_type_ib_set - Set port type to InfiniBand
2591 * @devlink_port: devlink port
2592 * @ibdev: related IB device
2594 void devlink_port_type_ib_set(struct devlink_port
*devlink_port
,
2595 struct ib_device
*ibdev
)
2597 return __devlink_port_type_set(devlink_port
,
2598 DEVLINK_PORT_TYPE_IB
, ibdev
);
2600 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set
);
2603 * devlink_port_type_clear - Clear port type
2605 * @devlink_port: devlink port
2607 void devlink_port_type_clear(struct devlink_port
*devlink_port
)
2609 return __devlink_port_type_set(devlink_port
,
2610 DEVLINK_PORT_TYPE_NOTSET
, NULL
);
2612 EXPORT_SYMBOL_GPL(devlink_port_type_clear
);
2615 * devlink_port_split_set - Set port is split
2617 * @devlink_port: devlink port
2618 * @split_group: split group - identifies group split port is part of
2620 void devlink_port_split_set(struct devlink_port
*devlink_port
,
2623 devlink_port
->split
= true;
2624 devlink_port
->split_group
= split_group
;
2625 devlink_port_notify(devlink_port
, DEVLINK_CMD_PORT_NEW
);
2627 EXPORT_SYMBOL_GPL(devlink_port_split_set
);
2629 int devlink_sb_register(struct devlink
*devlink
, unsigned int sb_index
,
2630 u32 size
, u16 ingress_pools_count
,
2631 u16 egress_pools_count
, u16 ingress_tc_count
,
2632 u16 egress_tc_count
)
2634 struct devlink_sb
*devlink_sb
;
2637 mutex_lock(&devlink_mutex
);
2638 if (devlink_sb_index_exists(devlink
, sb_index
)) {
2643 devlink_sb
= kzalloc(sizeof(*devlink_sb
), GFP_KERNEL
);
2648 devlink_sb
->index
= sb_index
;
2649 devlink_sb
->size
= size
;
2650 devlink_sb
->ingress_pools_count
= ingress_pools_count
;
2651 devlink_sb
->egress_pools_count
= egress_pools_count
;
2652 devlink_sb
->ingress_tc_count
= ingress_tc_count
;
2653 devlink_sb
->egress_tc_count
= egress_tc_count
;
2654 list_add_tail(&devlink_sb
->list
, &devlink
->sb_list
);
2656 mutex_unlock(&devlink_mutex
);
2659 EXPORT_SYMBOL_GPL(devlink_sb_register
);
2661 void devlink_sb_unregister(struct devlink
*devlink
, unsigned int sb_index
)
2663 struct devlink_sb
*devlink_sb
;
2665 mutex_lock(&devlink_mutex
);
2666 devlink_sb
= devlink_sb_get_by_index(devlink
, sb_index
);
2667 WARN_ON(!devlink_sb
);
2668 list_del(&devlink_sb
->list
);
2669 mutex_unlock(&devlink_mutex
);
2672 EXPORT_SYMBOL_GPL(devlink_sb_unregister
);
2675 * devlink_dpipe_headers_register - register dpipe headers
2678 * @dpipe_headers: dpipe header array
2680 * Register the headers supported by hardware.
2682 int devlink_dpipe_headers_register(struct devlink
*devlink
,
2683 struct devlink_dpipe_headers
*dpipe_headers
)
2685 mutex_lock(&devlink_mutex
);
2686 devlink
->dpipe_headers
= dpipe_headers
;
2687 mutex_unlock(&devlink_mutex
);
2690 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register
);
2693 * devlink_dpipe_headers_unregister - unregister dpipe headers
2697 * Unregister the headers supported by hardware.
2699 void devlink_dpipe_headers_unregister(struct devlink
*devlink
)
2701 mutex_lock(&devlink_mutex
);
2702 devlink
->dpipe_headers
= NULL
;
2703 mutex_unlock(&devlink_mutex
);
2705 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister
);
2708 * devlink_dpipe_table_counter_enabled - check if counter allocation
2711 * @table_name: tables name
2713 * Used by driver to check if counter allocation is required.
2714 * After counter allocation is turned on the table entries
2715 * are updated to include counter statistics.
2717 * After that point on the driver must respect the counter
2718 * state so that each entry added to the table is added
2721 bool devlink_dpipe_table_counter_enabled(struct devlink
*devlink
,
2722 const char *table_name
)
2724 struct devlink_dpipe_table
*table
;
2728 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2732 enabled
= table
->counters_enabled
;
2736 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled
);
2739 * devlink_dpipe_table_register - register dpipe table
2742 * @table_name: table name
2743 * @table_ops: table ops
2745 * @counter_control_extern: external control for counters
2747 int devlink_dpipe_table_register(struct devlink
*devlink
,
2748 const char *table_name
,
2749 struct devlink_dpipe_table_ops
*table_ops
,
2750 void *priv
, bool counter_control_extern
)
2752 struct devlink_dpipe_table
*table
;
2754 if (devlink_dpipe_table_find(&devlink
->dpipe_table_list
, table_name
))
2757 if (WARN_ON(!table_ops
->size_get
))
2760 table
= kzalloc(sizeof(*table
), GFP_KERNEL
);
2764 table
->name
= table_name
;
2765 table
->table_ops
= table_ops
;
2767 table
->counter_control_extern
= counter_control_extern
;
2769 mutex_lock(&devlink_mutex
);
2770 list_add_tail_rcu(&table
->list
, &devlink
->dpipe_table_list
);
2771 mutex_unlock(&devlink_mutex
);
2774 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register
);
2777 * devlink_dpipe_table_unregister - unregister dpipe table
2780 * @table_name: table name
2782 void devlink_dpipe_table_unregister(struct devlink
*devlink
,
2783 const char *table_name
)
2785 struct devlink_dpipe_table
*table
;
2787 mutex_lock(&devlink_mutex
);
2788 table
= devlink_dpipe_table_find(&devlink
->dpipe_table_list
,
2792 list_del_rcu(&table
->list
);
2793 mutex_unlock(&devlink_mutex
);
2794 kfree_rcu(table
, rcu
);
2797 mutex_unlock(&devlink_mutex
);
2799 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister
);
2801 static int __init
devlink_module_init(void)
2803 return genl_register_family(&devlink_nl_family
);
2806 static void __exit
devlink_module_exit(void)
2808 genl_unregister_family(&devlink_nl_family
);
2811 module_init(devlink_module_init
);
2812 module_exit(devlink_module_exit
);
2814 MODULE_LICENSE("GPL v2");
2815 MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
2816 MODULE_DESCRIPTION("Network physical device Netlink interface");
2817 MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME
);