b2e592a198c07736cfd03e577b4ff8e85fa3ca61
[cascardo/linux.git] / net / core / devlink.c
1 /*
2  * net/core/devlink.c - Network physical/parent device Netlink interface
3  *
4  * Heavily inspired by net/wireless/
5  * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
6  * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
7  *
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.
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/types.h>
17 #include <linux/slab.h>
18 #include <linux/gfp.h>
19 #include <linux/device.h>
20 #include <linux/list.h>
21 #include <linux/netdevice.h>
22 #include <rdma/ib_verbs.h>
23 #include <net/netlink.h>
24 #include <net/genetlink.h>
25 #include <net/rtnetlink.h>
26 #include <net/net_namespace.h>
27 #include <net/sock.h>
28 #include <net/devlink.h>
29
30 static LIST_HEAD(devlink_list);
31
32 /* devlink_mutex
33  *
34  * An overall lock guarding every operation coming from userspace.
35  * It also guards devlink devices list and it is taken when
36  * driver registers/unregisters it.
37  */
38 static DEFINE_MUTEX(devlink_mutex);
39
40 /* devlink_port_mutex
41  *
42  * Shared lock to guard lists of ports in all devlink devices.
43  */
44 static DEFINE_MUTEX(devlink_port_mutex);
45
46 static struct net *devlink_net(const struct devlink *devlink)
47 {
48         return read_pnet(&devlink->_net);
49 }
50
51 static void devlink_net_set(struct devlink *devlink, struct net *net)
52 {
53         write_pnet(&devlink->_net, net);
54 }
55
56 static struct devlink *devlink_get_from_attrs(struct net *net,
57                                               struct nlattr **attrs)
58 {
59         struct devlink *devlink;
60         char *busname;
61         char *devname;
62
63         if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
64                 return ERR_PTR(-EINVAL);
65
66         busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
67         devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
68
69         list_for_each_entry(devlink, &devlink_list, list) {
70                 if (strcmp(devlink->dev->bus->name, busname) == 0 &&
71                     strcmp(dev_name(devlink->dev), devname) == 0 &&
72                     net_eq(devlink_net(devlink), net))
73                         return devlink;
74         }
75
76         return ERR_PTR(-ENODEV);
77 }
78
79 static struct devlink *devlink_get_from_info(struct genl_info *info)
80 {
81         return devlink_get_from_attrs(genl_info_net(info), info->attrs);
82 }
83
84 static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
85                                                       int port_index)
86 {
87         struct devlink_port *devlink_port;
88
89         list_for_each_entry(devlink_port, &devlink->port_list, list) {
90                 if (devlink_port->index == port_index)
91                         return devlink_port;
92         }
93         return NULL;
94 }
95
96 static bool devlink_port_index_exists(struct devlink *devlink, int port_index)
97 {
98         return devlink_port_get_by_index(devlink, port_index);
99 }
100
101 static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
102                                                         struct nlattr **attrs)
103 {
104         if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
105                 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
106                 struct devlink_port *devlink_port;
107
108                 devlink_port = devlink_port_get_by_index(devlink, port_index);
109                 if (!devlink_port)
110                         return ERR_PTR(-ENODEV);
111                 return devlink_port;
112         }
113         return ERR_PTR(-EINVAL);
114 }
115
116 static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
117                                                        struct genl_info *info)
118 {
119         return devlink_port_get_from_attrs(devlink, info->attrs);
120 }
121
122 struct devlink_sb {
123         struct list_head list;
124         unsigned int index;
125         u32 size;
126         u16 ingress_pools_count;
127         u16 egress_pools_count;
128         u16 ingress_tc_count;
129         u16 egress_tc_count;
130 };
131
132 static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
133 {
134         return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
135 }
136
137 static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
138                                                   unsigned int sb_index)
139 {
140         struct devlink_sb *devlink_sb;
141
142         list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
143                 if (devlink_sb->index == sb_index)
144                         return devlink_sb;
145         }
146         return NULL;
147 }
148
149 static bool devlink_sb_index_exists(struct devlink *devlink,
150                                     unsigned int sb_index)
151 {
152         return devlink_sb_get_by_index(devlink, sb_index);
153 }
154
155 static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
156                                                     struct nlattr **attrs)
157 {
158         if (attrs[DEVLINK_ATTR_SB_INDEX]) {
159                 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
160                 struct devlink_sb *devlink_sb;
161
162                 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
163                 if (!devlink_sb)
164                         return ERR_PTR(-ENODEV);
165                 return devlink_sb;
166         }
167         return ERR_PTR(-EINVAL);
168 }
169
170 static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
171                                                    struct genl_info *info)
172 {
173         return devlink_sb_get_from_attrs(devlink, info->attrs);
174 }
175
176 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
177                                                 struct nlattr **attrs,
178                                                 u16 *p_pool_index)
179 {
180         u16 val;
181
182         if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
183                 return -EINVAL;
184
185         val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
186         if (val >= devlink_sb_pool_count(devlink_sb))
187                 return -EINVAL;
188         *p_pool_index = val;
189         return 0;
190 }
191
192 static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
193                                                struct genl_info *info,
194                                                u16 *p_pool_index)
195 {
196         return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
197                                                     p_pool_index);
198 }
199
200 static int
201 devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
202                                     enum devlink_sb_pool_type *p_pool_type)
203 {
204         u8 val;
205
206         if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
207                 return -EINVAL;
208
209         val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
210         if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
211             val != DEVLINK_SB_POOL_TYPE_EGRESS)
212                 return -EINVAL;
213         *p_pool_type = val;
214         return 0;
215 }
216
217 static int
218 devlink_sb_pool_type_get_from_info(struct genl_info *info,
219                                    enum devlink_sb_pool_type *p_pool_type)
220 {
221         return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
222 }
223
224 static int
225 devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
226                                   enum devlink_sb_threshold_type *p_th_type)
227 {
228         u8 val;
229
230         if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
231                 return -EINVAL;
232
233         val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
234         if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
235             val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
236                 return -EINVAL;
237         *p_th_type = val;
238         return 0;
239 }
240
241 static int
242 devlink_sb_th_type_get_from_info(struct genl_info *info,
243                                  enum devlink_sb_threshold_type *p_th_type)
244 {
245         return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
246 }
247
248 static int
249 devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
250                                    struct nlattr **attrs,
251                                    enum devlink_sb_pool_type pool_type,
252                                    u16 *p_tc_index)
253 {
254         u16 val;
255
256         if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
257                 return -EINVAL;
258
259         val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
260         if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
261             val >= devlink_sb->ingress_tc_count)
262                 return -EINVAL;
263         if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
264             val >= devlink_sb->egress_tc_count)
265                 return -EINVAL;
266         *p_tc_index = val;
267         return 0;
268 }
269
270 static int
271 devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
272                                   struct genl_info *info,
273                                   enum devlink_sb_pool_type pool_type,
274                                   u16 *p_tc_index)
275 {
276         return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
277                                                   pool_type, p_tc_index);
278 }
279
280 #define DEVLINK_NL_FLAG_NEED_DEVLINK    BIT(0)
281 #define DEVLINK_NL_FLAG_NEED_PORT       BIT(1)
282 #define DEVLINK_NL_FLAG_NEED_SB         BIT(2)
283 #define DEVLINK_NL_FLAG_LOCK_PORTS      BIT(3)
284         /* port is not needed but we need to ensure they don't
285          * change in the middle of command
286          */
287
288 static int devlink_nl_pre_doit(const struct genl_ops *ops,
289                                struct sk_buff *skb, struct genl_info *info)
290 {
291         struct devlink *devlink;
292
293         mutex_lock(&devlink_mutex);
294         devlink = devlink_get_from_info(info);
295         if (IS_ERR(devlink)) {
296                 mutex_unlock(&devlink_mutex);
297                 return PTR_ERR(devlink);
298         }
299         if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) {
300                 info->user_ptr[0] = devlink;
301         } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
302                 struct devlink_port *devlink_port;
303
304                 mutex_lock(&devlink_port_mutex);
305                 devlink_port = devlink_port_get_from_info(devlink, info);
306                 if (IS_ERR(devlink_port)) {
307                         mutex_unlock(&devlink_port_mutex);
308                         mutex_unlock(&devlink_mutex);
309                         return PTR_ERR(devlink_port);
310                 }
311                 info->user_ptr[0] = devlink_port;
312         }
313         if (ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS) {
314                 mutex_lock(&devlink_port_mutex);
315         }
316         if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) {
317                 struct devlink_sb *devlink_sb;
318
319                 devlink_sb = devlink_sb_get_from_info(devlink, info);
320                 if (IS_ERR(devlink_sb)) {
321                         if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT)
322                                 mutex_unlock(&devlink_port_mutex);
323                         mutex_unlock(&devlink_mutex);
324                         return PTR_ERR(devlink_sb);
325                 }
326                 info->user_ptr[1] = devlink_sb;
327         }
328         return 0;
329 }
330
331 static void devlink_nl_post_doit(const struct genl_ops *ops,
332                                  struct sk_buff *skb, struct genl_info *info)
333 {
334         if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT ||
335             ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS)
336                 mutex_unlock(&devlink_port_mutex);
337         mutex_unlock(&devlink_mutex);
338 }
339
340 static struct genl_family devlink_nl_family = {
341         .id             = GENL_ID_GENERATE,
342         .name           = DEVLINK_GENL_NAME,
343         .version        = DEVLINK_GENL_VERSION,
344         .maxattr        = DEVLINK_ATTR_MAX,
345         .netnsok        = true,
346         .pre_doit       = devlink_nl_pre_doit,
347         .post_doit      = devlink_nl_post_doit,
348 };
349
350 enum devlink_multicast_groups {
351         DEVLINK_MCGRP_CONFIG,
352 };
353
354 static const struct genl_multicast_group devlink_nl_mcgrps[] = {
355         [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
356 };
357
358 static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
359 {
360         if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
361                 return -EMSGSIZE;
362         if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
363                 return -EMSGSIZE;
364         return 0;
365 }
366
367 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
368                            enum devlink_command cmd, u32 portid,
369                            u32 seq, int flags)
370 {
371         void *hdr;
372
373         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
374         if (!hdr)
375                 return -EMSGSIZE;
376
377         if (devlink_nl_put_handle(msg, devlink))
378                 goto nla_put_failure;
379
380         genlmsg_end(msg, hdr);
381         return 0;
382
383 nla_put_failure:
384         genlmsg_cancel(msg, hdr);
385         return -EMSGSIZE;
386 }
387
388 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
389 {
390         struct sk_buff *msg;
391         int err;
392
393         WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
394
395         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
396         if (!msg)
397                 return;
398
399         err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
400         if (err) {
401                 nlmsg_free(msg);
402                 return;
403         }
404
405         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
406                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
407 }
408
409 static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
410                                 struct devlink_port *devlink_port,
411                                 enum devlink_command cmd, u32 portid,
412                                 u32 seq, int flags)
413 {
414         void *hdr;
415
416         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
417         if (!hdr)
418                 return -EMSGSIZE;
419
420         if (devlink_nl_put_handle(msg, devlink))
421                 goto nla_put_failure;
422         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
423                 goto nla_put_failure;
424         if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
425                 goto nla_put_failure;
426         if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
427             nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
428                         devlink_port->desired_type))
429                 goto nla_put_failure;
430         if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
431                 struct net_device *netdev = devlink_port->type_dev;
432
433                 if (netdev &&
434                     (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
435                                  netdev->ifindex) ||
436                      nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
437                                     netdev->name)))
438                         goto nla_put_failure;
439         }
440         if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
441                 struct ib_device *ibdev = devlink_port->type_dev;
442
443                 if (ibdev &&
444                     nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
445                                    ibdev->name))
446                         goto nla_put_failure;
447         }
448         if (devlink_port->split &&
449             nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
450                         devlink_port->split_group))
451                 goto nla_put_failure;
452
453         genlmsg_end(msg, hdr);
454         return 0;
455
456 nla_put_failure:
457         genlmsg_cancel(msg, hdr);
458         return -EMSGSIZE;
459 }
460
461 static void devlink_port_notify(struct devlink_port *devlink_port,
462                                 enum devlink_command cmd)
463 {
464         struct devlink *devlink = devlink_port->devlink;
465         struct sk_buff *msg;
466         int err;
467
468         if (!devlink_port->registered)
469                 return;
470
471         WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
472
473         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
474         if (!msg)
475                 return;
476
477         err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);
478         if (err) {
479                 nlmsg_free(msg);
480                 return;
481         }
482
483         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
484                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
485 }
486
487 static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
488 {
489         struct devlink *devlink = info->user_ptr[0];
490         struct sk_buff *msg;
491         int err;
492
493         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
494         if (!msg)
495                 return -ENOMEM;
496
497         err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
498                               info->snd_portid, info->snd_seq, 0);
499         if (err) {
500                 nlmsg_free(msg);
501                 return err;
502         }
503
504         return genlmsg_reply(msg, info);
505 }
506
507 static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
508                                      struct netlink_callback *cb)
509 {
510         struct devlink *devlink;
511         int start = cb->args[0];
512         int idx = 0;
513         int err;
514
515         mutex_lock(&devlink_mutex);
516         list_for_each_entry(devlink, &devlink_list, list) {
517                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
518                         continue;
519                 if (idx < start) {
520                         idx++;
521                         continue;
522                 }
523                 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
524                                       NETLINK_CB(cb->skb).portid,
525                                       cb->nlh->nlmsg_seq, NLM_F_MULTI);
526                 if (err)
527                         goto out;
528                 idx++;
529         }
530 out:
531         mutex_unlock(&devlink_mutex);
532
533         cb->args[0] = idx;
534         return msg->len;
535 }
536
537 static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
538                                         struct genl_info *info)
539 {
540         struct devlink_port *devlink_port = info->user_ptr[0];
541         struct devlink *devlink = devlink_port->devlink;
542         struct sk_buff *msg;
543         int err;
544
545         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
546         if (!msg)
547                 return -ENOMEM;
548
549         err = devlink_nl_port_fill(msg, devlink, devlink_port,
550                                    DEVLINK_CMD_PORT_NEW,
551                                    info->snd_portid, info->snd_seq, 0);
552         if (err) {
553                 nlmsg_free(msg);
554                 return err;
555         }
556
557         return genlmsg_reply(msg, info);
558 }
559
560 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
561                                           struct netlink_callback *cb)
562 {
563         struct devlink *devlink;
564         struct devlink_port *devlink_port;
565         int start = cb->args[0];
566         int idx = 0;
567         int err;
568
569         mutex_lock(&devlink_mutex);
570         mutex_lock(&devlink_port_mutex);
571         list_for_each_entry(devlink, &devlink_list, list) {
572                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
573                         continue;
574                 list_for_each_entry(devlink_port, &devlink->port_list, list) {
575                         if (idx < start) {
576                                 idx++;
577                                 continue;
578                         }
579                         err = devlink_nl_port_fill(msg, devlink, devlink_port,
580                                                    DEVLINK_CMD_NEW,
581                                                    NETLINK_CB(cb->skb).portid,
582                                                    cb->nlh->nlmsg_seq,
583                                                    NLM_F_MULTI);
584                         if (err)
585                                 goto out;
586                         idx++;
587                 }
588         }
589 out:
590         mutex_unlock(&devlink_port_mutex);
591         mutex_unlock(&devlink_mutex);
592
593         cb->args[0] = idx;
594         return msg->len;
595 }
596
597 static int devlink_port_type_set(struct devlink *devlink,
598                                  struct devlink_port *devlink_port,
599                                  enum devlink_port_type port_type)
600
601 {
602         int err;
603
604         if (devlink->ops && devlink->ops->port_type_set) {
605                 if (port_type == DEVLINK_PORT_TYPE_NOTSET)
606                         return -EINVAL;
607                 err = devlink->ops->port_type_set(devlink_port, port_type);
608                 if (err)
609                         return err;
610                 devlink_port->desired_type = port_type;
611                 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
612                 return 0;
613         }
614         return -EOPNOTSUPP;
615 }
616
617 static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
618                                         struct genl_info *info)
619 {
620         struct devlink_port *devlink_port = info->user_ptr[0];
621         struct devlink *devlink = devlink_port->devlink;
622         int err;
623
624         if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
625                 enum devlink_port_type port_type;
626
627                 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
628                 err = devlink_port_type_set(devlink, devlink_port, port_type);
629                 if (err)
630                         return err;
631         }
632         return 0;
633 }
634
635 static int devlink_port_split(struct devlink *devlink,
636                               u32 port_index, u32 count)
637
638 {
639         if (devlink->ops && devlink->ops->port_split)
640                 return devlink->ops->port_split(devlink, port_index, count);
641         return -EOPNOTSUPP;
642 }
643
644 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
645                                           struct genl_info *info)
646 {
647         struct devlink *devlink = info->user_ptr[0];
648         u32 port_index;
649         u32 count;
650
651         if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
652             !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
653                 return -EINVAL;
654
655         port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
656         count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
657         return devlink_port_split(devlink, port_index, count);
658 }
659
660 static int devlink_port_unsplit(struct devlink *devlink, u32 port_index)
661
662 {
663         if (devlink->ops && devlink->ops->port_unsplit)
664                 return devlink->ops->port_unsplit(devlink, port_index);
665         return -EOPNOTSUPP;
666 }
667
668 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
669                                             struct genl_info *info)
670 {
671         struct devlink *devlink = info->user_ptr[0];
672         u32 port_index;
673
674         if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
675                 return -EINVAL;
676
677         port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
678         return devlink_port_unsplit(devlink, port_index);
679 }
680
681 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
682                               struct devlink_sb *devlink_sb,
683                               enum devlink_command cmd, u32 portid,
684                               u32 seq, int flags)
685 {
686         void *hdr;
687
688         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
689         if (!hdr)
690                 return -EMSGSIZE;
691
692         if (devlink_nl_put_handle(msg, devlink))
693                 goto nla_put_failure;
694         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
695                 goto nla_put_failure;
696         if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
697                 goto nla_put_failure;
698         if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
699                         devlink_sb->ingress_pools_count))
700                 goto nla_put_failure;
701         if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
702                         devlink_sb->egress_pools_count))
703                 goto nla_put_failure;
704         if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
705                         devlink_sb->ingress_tc_count))
706                 goto nla_put_failure;
707         if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
708                         devlink_sb->egress_tc_count))
709                 goto nla_put_failure;
710
711         genlmsg_end(msg, hdr);
712         return 0;
713
714 nla_put_failure:
715         genlmsg_cancel(msg, hdr);
716         return -EMSGSIZE;
717 }
718
719 static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
720                                       struct genl_info *info)
721 {
722         struct devlink *devlink = info->user_ptr[0];
723         struct devlink_sb *devlink_sb = info->user_ptr[1];
724         struct sk_buff *msg;
725         int err;
726
727         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
728         if (!msg)
729                 return -ENOMEM;
730
731         err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
732                                  DEVLINK_CMD_SB_NEW,
733                                  info->snd_portid, info->snd_seq, 0);
734         if (err) {
735                 nlmsg_free(msg);
736                 return err;
737         }
738
739         return genlmsg_reply(msg, info);
740 }
741
742 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
743                                         struct netlink_callback *cb)
744 {
745         struct devlink *devlink;
746         struct devlink_sb *devlink_sb;
747         int start = cb->args[0];
748         int idx = 0;
749         int err;
750
751         mutex_lock(&devlink_mutex);
752         list_for_each_entry(devlink, &devlink_list, list) {
753                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
754                         continue;
755                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
756                         if (idx < start) {
757                                 idx++;
758                                 continue;
759                         }
760                         err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
761                                                  DEVLINK_CMD_SB_NEW,
762                                                  NETLINK_CB(cb->skb).portid,
763                                                  cb->nlh->nlmsg_seq,
764                                                  NLM_F_MULTI);
765                         if (err)
766                                 goto out;
767                         idx++;
768                 }
769         }
770 out:
771         mutex_unlock(&devlink_mutex);
772
773         cb->args[0] = idx;
774         return msg->len;
775 }
776
777 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
778                                    struct devlink_sb *devlink_sb,
779                                    u16 pool_index, enum devlink_command cmd,
780                                    u32 portid, u32 seq, int flags)
781 {
782         struct devlink_sb_pool_info pool_info;
783         void *hdr;
784         int err;
785
786         err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
787                                         pool_index, &pool_info);
788         if (err)
789                 return err;
790
791         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
792         if (!hdr)
793                 return -EMSGSIZE;
794
795         if (devlink_nl_put_handle(msg, devlink))
796                 goto nla_put_failure;
797         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
798                 goto nla_put_failure;
799         if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
800                 goto nla_put_failure;
801         if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
802                 goto nla_put_failure;
803         if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
804                 goto nla_put_failure;
805         if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
806                        pool_info.threshold_type))
807                 goto nla_put_failure;
808
809         genlmsg_end(msg, hdr);
810         return 0;
811
812 nla_put_failure:
813         genlmsg_cancel(msg, hdr);
814         return -EMSGSIZE;
815 }
816
817 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
818                                            struct genl_info *info)
819 {
820         struct devlink *devlink = info->user_ptr[0];
821         struct devlink_sb *devlink_sb = info->user_ptr[1];
822         struct sk_buff *msg;
823         u16 pool_index;
824         int err;
825
826         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
827                                                   &pool_index);
828         if (err)
829                 return err;
830
831         if (!devlink->ops || !devlink->ops->sb_pool_get)
832                 return -EOPNOTSUPP;
833
834         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
835         if (!msg)
836                 return -ENOMEM;
837
838         err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
839                                       DEVLINK_CMD_SB_POOL_NEW,
840                                       info->snd_portid, info->snd_seq, 0);
841         if (err) {
842                 nlmsg_free(msg);
843                 return err;
844         }
845
846         return genlmsg_reply(msg, info);
847 }
848
849 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
850                                 struct devlink *devlink,
851                                 struct devlink_sb *devlink_sb,
852                                 u32 portid, u32 seq)
853 {
854         u16 pool_count = devlink_sb_pool_count(devlink_sb);
855         u16 pool_index;
856         int err;
857
858         for (pool_index = 0; pool_index < pool_count; pool_index++) {
859                 if (*p_idx < start) {
860                         (*p_idx)++;
861                         continue;
862                 }
863                 err = devlink_nl_sb_pool_fill(msg, devlink,
864                                               devlink_sb,
865                                               pool_index,
866                                               DEVLINK_CMD_SB_POOL_NEW,
867                                               portid, seq, NLM_F_MULTI);
868                 if (err)
869                         return err;
870                 (*p_idx)++;
871         }
872         return 0;
873 }
874
875 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
876                                              struct netlink_callback *cb)
877 {
878         struct devlink *devlink;
879         struct devlink_sb *devlink_sb;
880         int start = cb->args[0];
881         int idx = 0;
882         int err;
883
884         mutex_lock(&devlink_mutex);
885         list_for_each_entry(devlink, &devlink_list, list) {
886                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
887                     !devlink->ops || !devlink->ops->sb_pool_get)
888                         continue;
889                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
890                         err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
891                                                    devlink_sb,
892                                                    NETLINK_CB(cb->skb).portid,
893                                                    cb->nlh->nlmsg_seq);
894                         if (err && err != -EOPNOTSUPP)
895                                 goto out;
896                 }
897         }
898 out:
899         mutex_unlock(&devlink_mutex);
900
901         cb->args[0] = idx;
902         return msg->len;
903 }
904
905 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
906                                u16 pool_index, u32 size,
907                                enum devlink_sb_threshold_type threshold_type)
908
909 {
910         const struct devlink_ops *ops = devlink->ops;
911
912         if (ops && ops->sb_pool_set)
913                 return ops->sb_pool_set(devlink, sb_index, pool_index,
914                                         size, threshold_type);
915         return -EOPNOTSUPP;
916 }
917
918 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
919                                            struct genl_info *info)
920 {
921         struct devlink *devlink = info->user_ptr[0];
922         struct devlink_sb *devlink_sb = info->user_ptr[1];
923         enum devlink_sb_threshold_type threshold_type;
924         u16 pool_index;
925         u32 size;
926         int err;
927
928         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
929                                                   &pool_index);
930         if (err)
931                 return err;
932
933         err = devlink_sb_th_type_get_from_info(info, &threshold_type);
934         if (err)
935                 return err;
936
937         if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
938                 return -EINVAL;
939
940         size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
941         return devlink_sb_pool_set(devlink, devlink_sb->index,
942                                    pool_index, size, threshold_type);
943 }
944
945 static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
946                                         struct devlink *devlink,
947                                         struct devlink_port *devlink_port,
948                                         struct devlink_sb *devlink_sb,
949                                         u16 pool_index,
950                                         enum devlink_command cmd,
951                                         u32 portid, u32 seq, int flags)
952 {
953         const struct devlink_ops *ops = devlink->ops;
954         u32 threshold;
955         void *hdr;
956         int err;
957
958         err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
959                                     pool_index, &threshold);
960         if (err)
961                 return err;
962
963         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
964         if (!hdr)
965                 return -EMSGSIZE;
966
967         if (devlink_nl_put_handle(msg, devlink))
968                 goto nla_put_failure;
969         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
970                 goto nla_put_failure;
971         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
972                 goto nla_put_failure;
973         if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
974                 goto nla_put_failure;
975         if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
976                 goto nla_put_failure;
977
978         if (ops->sb_occ_port_pool_get) {
979                 u32 cur;
980                 u32 max;
981
982                 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
983                                                 pool_index, &cur, &max);
984                 if (err && err != -EOPNOTSUPP)
985                         return err;
986                 if (!err) {
987                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
988                                 goto nla_put_failure;
989                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
990                                 goto nla_put_failure;
991                 }
992         }
993
994         genlmsg_end(msg, hdr);
995         return 0;
996
997 nla_put_failure:
998         genlmsg_cancel(msg, hdr);
999         return -EMSGSIZE;
1000 }
1001
1002 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
1003                                                 struct genl_info *info)
1004 {
1005         struct devlink_port *devlink_port = info->user_ptr[0];
1006         struct devlink *devlink = devlink_port->devlink;
1007         struct devlink_sb *devlink_sb = info->user_ptr[1];
1008         struct sk_buff *msg;
1009         u16 pool_index;
1010         int err;
1011
1012         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1013                                                   &pool_index);
1014         if (err)
1015                 return err;
1016
1017         if (!devlink->ops || !devlink->ops->sb_port_pool_get)
1018                 return -EOPNOTSUPP;
1019
1020         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1021         if (!msg)
1022                 return -ENOMEM;
1023
1024         err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
1025                                            devlink_sb, pool_index,
1026                                            DEVLINK_CMD_SB_PORT_POOL_NEW,
1027                                            info->snd_portid, info->snd_seq, 0);
1028         if (err) {
1029                 nlmsg_free(msg);
1030                 return err;
1031         }
1032
1033         return genlmsg_reply(msg, info);
1034 }
1035
1036 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1037                                      struct devlink *devlink,
1038                                      struct devlink_sb *devlink_sb,
1039                                      u32 portid, u32 seq)
1040 {
1041         struct devlink_port *devlink_port;
1042         u16 pool_count = devlink_sb_pool_count(devlink_sb);
1043         u16 pool_index;
1044         int err;
1045
1046         list_for_each_entry(devlink_port, &devlink->port_list, list) {
1047                 for (pool_index = 0; pool_index < pool_count; pool_index++) {
1048                         if (*p_idx < start) {
1049                                 (*p_idx)++;
1050                                 continue;
1051                         }
1052                         err = devlink_nl_sb_port_pool_fill(msg, devlink,
1053                                                            devlink_port,
1054                                                            devlink_sb,
1055                                                            pool_index,
1056                                                            DEVLINK_CMD_SB_PORT_POOL_NEW,
1057                                                            portid, seq,
1058                                                            NLM_F_MULTI);
1059                         if (err)
1060                                 return err;
1061                         (*p_idx)++;
1062                 }
1063         }
1064         return 0;
1065 }
1066
1067 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
1068                                                   struct netlink_callback *cb)
1069 {
1070         struct devlink *devlink;
1071         struct devlink_sb *devlink_sb;
1072         int start = cb->args[0];
1073         int idx = 0;
1074         int err;
1075
1076         mutex_lock(&devlink_mutex);
1077         mutex_lock(&devlink_port_mutex);
1078         list_for_each_entry(devlink, &devlink_list, list) {
1079                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1080                     !devlink->ops || !devlink->ops->sb_port_pool_get)
1081                         continue;
1082                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1083                         err = __sb_port_pool_get_dumpit(msg, start, &idx,
1084                                                         devlink, devlink_sb,
1085                                                         NETLINK_CB(cb->skb).portid,
1086                                                         cb->nlh->nlmsg_seq);
1087                         if (err && err != -EOPNOTSUPP)
1088                                 goto out;
1089                 }
1090         }
1091 out:
1092         mutex_unlock(&devlink_port_mutex);
1093         mutex_unlock(&devlink_mutex);
1094
1095         cb->args[0] = idx;
1096         return msg->len;
1097 }
1098
1099 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
1100                                     unsigned int sb_index, u16 pool_index,
1101                                     u32 threshold)
1102
1103 {
1104         const struct devlink_ops *ops = devlink_port->devlink->ops;
1105
1106         if (ops && ops->sb_port_pool_set)
1107                 return ops->sb_port_pool_set(devlink_port, sb_index,
1108                                              pool_index, threshold);
1109         return -EOPNOTSUPP;
1110 }
1111
1112 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
1113                                                 struct genl_info *info)
1114 {
1115         struct devlink_port *devlink_port = info->user_ptr[0];
1116         struct devlink_sb *devlink_sb = info->user_ptr[1];
1117         u16 pool_index;
1118         u32 threshold;
1119         int err;
1120
1121         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1122                                                   &pool_index);
1123         if (err)
1124                 return err;
1125
1126         if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1127                 return -EINVAL;
1128
1129         threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1130         return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
1131                                         pool_index, threshold);
1132 }
1133
1134 static int
1135 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
1136                                 struct devlink_port *devlink_port,
1137                                 struct devlink_sb *devlink_sb, u16 tc_index,
1138                                 enum devlink_sb_pool_type pool_type,
1139                                 enum devlink_command cmd,
1140                                 u32 portid, u32 seq, int flags)
1141 {
1142         const struct devlink_ops *ops = devlink->ops;
1143         u16 pool_index;
1144         u32 threshold;
1145         void *hdr;
1146         int err;
1147
1148         err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
1149                                        tc_index, pool_type,
1150                                        &pool_index, &threshold);
1151         if (err)
1152                 return err;
1153
1154         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1155         if (!hdr)
1156                 return -EMSGSIZE;
1157
1158         if (devlink_nl_put_handle(msg, devlink))
1159                 goto nla_put_failure;
1160         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1161                 goto nla_put_failure;
1162         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1163                 goto nla_put_failure;
1164         if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
1165                 goto nla_put_failure;
1166         if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
1167                 goto nla_put_failure;
1168         if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1169                 goto nla_put_failure;
1170         if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1171                 goto nla_put_failure;
1172
1173         if (ops->sb_occ_tc_port_bind_get) {
1174                 u32 cur;
1175                 u32 max;
1176
1177                 err = ops->sb_occ_tc_port_bind_get(devlink_port,
1178                                                    devlink_sb->index,
1179                                                    tc_index, pool_type,
1180                                                    &cur, &max);
1181                 if (err && err != -EOPNOTSUPP)
1182                         return err;
1183                 if (!err) {
1184                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1185                                 goto nla_put_failure;
1186                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1187                                 goto nla_put_failure;
1188                 }
1189         }
1190
1191         genlmsg_end(msg, hdr);
1192         return 0;
1193
1194 nla_put_failure:
1195         genlmsg_cancel(msg, hdr);
1196         return -EMSGSIZE;
1197 }
1198
1199 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
1200                                                    struct genl_info *info)
1201 {
1202         struct devlink_port *devlink_port = info->user_ptr[0];
1203         struct devlink *devlink = devlink_port->devlink;
1204         struct devlink_sb *devlink_sb = info->user_ptr[1];
1205         struct sk_buff *msg;
1206         enum devlink_sb_pool_type pool_type;
1207         u16 tc_index;
1208         int err;
1209
1210         err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1211         if (err)
1212                 return err;
1213
1214         err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1215                                                 pool_type, &tc_index);
1216         if (err)
1217                 return err;
1218
1219         if (!devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
1220                 return -EOPNOTSUPP;
1221
1222         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1223         if (!msg)
1224                 return -ENOMEM;
1225
1226         err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
1227                                               devlink_sb, tc_index, pool_type,
1228                                               DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1229                                               info->snd_portid,
1230                                               info->snd_seq, 0);
1231         if (err) {
1232                 nlmsg_free(msg);
1233                 return err;
1234         }
1235
1236         return genlmsg_reply(msg, info);
1237 }
1238
1239 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1240                                         int start, int *p_idx,
1241                                         struct devlink *devlink,
1242                                         struct devlink_sb *devlink_sb,
1243                                         u32 portid, u32 seq)
1244 {
1245         struct devlink_port *devlink_port;
1246         u16 tc_index;
1247         int err;
1248
1249         list_for_each_entry(devlink_port, &devlink->port_list, list) {
1250                 for (tc_index = 0;
1251                      tc_index < devlink_sb->ingress_tc_count; tc_index++) {
1252                         if (*p_idx < start) {
1253                                 (*p_idx)++;
1254                                 continue;
1255                         }
1256                         err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1257                                                               devlink_port,
1258                                                               devlink_sb,
1259                                                               tc_index,
1260                                                               DEVLINK_SB_POOL_TYPE_INGRESS,
1261                                                               DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1262                                                               portid, seq,
1263                                                               NLM_F_MULTI);
1264                         if (err)
1265                                 return err;
1266                         (*p_idx)++;
1267                 }
1268                 for (tc_index = 0;
1269                      tc_index < devlink_sb->egress_tc_count; tc_index++) {
1270                         if (*p_idx < start) {
1271                                 (*p_idx)++;
1272                                 continue;
1273                         }
1274                         err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1275                                                               devlink_port,
1276                                                               devlink_sb,
1277                                                               tc_index,
1278                                                               DEVLINK_SB_POOL_TYPE_EGRESS,
1279                                                               DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1280                                                               portid, seq,
1281                                                               NLM_F_MULTI);
1282                         if (err)
1283                                 return err;
1284                         (*p_idx)++;
1285                 }
1286         }
1287         return 0;
1288 }
1289
1290 static int
1291 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1292                                           struct netlink_callback *cb)
1293 {
1294         struct devlink *devlink;
1295         struct devlink_sb *devlink_sb;
1296         int start = cb->args[0];
1297         int idx = 0;
1298         int err;
1299
1300         mutex_lock(&devlink_mutex);
1301         mutex_lock(&devlink_port_mutex);
1302         list_for_each_entry(devlink, &devlink_list, list) {
1303                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1304                     !devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
1305                         continue;
1306                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1307                         err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
1308                                                            devlink,
1309                                                            devlink_sb,
1310                                                            NETLINK_CB(cb->skb).portid,
1311                                                            cb->nlh->nlmsg_seq);
1312                         if (err && err != -EOPNOTSUPP)
1313                                 goto out;
1314                 }
1315         }
1316 out:
1317         mutex_unlock(&devlink_port_mutex);
1318         mutex_unlock(&devlink_mutex);
1319
1320         cb->args[0] = idx;
1321         return msg->len;
1322 }
1323
1324 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
1325                                        unsigned int sb_index, u16 tc_index,
1326                                        enum devlink_sb_pool_type pool_type,
1327                                        u16 pool_index, u32 threshold)
1328
1329 {
1330         const struct devlink_ops *ops = devlink_port->devlink->ops;
1331
1332         if (ops && ops->sb_tc_pool_bind_set)
1333                 return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
1334                                                 tc_index, pool_type,
1335                                                 pool_index, threshold);
1336         return -EOPNOTSUPP;
1337 }
1338
1339 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
1340                                                    struct genl_info *info)
1341 {
1342         struct devlink_port *devlink_port = info->user_ptr[0];
1343         struct devlink_sb *devlink_sb = info->user_ptr[1];
1344         enum devlink_sb_pool_type pool_type;
1345         u16 tc_index;
1346         u16 pool_index;
1347         u32 threshold;
1348         int err;
1349
1350         err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1351         if (err)
1352                 return err;
1353
1354         err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1355                                                 pool_type, &tc_index);
1356         if (err)
1357                 return err;
1358
1359         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1360                                                   &pool_index);
1361         if (err)
1362                 return err;
1363
1364         if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1365                 return -EINVAL;
1366
1367         threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1368         return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
1369                                            tc_index, pool_type,
1370                                            pool_index, threshold);
1371 }
1372
1373 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
1374                                                struct genl_info *info)
1375 {
1376         struct devlink *devlink = info->user_ptr[0];
1377         struct devlink_sb *devlink_sb = info->user_ptr[1];
1378         const struct devlink_ops *ops = devlink->ops;
1379
1380         if (ops && ops->sb_occ_snapshot)
1381                 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
1382         return -EOPNOTSUPP;
1383 }
1384
1385 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
1386                                                 struct genl_info *info)
1387 {
1388         struct devlink *devlink = info->user_ptr[0];
1389         struct devlink_sb *devlink_sb = info->user_ptr[1];
1390         const struct devlink_ops *ops = devlink->ops;
1391
1392         if (ops && ops->sb_occ_max_clear)
1393                 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
1394         return -EOPNOTSUPP;
1395 }
1396
1397 static int devlink_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
1398                                 enum devlink_command cmd, u32 portid,
1399                                 u32 seq, int flags, u16 mode)
1400 {
1401         void *hdr;
1402
1403         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1404         if (!hdr)
1405                 return -EMSGSIZE;
1406
1407         if (devlink_nl_put_handle(msg, devlink))
1408                 goto nla_put_failure;
1409
1410         if (nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode))
1411                 goto nla_put_failure;
1412
1413         genlmsg_end(msg, hdr);
1414         return 0;
1415
1416 nla_put_failure:
1417         genlmsg_cancel(msg, hdr);
1418         return -EMSGSIZE;
1419 }
1420
1421 static int devlink_nl_cmd_eswitch_mode_get_doit(struct sk_buff *skb,
1422                                                 struct genl_info *info)
1423 {
1424         struct devlink *devlink = info->user_ptr[0];
1425         const struct devlink_ops *ops = devlink->ops;
1426         struct sk_buff *msg;
1427         u16 mode;
1428         int err;
1429
1430         if (!ops || !ops->eswitch_mode_get)
1431                 return -EOPNOTSUPP;
1432
1433         err = ops->eswitch_mode_get(devlink, &mode);
1434         if (err)
1435                 return err;
1436
1437         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1438         if (!msg)
1439                 return -ENOMEM;
1440
1441         err = devlink_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_MODE_GET,
1442                                    info->snd_portid, info->snd_seq, 0, mode);
1443
1444         if (err) {
1445                 nlmsg_free(msg);
1446                 return err;
1447         }
1448
1449         return genlmsg_reply(msg, info);
1450 }
1451
1452 static int devlink_nl_cmd_eswitch_mode_set_doit(struct sk_buff *skb,
1453                                                 struct genl_info *info)
1454 {
1455         struct devlink *devlink = info->user_ptr[0];
1456         const struct devlink_ops *ops = devlink->ops;
1457         u16 mode;
1458
1459         if (!info->attrs[DEVLINK_ATTR_ESWITCH_MODE])
1460                 return -EINVAL;
1461
1462         mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1463
1464         if (ops && ops->eswitch_mode_set)
1465                 return ops->eswitch_mode_set(devlink, mode);
1466         return -EOPNOTSUPP;
1467 }
1468
1469 static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
1470         [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
1471         [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
1472         [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
1473         [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
1474         [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
1475         [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
1476         [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
1477         [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
1478         [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
1479         [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
1480         [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
1481         [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
1482         [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
1483 };
1484
1485 static const struct genl_ops devlink_nl_ops[] = {
1486         {
1487                 .cmd = DEVLINK_CMD_GET,
1488                 .doit = devlink_nl_cmd_get_doit,
1489                 .dumpit = devlink_nl_cmd_get_dumpit,
1490                 .policy = devlink_nl_policy,
1491                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1492                 /* can be retrieved by unprivileged users */
1493         },
1494         {
1495                 .cmd = DEVLINK_CMD_PORT_GET,
1496                 .doit = devlink_nl_cmd_port_get_doit,
1497                 .dumpit = devlink_nl_cmd_port_get_dumpit,
1498                 .policy = devlink_nl_policy,
1499                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
1500                 /* can be retrieved by unprivileged users */
1501         },
1502         {
1503                 .cmd = DEVLINK_CMD_PORT_SET,
1504                 .doit = devlink_nl_cmd_port_set_doit,
1505                 .policy = devlink_nl_policy,
1506                 .flags = GENL_ADMIN_PERM,
1507                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
1508         },
1509         {
1510                 .cmd = DEVLINK_CMD_PORT_SPLIT,
1511                 .doit = devlink_nl_cmd_port_split_doit,
1512                 .policy = devlink_nl_policy,
1513                 .flags = GENL_ADMIN_PERM,
1514                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1515         },
1516         {
1517                 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
1518                 .doit = devlink_nl_cmd_port_unsplit_doit,
1519                 .policy = devlink_nl_policy,
1520                 .flags = GENL_ADMIN_PERM,
1521                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1522         },
1523         {
1524                 .cmd = DEVLINK_CMD_SB_GET,
1525                 .doit = devlink_nl_cmd_sb_get_doit,
1526                 .dumpit = devlink_nl_cmd_sb_get_dumpit,
1527                 .policy = devlink_nl_policy,
1528                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1529                                   DEVLINK_NL_FLAG_NEED_SB,
1530                 /* can be retrieved by unprivileged users */
1531         },
1532         {
1533                 .cmd = DEVLINK_CMD_SB_POOL_GET,
1534                 .doit = devlink_nl_cmd_sb_pool_get_doit,
1535                 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
1536                 .policy = devlink_nl_policy,
1537                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1538                                   DEVLINK_NL_FLAG_NEED_SB,
1539                 /* can be retrieved by unprivileged users */
1540         },
1541         {
1542                 .cmd = DEVLINK_CMD_SB_POOL_SET,
1543                 .doit = devlink_nl_cmd_sb_pool_set_doit,
1544                 .policy = devlink_nl_policy,
1545                 .flags = GENL_ADMIN_PERM,
1546                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1547                                   DEVLINK_NL_FLAG_NEED_SB,
1548         },
1549         {
1550                 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
1551                 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
1552                 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
1553                 .policy = devlink_nl_policy,
1554                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
1555                                   DEVLINK_NL_FLAG_NEED_SB,
1556                 /* can be retrieved by unprivileged users */
1557         },
1558         {
1559                 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
1560                 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
1561                 .policy = devlink_nl_policy,
1562                 .flags = GENL_ADMIN_PERM,
1563                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
1564                                   DEVLINK_NL_FLAG_NEED_SB,
1565         },
1566         {
1567                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
1568                 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
1569                 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
1570                 .policy = devlink_nl_policy,
1571                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
1572                                   DEVLINK_NL_FLAG_NEED_SB,
1573                 /* can be retrieved by unprivileged users */
1574         },
1575         {
1576                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
1577                 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
1578                 .policy = devlink_nl_policy,
1579                 .flags = GENL_ADMIN_PERM,
1580                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
1581                                   DEVLINK_NL_FLAG_NEED_SB,
1582         },
1583         {
1584                 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
1585                 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
1586                 .policy = devlink_nl_policy,
1587                 .flags = GENL_ADMIN_PERM,
1588                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1589                                   DEVLINK_NL_FLAG_NEED_SB |
1590                                   DEVLINK_NL_FLAG_LOCK_PORTS,
1591         },
1592         {
1593                 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
1594                 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
1595                 .policy = devlink_nl_policy,
1596                 .flags = GENL_ADMIN_PERM,
1597                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1598                                   DEVLINK_NL_FLAG_NEED_SB |
1599                                   DEVLINK_NL_FLAG_LOCK_PORTS,
1600         },
1601         {
1602                 .cmd = DEVLINK_CMD_ESWITCH_MODE_GET,
1603                 .doit = devlink_nl_cmd_eswitch_mode_get_doit,
1604                 .policy = devlink_nl_policy,
1605                 .flags = GENL_ADMIN_PERM,
1606                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1607         },
1608         {
1609                 .cmd = DEVLINK_CMD_ESWITCH_MODE_SET,
1610                 .doit = devlink_nl_cmd_eswitch_mode_set_doit,
1611                 .policy = devlink_nl_policy,
1612                 .flags = GENL_ADMIN_PERM,
1613                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1614         },
1615 };
1616
1617 /**
1618  *      devlink_alloc - Allocate new devlink instance resources
1619  *
1620  *      @ops: ops
1621  *      @priv_size: size of user private data
1622  *
1623  *      Allocate new devlink instance resources, including devlink index
1624  *      and name.
1625  */
1626 struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
1627 {
1628         struct devlink *devlink;
1629
1630         devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
1631         if (!devlink)
1632                 return NULL;
1633         devlink->ops = ops;
1634         devlink_net_set(devlink, &init_net);
1635         INIT_LIST_HEAD(&devlink->port_list);
1636         INIT_LIST_HEAD(&devlink->sb_list);
1637         return devlink;
1638 }
1639 EXPORT_SYMBOL_GPL(devlink_alloc);
1640
1641 /**
1642  *      devlink_register - Register devlink instance
1643  *
1644  *      @devlink: devlink
1645  */
1646 int devlink_register(struct devlink *devlink, struct device *dev)
1647 {
1648         mutex_lock(&devlink_mutex);
1649         devlink->dev = dev;
1650         list_add_tail(&devlink->list, &devlink_list);
1651         devlink_notify(devlink, DEVLINK_CMD_NEW);
1652         mutex_unlock(&devlink_mutex);
1653         return 0;
1654 }
1655 EXPORT_SYMBOL_GPL(devlink_register);
1656
1657 /**
1658  *      devlink_unregister - Unregister devlink instance
1659  *
1660  *      @devlink: devlink
1661  */
1662 void devlink_unregister(struct devlink *devlink)
1663 {
1664         mutex_lock(&devlink_mutex);
1665         devlink_notify(devlink, DEVLINK_CMD_DEL);
1666         list_del(&devlink->list);
1667         mutex_unlock(&devlink_mutex);
1668 }
1669 EXPORT_SYMBOL_GPL(devlink_unregister);
1670
1671 /**
1672  *      devlink_free - Free devlink instance resources
1673  *
1674  *      @devlink: devlink
1675  */
1676 void devlink_free(struct devlink *devlink)
1677 {
1678         kfree(devlink);
1679 }
1680 EXPORT_SYMBOL_GPL(devlink_free);
1681
1682 /**
1683  *      devlink_port_register - Register devlink port
1684  *
1685  *      @devlink: devlink
1686  *      @devlink_port: devlink port
1687  *      @port_index
1688  *
1689  *      Register devlink port with provided port index. User can use
1690  *      any indexing, even hw-related one. devlink_port structure
1691  *      is convenient to be embedded inside user driver private structure.
1692  *      Note that the caller should take care of zeroing the devlink_port
1693  *      structure.
1694  */
1695 int devlink_port_register(struct devlink *devlink,
1696                           struct devlink_port *devlink_port,
1697                           unsigned int port_index)
1698 {
1699         mutex_lock(&devlink_port_mutex);
1700         if (devlink_port_index_exists(devlink, port_index)) {
1701                 mutex_unlock(&devlink_port_mutex);
1702                 return -EEXIST;
1703         }
1704         devlink_port->devlink = devlink;
1705         devlink_port->index = port_index;
1706         devlink_port->registered = true;
1707         list_add_tail(&devlink_port->list, &devlink->port_list);
1708         mutex_unlock(&devlink_port_mutex);
1709         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1710         return 0;
1711 }
1712 EXPORT_SYMBOL_GPL(devlink_port_register);
1713
1714 /**
1715  *      devlink_port_unregister - Unregister devlink port
1716  *
1717  *      @devlink_port: devlink port
1718  */
1719 void devlink_port_unregister(struct devlink_port *devlink_port)
1720 {
1721         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
1722         mutex_lock(&devlink_port_mutex);
1723         list_del(&devlink_port->list);
1724         mutex_unlock(&devlink_port_mutex);
1725 }
1726 EXPORT_SYMBOL_GPL(devlink_port_unregister);
1727
1728 static void __devlink_port_type_set(struct devlink_port *devlink_port,
1729                                     enum devlink_port_type type,
1730                                     void *type_dev)
1731 {
1732         devlink_port->type = type;
1733         devlink_port->type_dev = type_dev;
1734         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1735 }
1736
1737 /**
1738  *      devlink_port_type_eth_set - Set port type to Ethernet
1739  *
1740  *      @devlink_port: devlink port
1741  *      @netdev: related netdevice
1742  */
1743 void devlink_port_type_eth_set(struct devlink_port *devlink_port,
1744                                struct net_device *netdev)
1745 {
1746         return __devlink_port_type_set(devlink_port,
1747                                        DEVLINK_PORT_TYPE_ETH, netdev);
1748 }
1749 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
1750
1751 /**
1752  *      devlink_port_type_ib_set - Set port type to InfiniBand
1753  *
1754  *      @devlink_port: devlink port
1755  *      @ibdev: related IB device
1756  */
1757 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
1758                               struct ib_device *ibdev)
1759 {
1760         return __devlink_port_type_set(devlink_port,
1761                                        DEVLINK_PORT_TYPE_IB, ibdev);
1762 }
1763 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
1764
1765 /**
1766  *      devlink_port_type_clear - Clear port type
1767  *
1768  *      @devlink_port: devlink port
1769  */
1770 void devlink_port_type_clear(struct devlink_port *devlink_port)
1771 {
1772         return __devlink_port_type_set(devlink_port,
1773                                        DEVLINK_PORT_TYPE_NOTSET, NULL);
1774 }
1775 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
1776
1777 /**
1778  *      devlink_port_split_set - Set port is split
1779  *
1780  *      @devlink_port: devlink port
1781  *      @split_group: split group - identifies group split port is part of
1782  */
1783 void devlink_port_split_set(struct devlink_port *devlink_port,
1784                             u32 split_group)
1785 {
1786         devlink_port->split = true;
1787         devlink_port->split_group = split_group;
1788         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1789 }
1790 EXPORT_SYMBOL_GPL(devlink_port_split_set);
1791
1792 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
1793                         u32 size, u16 ingress_pools_count,
1794                         u16 egress_pools_count, u16 ingress_tc_count,
1795                         u16 egress_tc_count)
1796 {
1797         struct devlink_sb *devlink_sb;
1798         int err = 0;
1799
1800         mutex_lock(&devlink_mutex);
1801         if (devlink_sb_index_exists(devlink, sb_index)) {
1802                 err = -EEXIST;
1803                 goto unlock;
1804         }
1805
1806         devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
1807         if (!devlink_sb) {
1808                 err = -ENOMEM;
1809                 goto unlock;
1810         }
1811         devlink_sb->index = sb_index;
1812         devlink_sb->size = size;
1813         devlink_sb->ingress_pools_count = ingress_pools_count;
1814         devlink_sb->egress_pools_count = egress_pools_count;
1815         devlink_sb->ingress_tc_count = ingress_tc_count;
1816         devlink_sb->egress_tc_count = egress_tc_count;
1817         list_add_tail(&devlink_sb->list, &devlink->sb_list);
1818 unlock:
1819         mutex_unlock(&devlink_mutex);
1820         return err;
1821 }
1822 EXPORT_SYMBOL_GPL(devlink_sb_register);
1823
1824 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
1825 {
1826         struct devlink_sb *devlink_sb;
1827
1828         mutex_lock(&devlink_mutex);
1829         devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
1830         WARN_ON(!devlink_sb);
1831         list_del(&devlink_sb->list);
1832         mutex_unlock(&devlink_mutex);
1833         kfree(devlink_sb);
1834 }
1835 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
1836
1837 static int __init devlink_module_init(void)
1838 {
1839         return genl_register_family_with_ops_groups(&devlink_nl_family,
1840                                                     devlink_nl_ops,
1841                                                     devlink_nl_mcgrps);
1842 }
1843
1844 static void __exit devlink_module_exit(void)
1845 {
1846         genl_unregister_family(&devlink_nl_family);
1847 }
1848
1849 module_init(devlink_module_init);
1850 module_exit(devlink_module_exit);
1851
1852 MODULE_LICENSE("GPL v2");
1853 MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
1854 MODULE_DESCRIPTION("Network physical device Netlink interface");
1855 MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);