1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * net/core/devlink.c - Network physical/parent device Netlink interface
5 * Heavily inspired by net/wireless/
6 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
7 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
10 #include <linux/etherdevice.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/types.h>
14 #include <linux/slab.h>
15 #include <linux/gfp.h>
16 #include <linux/device.h>
17 #include <linux/list.h>
18 #include <linux/netdevice.h>
19 #include <linux/spinlock.h>
20 #include <linux/refcount.h>
21 #include <linux/workqueue.h>
22 #include <linux/u64_stats_sync.h>
23 #include <linux/timekeeping.h>
24 #include <rdma/ib_verbs.h>
25 #include <net/netlink.h>
26 #include <net/genetlink.h>
27 #include <net/rtnetlink.h>
28 #include <net/net_namespace.h>
30 #include <net/devlink.h>
32 #include "devl_internal.h"
34 const struct genl_small_ops devlink_nl_small_ops[40] = {
36 .cmd = DEVLINK_CMD_PORT_SET,
37 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
38 .doit = devlink_nl_cmd_port_set_doit,
39 .flags = GENL_ADMIN_PERM,
40 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
43 .cmd = DEVLINK_CMD_RATE_SET,
44 .doit = devlink_nl_cmd_rate_set_doit,
45 .flags = GENL_ADMIN_PERM,
48 .cmd = DEVLINK_CMD_RATE_NEW,
49 .doit = devlink_nl_cmd_rate_new_doit,
50 .flags = GENL_ADMIN_PERM,
53 .cmd = DEVLINK_CMD_RATE_DEL,
54 .doit = devlink_nl_cmd_rate_del_doit,
55 .flags = GENL_ADMIN_PERM,
58 .cmd = DEVLINK_CMD_PORT_SPLIT,
59 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
60 .doit = devlink_nl_cmd_port_split_doit,
61 .flags = GENL_ADMIN_PERM,
62 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
65 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
66 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67 .doit = devlink_nl_cmd_port_unsplit_doit,
68 .flags = GENL_ADMIN_PERM,
69 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
72 .cmd = DEVLINK_CMD_PORT_NEW,
73 .doit = devlink_nl_cmd_port_new_doit,
74 .flags = GENL_ADMIN_PERM,
77 .cmd = DEVLINK_CMD_PORT_DEL,
78 .doit = devlink_nl_cmd_port_del_doit,
79 .flags = GENL_ADMIN_PERM,
80 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
84 .cmd = DEVLINK_CMD_LINECARD_SET,
85 .doit = devlink_nl_cmd_linecard_set_doit,
86 .flags = GENL_ADMIN_PERM,
89 .cmd = DEVLINK_CMD_SB_POOL_SET,
90 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
91 .doit = devlink_nl_cmd_sb_pool_set_doit,
92 .flags = GENL_ADMIN_PERM,
95 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
96 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
97 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
98 .flags = GENL_ADMIN_PERM,
99 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
102 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
103 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
104 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
105 .flags = GENL_ADMIN_PERM,
106 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
109 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
110 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
111 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
112 .flags = GENL_ADMIN_PERM,
115 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
116 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
117 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
118 .flags = GENL_ADMIN_PERM,
121 .cmd = DEVLINK_CMD_ESWITCH_GET,
122 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
123 .doit = devlink_nl_cmd_eswitch_get_doit,
124 .flags = GENL_ADMIN_PERM,
127 .cmd = DEVLINK_CMD_ESWITCH_SET,
128 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
129 .doit = devlink_nl_cmd_eswitch_set_doit,
130 .flags = GENL_ADMIN_PERM,
133 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
134 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
135 .doit = devlink_nl_cmd_dpipe_table_get,
136 /* can be retrieved by unprivileged users */
139 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
140 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
141 .doit = devlink_nl_cmd_dpipe_entries_get,
142 /* can be retrieved by unprivileged users */
145 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
146 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
147 .doit = devlink_nl_cmd_dpipe_headers_get,
148 /* can be retrieved by unprivileged users */
151 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
152 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
153 .doit = devlink_nl_cmd_dpipe_table_counters_set,
154 .flags = GENL_ADMIN_PERM,
157 .cmd = DEVLINK_CMD_RESOURCE_SET,
158 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
159 .doit = devlink_nl_cmd_resource_set,
160 .flags = GENL_ADMIN_PERM,
163 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
164 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
165 .doit = devlink_nl_cmd_resource_dump,
166 /* can be retrieved by unprivileged users */
169 .cmd = DEVLINK_CMD_RELOAD,
170 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
171 .doit = devlink_nl_cmd_reload,
172 .flags = GENL_ADMIN_PERM,
175 .cmd = DEVLINK_CMD_PARAM_SET,
176 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
177 .doit = devlink_nl_cmd_param_set_doit,
178 .flags = GENL_ADMIN_PERM,
181 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
182 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
183 .doit = devlink_nl_cmd_port_param_get_doit,
184 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
185 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
186 /* can be retrieved by unprivileged users */
189 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
190 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
191 .doit = devlink_nl_cmd_port_param_set_doit,
192 .flags = GENL_ADMIN_PERM,
193 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
196 .cmd = DEVLINK_CMD_REGION_NEW,
197 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
198 .doit = devlink_nl_cmd_region_new,
199 .flags = GENL_ADMIN_PERM,
202 .cmd = DEVLINK_CMD_REGION_DEL,
203 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
204 .doit = devlink_nl_cmd_region_del,
205 .flags = GENL_ADMIN_PERM,
208 .cmd = DEVLINK_CMD_REGION_READ,
209 .validate = GENL_DONT_VALIDATE_STRICT |
210 GENL_DONT_VALIDATE_DUMP_STRICT,
211 .dumpit = devlink_nl_cmd_region_read_dumpit,
212 .flags = GENL_ADMIN_PERM,
215 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
216 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
217 .doit = devlink_nl_cmd_health_reporter_set_doit,
218 .flags = GENL_ADMIN_PERM,
219 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
222 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
223 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
224 .doit = devlink_nl_cmd_health_reporter_recover_doit,
225 .flags = GENL_ADMIN_PERM,
226 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
229 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
230 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
231 .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
232 .flags = GENL_ADMIN_PERM,
233 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
236 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
237 .validate = GENL_DONT_VALIDATE_STRICT |
238 GENL_DONT_VALIDATE_DUMP_STRICT,
239 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
240 .flags = GENL_ADMIN_PERM,
243 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
244 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
245 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
246 .flags = GENL_ADMIN_PERM,
247 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
250 .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST,
251 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
252 .doit = devlink_nl_cmd_health_reporter_test_doit,
253 .flags = GENL_ADMIN_PERM,
254 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
257 .cmd = DEVLINK_CMD_FLASH_UPDATE,
258 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
259 .doit = devlink_nl_cmd_flash_update,
260 .flags = GENL_ADMIN_PERM,
263 .cmd = DEVLINK_CMD_TRAP_SET,
264 .doit = devlink_nl_cmd_trap_set_doit,
265 .flags = GENL_ADMIN_PERM,
268 .cmd = DEVLINK_CMD_TRAP_GROUP_SET,
269 .doit = devlink_nl_cmd_trap_group_set_doit,
270 .flags = GENL_ADMIN_PERM,
273 .cmd = DEVLINK_CMD_TRAP_POLICER_SET,
274 .doit = devlink_nl_cmd_trap_policer_set_doit,
275 .flags = GENL_ADMIN_PERM,
278 .cmd = DEVLINK_CMD_SELFTESTS_RUN,
279 .doit = devlink_nl_cmd_selftests_run,
280 .flags = GENL_ADMIN_PERM,
282 /* -- No new ops here! Use split ops going forward! -- */
285 void devlink_notify_register(struct devlink *devlink)
287 devlink_notify(devlink, DEVLINK_CMD_NEW);
288 devlink_linecards_notify_register(devlink);
289 devlink_ports_notify_register(devlink);
290 devlink_trap_policers_notify_register(devlink);
291 devlink_trap_groups_notify_register(devlink);
292 devlink_traps_notify_register(devlink);
293 devlink_rates_notify_register(devlink);
294 devlink_regions_notify_register(devlink);
295 devlink_params_notify_register(devlink);
298 void devlink_notify_unregister(struct devlink *devlink)
300 devlink_params_notify_unregister(devlink);
301 devlink_regions_notify_unregister(devlink);
302 devlink_rates_notify_unregister(devlink);
303 devlink_traps_notify_unregister(devlink);
304 devlink_trap_groups_notify_unregister(devlink);
305 devlink_trap_policers_notify_unregister(devlink);
306 devlink_ports_notify_unregister(devlink);
307 devlink_linecards_notify_unregister(devlink);
308 devlink_notify(devlink, DEVLINK_CMD_DEL);