Merge tag 'apparmor-pr-2018-06-13' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.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 #define CREATE_TRACE_POINTS
30 #include <trace/events/devlink.h>
31
32 static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
33         {
34                 .name = "destination mac",
35                 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
36                 .bitwidth = 48,
37         },
38 };
39
40 struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
41         .name = "ethernet",
42         .id = DEVLINK_DPIPE_HEADER_ETHERNET,
43         .fields = devlink_dpipe_fields_ethernet,
44         .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
45         .global = true,
46 };
47 EXPORT_SYMBOL(devlink_dpipe_header_ethernet);
48
49 static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
50         {
51                 .name = "destination ip",
52                 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
53                 .bitwidth = 32,
54         },
55 };
56
57 struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
58         .name = "ipv4",
59         .id = DEVLINK_DPIPE_HEADER_IPV4,
60         .fields = devlink_dpipe_fields_ipv4,
61         .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
62         .global = true,
63 };
64 EXPORT_SYMBOL(devlink_dpipe_header_ipv4);
65
66 static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
67         {
68                 .name = "destination ip",
69                 .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
70                 .bitwidth = 128,
71         },
72 };
73
74 struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
75         .name = "ipv6",
76         .id = DEVLINK_DPIPE_HEADER_IPV6,
77         .fields = devlink_dpipe_fields_ipv6,
78         .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
79         .global = true,
80 };
81 EXPORT_SYMBOL(devlink_dpipe_header_ipv6);
82
83 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
84
85 static LIST_HEAD(devlink_list);
86
87 /* devlink_mutex
88  *
89  * An overall lock guarding every operation coming from userspace.
90  * It also guards devlink devices list and it is taken when
91  * driver registers/unregisters it.
92  */
93 static DEFINE_MUTEX(devlink_mutex);
94
95 static struct net *devlink_net(const struct devlink *devlink)
96 {
97         return read_pnet(&devlink->_net);
98 }
99
100 static void devlink_net_set(struct devlink *devlink, struct net *net)
101 {
102         write_pnet(&devlink->_net, net);
103 }
104
105 static struct devlink *devlink_get_from_attrs(struct net *net,
106                                               struct nlattr **attrs)
107 {
108         struct devlink *devlink;
109         char *busname;
110         char *devname;
111
112         if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
113                 return ERR_PTR(-EINVAL);
114
115         busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
116         devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
117
118         list_for_each_entry(devlink, &devlink_list, list) {
119                 if (strcmp(devlink->dev->bus->name, busname) == 0 &&
120                     strcmp(dev_name(devlink->dev), devname) == 0 &&
121                     net_eq(devlink_net(devlink), net))
122                         return devlink;
123         }
124
125         return ERR_PTR(-ENODEV);
126 }
127
128 static struct devlink *devlink_get_from_info(struct genl_info *info)
129 {
130         return devlink_get_from_attrs(genl_info_net(info), info->attrs);
131 }
132
133 static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
134                                                       int port_index)
135 {
136         struct devlink_port *devlink_port;
137
138         list_for_each_entry(devlink_port, &devlink->port_list, list) {
139                 if (devlink_port->index == port_index)
140                         return devlink_port;
141         }
142         return NULL;
143 }
144
145 static bool devlink_port_index_exists(struct devlink *devlink, int port_index)
146 {
147         return devlink_port_get_by_index(devlink, port_index);
148 }
149
150 static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
151                                                         struct nlattr **attrs)
152 {
153         if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
154                 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
155                 struct devlink_port *devlink_port;
156
157                 devlink_port = devlink_port_get_by_index(devlink, port_index);
158                 if (!devlink_port)
159                         return ERR_PTR(-ENODEV);
160                 return devlink_port;
161         }
162         return ERR_PTR(-EINVAL);
163 }
164
165 static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
166                                                        struct genl_info *info)
167 {
168         return devlink_port_get_from_attrs(devlink, info->attrs);
169 }
170
171 struct devlink_sb {
172         struct list_head list;
173         unsigned int index;
174         u32 size;
175         u16 ingress_pools_count;
176         u16 egress_pools_count;
177         u16 ingress_tc_count;
178         u16 egress_tc_count;
179 };
180
181 static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
182 {
183         return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
184 }
185
186 static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
187                                                   unsigned int sb_index)
188 {
189         struct devlink_sb *devlink_sb;
190
191         list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
192                 if (devlink_sb->index == sb_index)
193                         return devlink_sb;
194         }
195         return NULL;
196 }
197
198 static bool devlink_sb_index_exists(struct devlink *devlink,
199                                     unsigned int sb_index)
200 {
201         return devlink_sb_get_by_index(devlink, sb_index);
202 }
203
204 static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
205                                                     struct nlattr **attrs)
206 {
207         if (attrs[DEVLINK_ATTR_SB_INDEX]) {
208                 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
209                 struct devlink_sb *devlink_sb;
210
211                 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
212                 if (!devlink_sb)
213                         return ERR_PTR(-ENODEV);
214                 return devlink_sb;
215         }
216         return ERR_PTR(-EINVAL);
217 }
218
219 static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
220                                                    struct genl_info *info)
221 {
222         return devlink_sb_get_from_attrs(devlink, info->attrs);
223 }
224
225 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
226                                                 struct nlattr **attrs,
227                                                 u16 *p_pool_index)
228 {
229         u16 val;
230
231         if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
232                 return -EINVAL;
233
234         val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
235         if (val >= devlink_sb_pool_count(devlink_sb))
236                 return -EINVAL;
237         *p_pool_index = val;
238         return 0;
239 }
240
241 static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
242                                                struct genl_info *info,
243                                                u16 *p_pool_index)
244 {
245         return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
246                                                     p_pool_index);
247 }
248
249 static int
250 devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
251                                     enum devlink_sb_pool_type *p_pool_type)
252 {
253         u8 val;
254
255         if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
256                 return -EINVAL;
257
258         val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
259         if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
260             val != DEVLINK_SB_POOL_TYPE_EGRESS)
261                 return -EINVAL;
262         *p_pool_type = val;
263         return 0;
264 }
265
266 static int
267 devlink_sb_pool_type_get_from_info(struct genl_info *info,
268                                    enum devlink_sb_pool_type *p_pool_type)
269 {
270         return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
271 }
272
273 static int
274 devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
275                                   enum devlink_sb_threshold_type *p_th_type)
276 {
277         u8 val;
278
279         if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
280                 return -EINVAL;
281
282         val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
283         if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
284             val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
285                 return -EINVAL;
286         *p_th_type = val;
287         return 0;
288 }
289
290 static int
291 devlink_sb_th_type_get_from_info(struct genl_info *info,
292                                  enum devlink_sb_threshold_type *p_th_type)
293 {
294         return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
295 }
296
297 static int
298 devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
299                                    struct nlattr **attrs,
300                                    enum devlink_sb_pool_type pool_type,
301                                    u16 *p_tc_index)
302 {
303         u16 val;
304
305         if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
306                 return -EINVAL;
307
308         val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
309         if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
310             val >= devlink_sb->ingress_tc_count)
311                 return -EINVAL;
312         if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
313             val >= devlink_sb->egress_tc_count)
314                 return -EINVAL;
315         *p_tc_index = val;
316         return 0;
317 }
318
319 static int
320 devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
321                                   struct genl_info *info,
322                                   enum devlink_sb_pool_type pool_type,
323                                   u16 *p_tc_index)
324 {
325         return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
326                                                   pool_type, p_tc_index);
327 }
328
329 #define DEVLINK_NL_FLAG_NEED_DEVLINK    BIT(0)
330 #define DEVLINK_NL_FLAG_NEED_PORT       BIT(1)
331 #define DEVLINK_NL_FLAG_NEED_SB         BIT(2)
332
333 /* The per devlink instance lock is taken by default in the pre-doit
334  * operation, yet several commands do not require this. The global
335  * devlink lock is taken and protects from disruption by user-calls.
336  */
337 #define DEVLINK_NL_FLAG_NO_LOCK         BIT(3)
338
339 static int devlink_nl_pre_doit(const struct genl_ops *ops,
340                                struct sk_buff *skb, struct genl_info *info)
341 {
342         struct devlink *devlink;
343         int err;
344
345         mutex_lock(&devlink_mutex);
346         devlink = devlink_get_from_info(info);
347         if (IS_ERR(devlink)) {
348                 mutex_unlock(&devlink_mutex);
349                 return PTR_ERR(devlink);
350         }
351         if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
352                 mutex_lock(&devlink->lock);
353         if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) {
354                 info->user_ptr[0] = devlink;
355         } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
356                 struct devlink_port *devlink_port;
357
358                 devlink_port = devlink_port_get_from_info(devlink, info);
359                 if (IS_ERR(devlink_port)) {
360                         err = PTR_ERR(devlink_port);
361                         goto unlock;
362                 }
363                 info->user_ptr[0] = devlink_port;
364         }
365         if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) {
366                 struct devlink_sb *devlink_sb;
367
368                 devlink_sb = devlink_sb_get_from_info(devlink, info);
369                 if (IS_ERR(devlink_sb)) {
370                         err = PTR_ERR(devlink_sb);
371                         goto unlock;
372                 }
373                 info->user_ptr[1] = devlink_sb;
374         }
375         return 0;
376
377 unlock:
378         if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
379                 mutex_unlock(&devlink->lock);
380         mutex_unlock(&devlink_mutex);
381         return err;
382 }
383
384 static void devlink_nl_post_doit(const struct genl_ops *ops,
385                                  struct sk_buff *skb, struct genl_info *info)
386 {
387         struct devlink *devlink;
388
389         devlink = devlink_get_from_info(info);
390         if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
391                 mutex_unlock(&devlink->lock);
392         mutex_unlock(&devlink_mutex);
393 }
394
395 static struct genl_family devlink_nl_family;
396
397 enum devlink_multicast_groups {
398         DEVLINK_MCGRP_CONFIG,
399 };
400
401 static const struct genl_multicast_group devlink_nl_mcgrps[] = {
402         [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
403 };
404
405 static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
406 {
407         if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
408                 return -EMSGSIZE;
409         if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
410                 return -EMSGSIZE;
411         return 0;
412 }
413
414 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
415                            enum devlink_command cmd, u32 portid,
416                            u32 seq, int flags)
417 {
418         void *hdr;
419
420         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
421         if (!hdr)
422                 return -EMSGSIZE;
423
424         if (devlink_nl_put_handle(msg, devlink))
425                 goto nla_put_failure;
426
427         genlmsg_end(msg, hdr);
428         return 0;
429
430 nla_put_failure:
431         genlmsg_cancel(msg, hdr);
432         return -EMSGSIZE;
433 }
434
435 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
436 {
437         struct sk_buff *msg;
438         int err;
439
440         WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
441
442         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
443         if (!msg)
444                 return;
445
446         err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
447         if (err) {
448                 nlmsg_free(msg);
449                 return;
450         }
451
452         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
453                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
454 }
455
456 static int devlink_nl_port_attrs_put(struct sk_buff *msg,
457                                      struct devlink_port *devlink_port)
458 {
459         struct devlink_port_attrs *attrs = &devlink_port->attrs;
460
461         if (!attrs->set)
462                 return 0;
463         if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
464                 return -EMSGSIZE;
465         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER, attrs->port_number))
466                 return -EMSGSIZE;
467         if (!attrs->split)
468                 return 0;
469         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP, attrs->port_number))
470                 return -EMSGSIZE;
471         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
472                         attrs->split_subport_number))
473                 return -EMSGSIZE;
474         return 0;
475 }
476
477 static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
478                                 struct devlink_port *devlink_port,
479                                 enum devlink_command cmd, u32 portid,
480                                 u32 seq, int flags)
481 {
482         void *hdr;
483
484         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
485         if (!hdr)
486                 return -EMSGSIZE;
487
488         if (devlink_nl_put_handle(msg, devlink))
489                 goto nla_put_failure;
490         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
491                 goto nla_put_failure;
492         if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
493                 goto nla_put_failure;
494         if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
495             nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
496                         devlink_port->desired_type))
497                 goto nla_put_failure;
498         if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
499                 struct net_device *netdev = devlink_port->type_dev;
500
501                 if (netdev &&
502                     (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
503                                  netdev->ifindex) ||
504                      nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
505                                     netdev->name)))
506                         goto nla_put_failure;
507         }
508         if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
509                 struct ib_device *ibdev = devlink_port->type_dev;
510
511                 if (ibdev &&
512                     nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
513                                    ibdev->name))
514                         goto nla_put_failure;
515         }
516         if (devlink_nl_port_attrs_put(msg, devlink_port))
517                 goto nla_put_failure;
518
519         genlmsg_end(msg, hdr);
520         return 0;
521
522 nla_put_failure:
523         genlmsg_cancel(msg, hdr);
524         return -EMSGSIZE;
525 }
526
527 static void devlink_port_notify(struct devlink_port *devlink_port,
528                                 enum devlink_command cmd)
529 {
530         struct devlink *devlink = devlink_port->devlink;
531         struct sk_buff *msg;
532         int err;
533
534         if (!devlink_port->registered)
535                 return;
536
537         WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
538
539         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
540         if (!msg)
541                 return;
542
543         err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);
544         if (err) {
545                 nlmsg_free(msg);
546                 return;
547         }
548
549         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
550                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
551 }
552
553 static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
554 {
555         struct devlink *devlink = info->user_ptr[0];
556         struct sk_buff *msg;
557         int err;
558
559         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
560         if (!msg)
561                 return -ENOMEM;
562
563         err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
564                               info->snd_portid, info->snd_seq, 0);
565         if (err) {
566                 nlmsg_free(msg);
567                 return err;
568         }
569
570         return genlmsg_reply(msg, info);
571 }
572
573 static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
574                                      struct netlink_callback *cb)
575 {
576         struct devlink *devlink;
577         int start = cb->args[0];
578         int idx = 0;
579         int err;
580
581         mutex_lock(&devlink_mutex);
582         list_for_each_entry(devlink, &devlink_list, list) {
583                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
584                         continue;
585                 if (idx < start) {
586                         idx++;
587                         continue;
588                 }
589                 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
590                                       NETLINK_CB(cb->skb).portid,
591                                       cb->nlh->nlmsg_seq, NLM_F_MULTI);
592                 if (err)
593                         goto out;
594                 idx++;
595         }
596 out:
597         mutex_unlock(&devlink_mutex);
598
599         cb->args[0] = idx;
600         return msg->len;
601 }
602
603 static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
604                                         struct genl_info *info)
605 {
606         struct devlink_port *devlink_port = info->user_ptr[0];
607         struct devlink *devlink = devlink_port->devlink;
608         struct sk_buff *msg;
609         int err;
610
611         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
612         if (!msg)
613                 return -ENOMEM;
614
615         err = devlink_nl_port_fill(msg, devlink, devlink_port,
616                                    DEVLINK_CMD_PORT_NEW,
617                                    info->snd_portid, info->snd_seq, 0);
618         if (err) {
619                 nlmsg_free(msg);
620                 return err;
621         }
622
623         return genlmsg_reply(msg, info);
624 }
625
626 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
627                                           struct netlink_callback *cb)
628 {
629         struct devlink *devlink;
630         struct devlink_port *devlink_port;
631         int start = cb->args[0];
632         int idx = 0;
633         int err;
634
635         mutex_lock(&devlink_mutex);
636         list_for_each_entry(devlink, &devlink_list, list) {
637                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
638                         continue;
639                 mutex_lock(&devlink->lock);
640                 list_for_each_entry(devlink_port, &devlink->port_list, list) {
641                         if (idx < start) {
642                                 idx++;
643                                 continue;
644                         }
645                         err = devlink_nl_port_fill(msg, devlink, devlink_port,
646                                                    DEVLINK_CMD_NEW,
647                                                    NETLINK_CB(cb->skb).portid,
648                                                    cb->nlh->nlmsg_seq,
649                                                    NLM_F_MULTI);
650                         if (err) {
651                                 mutex_unlock(&devlink->lock);
652                                 goto out;
653                         }
654                         idx++;
655                 }
656                 mutex_unlock(&devlink->lock);
657         }
658 out:
659         mutex_unlock(&devlink_mutex);
660
661         cb->args[0] = idx;
662         return msg->len;
663 }
664
665 static int devlink_port_type_set(struct devlink *devlink,
666                                  struct devlink_port *devlink_port,
667                                  enum devlink_port_type port_type)
668
669 {
670         int err;
671
672         if (devlink->ops && devlink->ops->port_type_set) {
673                 if (port_type == DEVLINK_PORT_TYPE_NOTSET)
674                         return -EINVAL;
675                 if (port_type == devlink_port->type)
676                         return 0;
677                 err = devlink->ops->port_type_set(devlink_port, port_type);
678                 if (err)
679                         return err;
680                 devlink_port->desired_type = port_type;
681                 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
682                 return 0;
683         }
684         return -EOPNOTSUPP;
685 }
686
687 static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
688                                         struct genl_info *info)
689 {
690         struct devlink_port *devlink_port = info->user_ptr[0];
691         struct devlink *devlink = devlink_port->devlink;
692         int err;
693
694         if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
695                 enum devlink_port_type port_type;
696
697                 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
698                 err = devlink_port_type_set(devlink, devlink_port, port_type);
699                 if (err)
700                         return err;
701         }
702         return 0;
703 }
704
705 static int devlink_port_split(struct devlink *devlink, u32 port_index,
706                               u32 count, struct netlink_ext_ack *extack)
707
708 {
709         if (devlink->ops && devlink->ops->port_split)
710                 return devlink->ops->port_split(devlink, port_index, count,
711                                                 extack);
712         return -EOPNOTSUPP;
713 }
714
715 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
716                                           struct genl_info *info)
717 {
718         struct devlink *devlink = info->user_ptr[0];
719         u32 port_index;
720         u32 count;
721
722         if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
723             !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
724                 return -EINVAL;
725
726         port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
727         count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
728         return devlink_port_split(devlink, port_index, count, info->extack);
729 }
730
731 static int devlink_port_unsplit(struct devlink *devlink, u32 port_index,
732                                 struct netlink_ext_ack *extack)
733
734 {
735         if (devlink->ops && devlink->ops->port_unsplit)
736                 return devlink->ops->port_unsplit(devlink, port_index, extack);
737         return -EOPNOTSUPP;
738 }
739
740 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
741                                             struct genl_info *info)
742 {
743         struct devlink *devlink = info->user_ptr[0];
744         u32 port_index;
745
746         if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
747                 return -EINVAL;
748
749         port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
750         return devlink_port_unsplit(devlink, port_index, info->extack);
751 }
752
753 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
754                               struct devlink_sb *devlink_sb,
755                               enum devlink_command cmd, u32 portid,
756                               u32 seq, int flags)
757 {
758         void *hdr;
759
760         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
761         if (!hdr)
762                 return -EMSGSIZE;
763
764         if (devlink_nl_put_handle(msg, devlink))
765                 goto nla_put_failure;
766         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
767                 goto nla_put_failure;
768         if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
769                 goto nla_put_failure;
770         if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
771                         devlink_sb->ingress_pools_count))
772                 goto nla_put_failure;
773         if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
774                         devlink_sb->egress_pools_count))
775                 goto nla_put_failure;
776         if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
777                         devlink_sb->ingress_tc_count))
778                 goto nla_put_failure;
779         if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
780                         devlink_sb->egress_tc_count))
781                 goto nla_put_failure;
782
783         genlmsg_end(msg, hdr);
784         return 0;
785
786 nla_put_failure:
787         genlmsg_cancel(msg, hdr);
788         return -EMSGSIZE;
789 }
790
791 static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
792                                       struct genl_info *info)
793 {
794         struct devlink *devlink = info->user_ptr[0];
795         struct devlink_sb *devlink_sb = info->user_ptr[1];
796         struct sk_buff *msg;
797         int err;
798
799         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
800         if (!msg)
801                 return -ENOMEM;
802
803         err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
804                                  DEVLINK_CMD_SB_NEW,
805                                  info->snd_portid, info->snd_seq, 0);
806         if (err) {
807                 nlmsg_free(msg);
808                 return err;
809         }
810
811         return genlmsg_reply(msg, info);
812 }
813
814 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
815                                         struct netlink_callback *cb)
816 {
817         struct devlink *devlink;
818         struct devlink_sb *devlink_sb;
819         int start = cb->args[0];
820         int idx = 0;
821         int err;
822
823         mutex_lock(&devlink_mutex);
824         list_for_each_entry(devlink, &devlink_list, list) {
825                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
826                         continue;
827                 mutex_lock(&devlink->lock);
828                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
829                         if (idx < start) {
830                                 idx++;
831                                 continue;
832                         }
833                         err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
834                                                  DEVLINK_CMD_SB_NEW,
835                                                  NETLINK_CB(cb->skb).portid,
836                                                  cb->nlh->nlmsg_seq,
837                                                  NLM_F_MULTI);
838                         if (err) {
839                                 mutex_unlock(&devlink->lock);
840                                 goto out;
841                         }
842                         idx++;
843                 }
844                 mutex_unlock(&devlink->lock);
845         }
846 out:
847         mutex_unlock(&devlink_mutex);
848
849         cb->args[0] = idx;
850         return msg->len;
851 }
852
853 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
854                                    struct devlink_sb *devlink_sb,
855                                    u16 pool_index, enum devlink_command cmd,
856                                    u32 portid, u32 seq, int flags)
857 {
858         struct devlink_sb_pool_info pool_info;
859         void *hdr;
860         int err;
861
862         err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
863                                         pool_index, &pool_info);
864         if (err)
865                 return err;
866
867         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
868         if (!hdr)
869                 return -EMSGSIZE;
870
871         if (devlink_nl_put_handle(msg, devlink))
872                 goto nla_put_failure;
873         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
874                 goto nla_put_failure;
875         if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
876                 goto nla_put_failure;
877         if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
878                 goto nla_put_failure;
879         if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
880                 goto nla_put_failure;
881         if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
882                        pool_info.threshold_type))
883                 goto nla_put_failure;
884
885         genlmsg_end(msg, hdr);
886         return 0;
887
888 nla_put_failure:
889         genlmsg_cancel(msg, hdr);
890         return -EMSGSIZE;
891 }
892
893 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
894                                            struct genl_info *info)
895 {
896         struct devlink *devlink = info->user_ptr[0];
897         struct devlink_sb *devlink_sb = info->user_ptr[1];
898         struct sk_buff *msg;
899         u16 pool_index;
900         int err;
901
902         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
903                                                   &pool_index);
904         if (err)
905                 return err;
906
907         if (!devlink->ops || !devlink->ops->sb_pool_get)
908                 return -EOPNOTSUPP;
909
910         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
911         if (!msg)
912                 return -ENOMEM;
913
914         err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
915                                       DEVLINK_CMD_SB_POOL_NEW,
916                                       info->snd_portid, info->snd_seq, 0);
917         if (err) {
918                 nlmsg_free(msg);
919                 return err;
920         }
921
922         return genlmsg_reply(msg, info);
923 }
924
925 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
926                                 struct devlink *devlink,
927                                 struct devlink_sb *devlink_sb,
928                                 u32 portid, u32 seq)
929 {
930         u16 pool_count = devlink_sb_pool_count(devlink_sb);
931         u16 pool_index;
932         int err;
933
934         for (pool_index = 0; pool_index < pool_count; pool_index++) {
935                 if (*p_idx < start) {
936                         (*p_idx)++;
937                         continue;
938                 }
939                 err = devlink_nl_sb_pool_fill(msg, devlink,
940                                               devlink_sb,
941                                               pool_index,
942                                               DEVLINK_CMD_SB_POOL_NEW,
943                                               portid, seq, NLM_F_MULTI);
944                 if (err)
945                         return err;
946                 (*p_idx)++;
947         }
948         return 0;
949 }
950
951 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
952                                              struct netlink_callback *cb)
953 {
954         struct devlink *devlink;
955         struct devlink_sb *devlink_sb;
956         int start = cb->args[0];
957         int idx = 0;
958         int err;
959
960         mutex_lock(&devlink_mutex);
961         list_for_each_entry(devlink, &devlink_list, list) {
962                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
963                     !devlink->ops || !devlink->ops->sb_pool_get)
964                         continue;
965                 mutex_lock(&devlink->lock);
966                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
967                         err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
968                                                    devlink_sb,
969                                                    NETLINK_CB(cb->skb).portid,
970                                                    cb->nlh->nlmsg_seq);
971                         if (err && err != -EOPNOTSUPP) {
972                                 mutex_unlock(&devlink->lock);
973                                 goto out;
974                         }
975                 }
976                 mutex_unlock(&devlink->lock);
977         }
978 out:
979         mutex_unlock(&devlink_mutex);
980
981         cb->args[0] = idx;
982         return msg->len;
983 }
984
985 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
986                                u16 pool_index, u32 size,
987                                enum devlink_sb_threshold_type threshold_type)
988
989 {
990         const struct devlink_ops *ops = devlink->ops;
991
992         if (ops && ops->sb_pool_set)
993                 return ops->sb_pool_set(devlink, sb_index, pool_index,
994                                         size, threshold_type);
995         return -EOPNOTSUPP;
996 }
997
998 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
999                                            struct genl_info *info)
1000 {
1001         struct devlink *devlink = info->user_ptr[0];
1002         struct devlink_sb *devlink_sb = info->user_ptr[1];
1003         enum devlink_sb_threshold_type threshold_type;
1004         u16 pool_index;
1005         u32 size;
1006         int err;
1007
1008         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1009                                                   &pool_index);
1010         if (err)
1011                 return err;
1012
1013         err = devlink_sb_th_type_get_from_info(info, &threshold_type);
1014         if (err)
1015                 return err;
1016
1017         if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
1018                 return -EINVAL;
1019
1020         size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
1021         return devlink_sb_pool_set(devlink, devlink_sb->index,
1022                                    pool_index, size, threshold_type);
1023 }
1024
1025 static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
1026                                         struct devlink *devlink,
1027                                         struct devlink_port *devlink_port,
1028                                         struct devlink_sb *devlink_sb,
1029                                         u16 pool_index,
1030                                         enum devlink_command cmd,
1031                                         u32 portid, u32 seq, int flags)
1032 {
1033         const struct devlink_ops *ops = devlink->ops;
1034         u32 threshold;
1035         void *hdr;
1036         int err;
1037
1038         err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
1039                                     pool_index, &threshold);
1040         if (err)
1041                 return err;
1042
1043         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1044         if (!hdr)
1045                 return -EMSGSIZE;
1046
1047         if (devlink_nl_put_handle(msg, devlink))
1048                 goto nla_put_failure;
1049         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1050                 goto nla_put_failure;
1051         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1052                 goto nla_put_failure;
1053         if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1054                 goto nla_put_failure;
1055         if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1056                 goto nla_put_failure;
1057
1058         if (ops->sb_occ_port_pool_get) {
1059                 u32 cur;
1060                 u32 max;
1061
1062                 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
1063                                                 pool_index, &cur, &max);
1064                 if (err && err != -EOPNOTSUPP)
1065                         return err;
1066                 if (!err) {
1067                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1068                                 goto nla_put_failure;
1069                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1070                                 goto nla_put_failure;
1071                 }
1072         }
1073
1074         genlmsg_end(msg, hdr);
1075         return 0;
1076
1077 nla_put_failure:
1078         genlmsg_cancel(msg, hdr);
1079         return -EMSGSIZE;
1080 }
1081
1082 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
1083                                                 struct genl_info *info)
1084 {
1085         struct devlink_port *devlink_port = info->user_ptr[0];
1086         struct devlink *devlink = devlink_port->devlink;
1087         struct devlink_sb *devlink_sb = info->user_ptr[1];
1088         struct sk_buff *msg;
1089         u16 pool_index;
1090         int err;
1091
1092         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1093                                                   &pool_index);
1094         if (err)
1095                 return err;
1096
1097         if (!devlink->ops || !devlink->ops->sb_port_pool_get)
1098                 return -EOPNOTSUPP;
1099
1100         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1101         if (!msg)
1102                 return -ENOMEM;
1103
1104         err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
1105                                            devlink_sb, pool_index,
1106                                            DEVLINK_CMD_SB_PORT_POOL_NEW,
1107                                            info->snd_portid, info->snd_seq, 0);
1108         if (err) {
1109                 nlmsg_free(msg);
1110                 return err;
1111         }
1112
1113         return genlmsg_reply(msg, info);
1114 }
1115
1116 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1117                                      struct devlink *devlink,
1118                                      struct devlink_sb *devlink_sb,
1119                                      u32 portid, u32 seq)
1120 {
1121         struct devlink_port *devlink_port;
1122         u16 pool_count = devlink_sb_pool_count(devlink_sb);
1123         u16 pool_index;
1124         int err;
1125
1126         list_for_each_entry(devlink_port, &devlink->port_list, list) {
1127                 for (pool_index = 0; pool_index < pool_count; pool_index++) {
1128                         if (*p_idx < start) {
1129                                 (*p_idx)++;
1130                                 continue;
1131                         }
1132                         err = devlink_nl_sb_port_pool_fill(msg, devlink,
1133                                                            devlink_port,
1134                                                            devlink_sb,
1135                                                            pool_index,
1136                                                            DEVLINK_CMD_SB_PORT_POOL_NEW,
1137                                                            portid, seq,
1138                                                            NLM_F_MULTI);
1139                         if (err)
1140                                 return err;
1141                         (*p_idx)++;
1142                 }
1143         }
1144         return 0;
1145 }
1146
1147 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
1148                                                   struct netlink_callback *cb)
1149 {
1150         struct devlink *devlink;
1151         struct devlink_sb *devlink_sb;
1152         int start = cb->args[0];
1153         int idx = 0;
1154         int err;
1155
1156         mutex_lock(&devlink_mutex);
1157         list_for_each_entry(devlink, &devlink_list, list) {
1158                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1159                     !devlink->ops || !devlink->ops->sb_port_pool_get)
1160                         continue;
1161                 mutex_lock(&devlink->lock);
1162                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1163                         err = __sb_port_pool_get_dumpit(msg, start, &idx,
1164                                                         devlink, devlink_sb,
1165                                                         NETLINK_CB(cb->skb).portid,
1166                                                         cb->nlh->nlmsg_seq);
1167                         if (err && err != -EOPNOTSUPP) {
1168                                 mutex_unlock(&devlink->lock);
1169                                 goto out;
1170                         }
1171                 }
1172                 mutex_unlock(&devlink->lock);
1173         }
1174 out:
1175         mutex_unlock(&devlink_mutex);
1176
1177         cb->args[0] = idx;
1178         return msg->len;
1179 }
1180
1181 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
1182                                     unsigned int sb_index, u16 pool_index,
1183                                     u32 threshold)
1184
1185 {
1186         const struct devlink_ops *ops = devlink_port->devlink->ops;
1187
1188         if (ops && ops->sb_port_pool_set)
1189                 return ops->sb_port_pool_set(devlink_port, sb_index,
1190                                              pool_index, threshold);
1191         return -EOPNOTSUPP;
1192 }
1193
1194 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
1195                                                 struct genl_info *info)
1196 {
1197         struct devlink_port *devlink_port = info->user_ptr[0];
1198         struct devlink_sb *devlink_sb = info->user_ptr[1];
1199         u16 pool_index;
1200         u32 threshold;
1201         int err;
1202
1203         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1204                                                   &pool_index);
1205         if (err)
1206                 return err;
1207
1208         if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1209                 return -EINVAL;
1210
1211         threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1212         return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
1213                                         pool_index, threshold);
1214 }
1215
1216 static int
1217 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
1218                                 struct devlink_port *devlink_port,
1219                                 struct devlink_sb *devlink_sb, u16 tc_index,
1220                                 enum devlink_sb_pool_type pool_type,
1221                                 enum devlink_command cmd,
1222                                 u32 portid, u32 seq, int flags)
1223 {
1224         const struct devlink_ops *ops = devlink->ops;
1225         u16 pool_index;
1226         u32 threshold;
1227         void *hdr;
1228         int err;
1229
1230         err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
1231                                        tc_index, pool_type,
1232                                        &pool_index, &threshold);
1233         if (err)
1234                 return err;
1235
1236         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1237         if (!hdr)
1238                 return -EMSGSIZE;
1239
1240         if (devlink_nl_put_handle(msg, devlink))
1241                 goto nla_put_failure;
1242         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1243                 goto nla_put_failure;
1244         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1245                 goto nla_put_failure;
1246         if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
1247                 goto nla_put_failure;
1248         if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
1249                 goto nla_put_failure;
1250         if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1251                 goto nla_put_failure;
1252         if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1253                 goto nla_put_failure;
1254
1255         if (ops->sb_occ_tc_port_bind_get) {
1256                 u32 cur;
1257                 u32 max;
1258
1259                 err = ops->sb_occ_tc_port_bind_get(devlink_port,
1260                                                    devlink_sb->index,
1261                                                    tc_index, pool_type,
1262                                                    &cur, &max);
1263                 if (err && err != -EOPNOTSUPP)
1264                         return err;
1265                 if (!err) {
1266                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1267                                 goto nla_put_failure;
1268                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1269                                 goto nla_put_failure;
1270                 }
1271         }
1272
1273         genlmsg_end(msg, hdr);
1274         return 0;
1275
1276 nla_put_failure:
1277         genlmsg_cancel(msg, hdr);
1278         return -EMSGSIZE;
1279 }
1280
1281 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
1282                                                    struct genl_info *info)
1283 {
1284         struct devlink_port *devlink_port = info->user_ptr[0];
1285         struct devlink *devlink = devlink_port->devlink;
1286         struct devlink_sb *devlink_sb = info->user_ptr[1];
1287         struct sk_buff *msg;
1288         enum devlink_sb_pool_type pool_type;
1289         u16 tc_index;
1290         int err;
1291
1292         err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1293         if (err)
1294                 return err;
1295
1296         err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1297                                                 pool_type, &tc_index);
1298         if (err)
1299                 return err;
1300
1301         if (!devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
1302                 return -EOPNOTSUPP;
1303
1304         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1305         if (!msg)
1306                 return -ENOMEM;
1307
1308         err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
1309                                               devlink_sb, tc_index, pool_type,
1310                                               DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1311                                               info->snd_portid,
1312                                               info->snd_seq, 0);
1313         if (err) {
1314                 nlmsg_free(msg);
1315                 return err;
1316         }
1317
1318         return genlmsg_reply(msg, info);
1319 }
1320
1321 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1322                                         int start, int *p_idx,
1323                                         struct devlink *devlink,
1324                                         struct devlink_sb *devlink_sb,
1325                                         u32 portid, u32 seq)
1326 {
1327         struct devlink_port *devlink_port;
1328         u16 tc_index;
1329         int err;
1330
1331         list_for_each_entry(devlink_port, &devlink->port_list, list) {
1332                 for (tc_index = 0;
1333                      tc_index < devlink_sb->ingress_tc_count; tc_index++) {
1334                         if (*p_idx < start) {
1335                                 (*p_idx)++;
1336                                 continue;
1337                         }
1338                         err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1339                                                               devlink_port,
1340                                                               devlink_sb,
1341                                                               tc_index,
1342                                                               DEVLINK_SB_POOL_TYPE_INGRESS,
1343                                                               DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1344                                                               portid, seq,
1345                                                               NLM_F_MULTI);
1346                         if (err)
1347                                 return err;
1348                         (*p_idx)++;
1349                 }
1350                 for (tc_index = 0;
1351                      tc_index < devlink_sb->egress_tc_count; tc_index++) {
1352                         if (*p_idx < start) {
1353                                 (*p_idx)++;
1354                                 continue;
1355                         }
1356                         err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1357                                                               devlink_port,
1358                                                               devlink_sb,
1359                                                               tc_index,
1360                                                               DEVLINK_SB_POOL_TYPE_EGRESS,
1361                                                               DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1362                                                               portid, seq,
1363                                                               NLM_F_MULTI);
1364                         if (err)
1365                                 return err;
1366                         (*p_idx)++;
1367                 }
1368         }
1369         return 0;
1370 }
1371
1372 static int
1373 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1374                                           struct netlink_callback *cb)
1375 {
1376         struct devlink *devlink;
1377         struct devlink_sb *devlink_sb;
1378         int start = cb->args[0];
1379         int idx = 0;
1380         int err;
1381
1382         mutex_lock(&devlink_mutex);
1383         list_for_each_entry(devlink, &devlink_list, list) {
1384                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1385                     !devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
1386                         continue;
1387
1388                 mutex_lock(&devlink->lock);
1389                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1390                         err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
1391                                                            devlink,
1392                                                            devlink_sb,
1393                                                            NETLINK_CB(cb->skb).portid,
1394                                                            cb->nlh->nlmsg_seq);
1395                         if (err && err != -EOPNOTSUPP) {
1396                                 mutex_unlock(&devlink->lock);
1397                                 goto out;
1398                         }
1399                 }
1400                 mutex_unlock(&devlink->lock);
1401         }
1402 out:
1403         mutex_unlock(&devlink_mutex);
1404
1405         cb->args[0] = idx;
1406         return msg->len;
1407 }
1408
1409 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
1410                                        unsigned int sb_index, u16 tc_index,
1411                                        enum devlink_sb_pool_type pool_type,
1412                                        u16 pool_index, u32 threshold)
1413
1414 {
1415         const struct devlink_ops *ops = devlink_port->devlink->ops;
1416
1417         if (ops && ops->sb_tc_pool_bind_set)
1418                 return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
1419                                                 tc_index, pool_type,
1420                                                 pool_index, threshold);
1421         return -EOPNOTSUPP;
1422 }
1423
1424 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
1425                                                    struct genl_info *info)
1426 {
1427         struct devlink_port *devlink_port = info->user_ptr[0];
1428         struct devlink_sb *devlink_sb = info->user_ptr[1];
1429         enum devlink_sb_pool_type pool_type;
1430         u16 tc_index;
1431         u16 pool_index;
1432         u32 threshold;
1433         int err;
1434
1435         err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1436         if (err)
1437                 return err;
1438
1439         err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1440                                                 pool_type, &tc_index);
1441         if (err)
1442                 return err;
1443
1444         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1445                                                   &pool_index);
1446         if (err)
1447                 return err;
1448
1449         if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1450                 return -EINVAL;
1451
1452         threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1453         return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
1454                                            tc_index, pool_type,
1455                                            pool_index, threshold);
1456 }
1457
1458 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
1459                                                struct genl_info *info)
1460 {
1461         struct devlink *devlink = info->user_ptr[0];
1462         struct devlink_sb *devlink_sb = info->user_ptr[1];
1463         const struct devlink_ops *ops = devlink->ops;
1464
1465         if (ops && ops->sb_occ_snapshot)
1466                 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
1467         return -EOPNOTSUPP;
1468 }
1469
1470 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
1471                                                 struct genl_info *info)
1472 {
1473         struct devlink *devlink = info->user_ptr[0];
1474         struct devlink_sb *devlink_sb = info->user_ptr[1];
1475         const struct devlink_ops *ops = devlink->ops;
1476
1477         if (ops && ops->sb_occ_max_clear)
1478                 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
1479         return -EOPNOTSUPP;
1480 }
1481
1482 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
1483                                    enum devlink_command cmd, u32 portid,
1484                                    u32 seq, int flags)
1485 {
1486         const struct devlink_ops *ops = devlink->ops;
1487         u8 inline_mode, encap_mode;
1488         void *hdr;
1489         int err = 0;
1490         u16 mode;
1491
1492         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1493         if (!hdr)
1494                 return -EMSGSIZE;
1495
1496         err = devlink_nl_put_handle(msg, devlink);
1497         if (err)
1498                 goto nla_put_failure;
1499
1500         if (ops->eswitch_mode_get) {
1501                 err = ops->eswitch_mode_get(devlink, &mode);
1502                 if (err)
1503                         goto nla_put_failure;
1504                 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
1505                 if (err)
1506                         goto nla_put_failure;
1507         }
1508
1509         if (ops->eswitch_inline_mode_get) {
1510                 err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
1511                 if (err)
1512                         goto nla_put_failure;
1513                 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
1514                                  inline_mode);
1515                 if (err)
1516                         goto nla_put_failure;
1517         }
1518
1519         if (ops->eswitch_encap_mode_get) {
1520                 err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
1521                 if (err)
1522                         goto nla_put_failure;
1523                 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
1524                 if (err)
1525                         goto nla_put_failure;
1526         }
1527
1528         genlmsg_end(msg, hdr);
1529         return 0;
1530
1531 nla_put_failure:
1532         genlmsg_cancel(msg, hdr);
1533         return err;
1534 }
1535
1536 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
1537                                            struct genl_info *info)
1538 {
1539         struct devlink *devlink = info->user_ptr[0];
1540         const struct devlink_ops *ops = devlink->ops;
1541         struct sk_buff *msg;
1542         int err;
1543
1544         if (!ops)
1545                 return -EOPNOTSUPP;
1546
1547         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1548         if (!msg)
1549                 return -ENOMEM;
1550
1551         err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
1552                                       info->snd_portid, info->snd_seq, 0);
1553
1554         if (err) {
1555                 nlmsg_free(msg);
1556                 return err;
1557         }
1558
1559         return genlmsg_reply(msg, info);
1560 }
1561
1562 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
1563                                            struct genl_info *info)
1564 {
1565         struct devlink *devlink = info->user_ptr[0];
1566         const struct devlink_ops *ops = devlink->ops;
1567         u8 inline_mode, encap_mode;
1568         int err = 0;
1569         u16 mode;
1570
1571         if (!ops)
1572                 return -EOPNOTSUPP;
1573
1574         if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
1575                 if (!ops->eswitch_mode_set)
1576                         return -EOPNOTSUPP;
1577                 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1578                 err = ops->eswitch_mode_set(devlink, mode);
1579                 if (err)
1580                         return err;
1581         }
1582
1583         if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
1584                 if (!ops->eswitch_inline_mode_set)
1585                         return -EOPNOTSUPP;
1586                 inline_mode = nla_get_u8(
1587                                 info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
1588                 err = ops->eswitch_inline_mode_set(devlink, inline_mode);
1589                 if (err)
1590                         return err;
1591         }
1592
1593         if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
1594                 if (!ops->eswitch_encap_mode_set)
1595                         return -EOPNOTSUPP;
1596                 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
1597                 err = ops->eswitch_encap_mode_set(devlink, encap_mode);
1598                 if (err)
1599                         return err;
1600         }
1601
1602         return 0;
1603 }
1604
1605 int devlink_dpipe_match_put(struct sk_buff *skb,
1606                             struct devlink_dpipe_match *match)
1607 {
1608         struct devlink_dpipe_header *header = match->header;
1609         struct devlink_dpipe_field *field = &header->fields[match->field_id];
1610         struct nlattr *match_attr;
1611
1612         match_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_MATCH);
1613         if (!match_attr)
1614                 return -EMSGSIZE;
1615
1616         if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
1617             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
1618             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1619             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1620             nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1621                 goto nla_put_failure;
1622
1623         nla_nest_end(skb, match_attr);
1624         return 0;
1625
1626 nla_put_failure:
1627         nla_nest_cancel(skb, match_attr);
1628         return -EMSGSIZE;
1629 }
1630 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
1631
1632 static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
1633                                      struct sk_buff *skb)
1634 {
1635         struct nlattr *matches_attr;
1636
1637         matches_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
1638         if (!matches_attr)
1639                 return -EMSGSIZE;
1640
1641         if (table->table_ops->matches_dump(table->priv, skb))
1642                 goto nla_put_failure;
1643
1644         nla_nest_end(skb, matches_attr);
1645         return 0;
1646
1647 nla_put_failure:
1648         nla_nest_cancel(skb, matches_attr);
1649         return -EMSGSIZE;
1650 }
1651
1652 int devlink_dpipe_action_put(struct sk_buff *skb,
1653                              struct devlink_dpipe_action *action)
1654 {
1655         struct devlink_dpipe_header *header = action->header;
1656         struct devlink_dpipe_field *field = &header->fields[action->field_id];
1657         struct nlattr *action_attr;
1658
1659         action_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_ACTION);
1660         if (!action_attr)
1661                 return -EMSGSIZE;
1662
1663         if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
1664             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
1665             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1666             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1667             nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1668                 goto nla_put_failure;
1669
1670         nla_nest_end(skb, action_attr);
1671         return 0;
1672
1673 nla_put_failure:
1674         nla_nest_cancel(skb, action_attr);
1675         return -EMSGSIZE;
1676 }
1677 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
1678
1679 static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
1680                                      struct sk_buff *skb)
1681 {
1682         struct nlattr *actions_attr;
1683
1684         actions_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
1685         if (!actions_attr)
1686                 return -EMSGSIZE;
1687
1688         if (table->table_ops->actions_dump(table->priv, skb))
1689                 goto nla_put_failure;
1690
1691         nla_nest_end(skb, actions_attr);
1692         return 0;
1693
1694 nla_put_failure:
1695         nla_nest_cancel(skb, actions_attr);
1696         return -EMSGSIZE;
1697 }
1698
1699 static int devlink_dpipe_table_put(struct sk_buff *skb,
1700                                    struct devlink_dpipe_table *table)
1701 {
1702         struct nlattr *table_attr;
1703         u64 table_size;
1704
1705         table_size = table->table_ops->size_get(table->priv);
1706         table_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE);
1707         if (!table_attr)
1708                 return -EMSGSIZE;
1709
1710         if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
1711             nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
1712                               DEVLINK_ATTR_PAD))
1713                 goto nla_put_failure;
1714         if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
1715                        table->counters_enabled))
1716                 goto nla_put_failure;
1717
1718         if (table->resource_valid) {
1719                 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
1720                                       table->resource_id, DEVLINK_ATTR_PAD) ||
1721                     nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
1722                                       table->resource_units, DEVLINK_ATTR_PAD))
1723                         goto nla_put_failure;
1724         }
1725         if (devlink_dpipe_matches_put(table, skb))
1726                 goto nla_put_failure;
1727
1728         if (devlink_dpipe_actions_put(table, skb))
1729                 goto nla_put_failure;
1730
1731         nla_nest_end(skb, table_attr);
1732         return 0;
1733
1734 nla_put_failure:
1735         nla_nest_cancel(skb, table_attr);
1736         return -EMSGSIZE;
1737 }
1738
1739 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
1740                                             struct genl_info *info)
1741 {
1742         int err;
1743
1744         if (*pskb) {
1745                 err = genlmsg_reply(*pskb, info);
1746                 if (err)
1747                         return err;
1748         }
1749         *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
1750         if (!*pskb)
1751                 return -ENOMEM;
1752         return 0;
1753 }
1754
1755 static int devlink_dpipe_tables_fill(struct genl_info *info,
1756                                      enum devlink_command cmd, int flags,
1757                                      struct list_head *dpipe_tables,
1758                                      const char *table_name)
1759 {
1760         struct devlink *devlink = info->user_ptr[0];
1761         struct devlink_dpipe_table *table;
1762         struct nlattr *tables_attr;
1763         struct sk_buff *skb = NULL;
1764         struct nlmsghdr *nlh;
1765         bool incomplete;
1766         void *hdr;
1767         int i;
1768         int err;
1769
1770         table = list_first_entry(dpipe_tables,
1771                                  struct devlink_dpipe_table, list);
1772 start_again:
1773         err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1774         if (err)
1775                 return err;
1776
1777         hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
1778                           &devlink_nl_family, NLM_F_MULTI, cmd);
1779         if (!hdr) {
1780                 nlmsg_free(skb);
1781                 return -EMSGSIZE;
1782         }
1783
1784         if (devlink_nl_put_handle(skb, devlink))
1785                 goto nla_put_failure;
1786         tables_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLES);
1787         if (!tables_attr)
1788                 goto nla_put_failure;
1789
1790         i = 0;
1791         incomplete = false;
1792         list_for_each_entry_from(table, dpipe_tables, list) {
1793                 if (!table_name) {
1794                         err = devlink_dpipe_table_put(skb, table);
1795                         if (err) {
1796                                 if (!i)
1797                                         goto err_table_put;
1798                                 incomplete = true;
1799                                 break;
1800                         }
1801                 } else {
1802                         if (!strcmp(table->name, table_name)) {
1803                                 err = devlink_dpipe_table_put(skb, table);
1804                                 if (err)
1805                                         break;
1806                         }
1807                 }
1808                 i++;
1809         }
1810
1811         nla_nest_end(skb, tables_attr);
1812         genlmsg_end(skb, hdr);
1813         if (incomplete)
1814                 goto start_again;
1815
1816 send_done:
1817         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
1818                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
1819         if (!nlh) {
1820                 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1821                 if (err)
1822                         return err;
1823                 goto send_done;
1824         }
1825
1826         return genlmsg_reply(skb, info);
1827
1828 nla_put_failure:
1829         err = -EMSGSIZE;
1830 err_table_put:
1831         nlmsg_free(skb);
1832         return err;
1833 }
1834
1835 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
1836                                           struct genl_info *info)
1837 {
1838         struct devlink *devlink = info->user_ptr[0];
1839         const char *table_name =  NULL;
1840
1841         if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
1842                 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
1843
1844         return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
1845                                          &devlink->dpipe_table_list,
1846                                          table_name);
1847 }
1848
1849 static int devlink_dpipe_value_put(struct sk_buff *skb,
1850                                    struct devlink_dpipe_value *value)
1851 {
1852         if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
1853                     value->value_size, value->value))
1854                 return -EMSGSIZE;
1855         if (value->mask)
1856                 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
1857                             value->value_size, value->mask))
1858                         return -EMSGSIZE;
1859         if (value->mapping_valid)
1860                 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
1861                                 value->mapping_value))
1862                         return -EMSGSIZE;
1863         return 0;
1864 }
1865
1866 static int devlink_dpipe_action_value_put(struct sk_buff *skb,
1867                                           struct devlink_dpipe_value *value)
1868 {
1869         if (!value->action)
1870                 return -EINVAL;
1871         if (devlink_dpipe_action_put(skb, value->action))
1872                 return -EMSGSIZE;
1873         if (devlink_dpipe_value_put(skb, value))
1874                 return -EMSGSIZE;
1875         return 0;
1876 }
1877
1878 static int devlink_dpipe_action_values_put(struct sk_buff *skb,
1879                                            struct devlink_dpipe_value *values,
1880                                            unsigned int values_count)
1881 {
1882         struct nlattr *action_attr;
1883         int i;
1884         int err;
1885
1886         for (i = 0; i < values_count; i++) {
1887                 action_attr = nla_nest_start(skb,
1888                                              DEVLINK_ATTR_DPIPE_ACTION_VALUE);
1889                 if (!action_attr)
1890                         return -EMSGSIZE;
1891                 err = devlink_dpipe_action_value_put(skb, &values[i]);
1892                 if (err)
1893                         goto err_action_value_put;
1894                 nla_nest_end(skb, action_attr);
1895         }
1896         return 0;
1897
1898 err_action_value_put:
1899         nla_nest_cancel(skb, action_attr);
1900         return err;
1901 }
1902
1903 static int devlink_dpipe_match_value_put(struct sk_buff *skb,
1904                                          struct devlink_dpipe_value *value)
1905 {
1906         if (!value->match)
1907                 return -EINVAL;
1908         if (devlink_dpipe_match_put(skb, value->match))
1909                 return -EMSGSIZE;
1910         if (devlink_dpipe_value_put(skb, value))
1911                 return -EMSGSIZE;
1912         return 0;
1913 }
1914
1915 static int devlink_dpipe_match_values_put(struct sk_buff *skb,
1916                                           struct devlink_dpipe_value *values,
1917                                           unsigned int values_count)
1918 {
1919         struct nlattr *match_attr;
1920         int i;
1921         int err;
1922
1923         for (i = 0; i < values_count; i++) {
1924                 match_attr = nla_nest_start(skb,
1925                                             DEVLINK_ATTR_DPIPE_MATCH_VALUE);
1926                 if (!match_attr)
1927                         return -EMSGSIZE;
1928                 err = devlink_dpipe_match_value_put(skb, &values[i]);
1929                 if (err)
1930                         goto err_match_value_put;
1931                 nla_nest_end(skb, match_attr);
1932         }
1933         return 0;
1934
1935 err_match_value_put:
1936         nla_nest_cancel(skb, match_attr);
1937         return err;
1938 }
1939
1940 static int devlink_dpipe_entry_put(struct sk_buff *skb,
1941                                    struct devlink_dpipe_entry *entry)
1942 {
1943         struct nlattr *entry_attr, *matches_attr, *actions_attr;
1944         int err;
1945
1946         entry_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_ENTRY);
1947         if (!entry_attr)
1948                 return  -EMSGSIZE;
1949
1950         if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
1951                               DEVLINK_ATTR_PAD))
1952                 goto nla_put_failure;
1953         if (entry->counter_valid)
1954                 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
1955                                       entry->counter, DEVLINK_ATTR_PAD))
1956                         goto nla_put_failure;
1957
1958         matches_attr = nla_nest_start(skb,
1959                                       DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
1960         if (!matches_attr)
1961                 goto nla_put_failure;
1962
1963         err = devlink_dpipe_match_values_put(skb, entry->match_values,
1964                                              entry->match_values_count);
1965         if (err) {
1966                 nla_nest_cancel(skb, matches_attr);
1967                 goto err_match_values_put;
1968         }
1969         nla_nest_end(skb, matches_attr);
1970
1971         actions_attr = nla_nest_start(skb,
1972                                       DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
1973         if (!actions_attr)
1974                 goto nla_put_failure;
1975
1976         err = devlink_dpipe_action_values_put(skb, entry->action_values,
1977                                               entry->action_values_count);
1978         if (err) {
1979                 nla_nest_cancel(skb, actions_attr);
1980                 goto err_action_values_put;
1981         }
1982         nla_nest_end(skb, actions_attr);
1983
1984         nla_nest_end(skb, entry_attr);
1985         return 0;
1986
1987 nla_put_failure:
1988         err = -EMSGSIZE;
1989 err_match_values_put:
1990 err_action_values_put:
1991         nla_nest_cancel(skb, entry_attr);
1992         return err;
1993 }
1994
1995 static struct devlink_dpipe_table *
1996 devlink_dpipe_table_find(struct list_head *dpipe_tables,
1997                          const char *table_name)
1998 {
1999         struct devlink_dpipe_table *table;
2000
2001         list_for_each_entry_rcu(table, dpipe_tables, list) {
2002                 if (!strcmp(table->name, table_name))
2003                         return table;
2004         }
2005         return NULL;
2006 }
2007
2008 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
2009 {
2010         struct devlink *devlink;
2011         int err;
2012
2013         err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
2014                                                dump_ctx->info);
2015         if (err)
2016                 return err;
2017
2018         dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
2019                                     dump_ctx->info->snd_portid,
2020                                     dump_ctx->info->snd_seq,
2021                                     &devlink_nl_family, NLM_F_MULTI,
2022                                     dump_ctx->cmd);
2023         if (!dump_ctx->hdr)
2024                 goto nla_put_failure;
2025
2026         devlink = dump_ctx->info->user_ptr[0];
2027         if (devlink_nl_put_handle(dump_ctx->skb, devlink))
2028                 goto nla_put_failure;
2029         dump_ctx->nest = nla_nest_start(dump_ctx->skb,
2030                                         DEVLINK_ATTR_DPIPE_ENTRIES);
2031         if (!dump_ctx->nest)
2032                 goto nla_put_failure;
2033         return 0;
2034
2035 nla_put_failure:
2036         nlmsg_free(dump_ctx->skb);
2037         return -EMSGSIZE;
2038 }
2039 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
2040
2041 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
2042                                    struct devlink_dpipe_entry *entry)
2043 {
2044         return devlink_dpipe_entry_put(dump_ctx->skb, entry);
2045 }
2046 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
2047
2048 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
2049 {
2050         nla_nest_end(dump_ctx->skb, dump_ctx->nest);
2051         genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
2052         return 0;
2053 }
2054 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
2055
2056 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
2057
2058 {
2059         unsigned int value_count, value_index;
2060         struct devlink_dpipe_value *value;
2061
2062         value = entry->action_values;
2063         value_count = entry->action_values_count;
2064         for (value_index = 0; value_index < value_count; value_index++) {
2065                 kfree(value[value_index].value);
2066                 kfree(value[value_index].mask);
2067         }
2068
2069         value = entry->match_values;
2070         value_count = entry->match_values_count;
2071         for (value_index = 0; value_index < value_count; value_index++) {
2072                 kfree(value[value_index].value);
2073                 kfree(value[value_index].mask);
2074         }
2075 }
2076 EXPORT_SYMBOL(devlink_dpipe_entry_clear);
2077
2078 static int devlink_dpipe_entries_fill(struct genl_info *info,
2079                                       enum devlink_command cmd, int flags,
2080                                       struct devlink_dpipe_table *table)
2081 {
2082         struct devlink_dpipe_dump_ctx dump_ctx;
2083         struct nlmsghdr *nlh;
2084         int err;
2085
2086         dump_ctx.skb = NULL;
2087         dump_ctx.cmd = cmd;
2088         dump_ctx.info = info;
2089
2090         err = table->table_ops->entries_dump(table->priv,
2091                                              table->counters_enabled,
2092                                              &dump_ctx);
2093         if (err)
2094                 return err;
2095
2096 send_done:
2097         nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
2098                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
2099         if (!nlh) {
2100                 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
2101                 if (err)
2102                         return err;
2103                 goto send_done;
2104         }
2105         return genlmsg_reply(dump_ctx.skb, info);
2106 }
2107
2108 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
2109                                             struct genl_info *info)
2110 {
2111         struct devlink *devlink = info->user_ptr[0];
2112         struct devlink_dpipe_table *table;
2113         const char *table_name;
2114
2115         if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
2116                 return -EINVAL;
2117
2118         table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2119         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2120                                          table_name);
2121         if (!table)
2122                 return -EINVAL;
2123
2124         if (!table->table_ops->entries_dump)
2125                 return -EINVAL;
2126
2127         return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
2128                                           0, table);
2129 }
2130
2131 static int devlink_dpipe_fields_put(struct sk_buff *skb,
2132                                     const struct devlink_dpipe_header *header)
2133 {
2134         struct devlink_dpipe_field *field;
2135         struct nlattr *field_attr;
2136         int i;
2137
2138         for (i = 0; i < header->fields_count; i++) {
2139                 field = &header->fields[i];
2140                 field_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_FIELD);
2141                 if (!field_attr)
2142                         return -EMSGSIZE;
2143                 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
2144                     nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
2145                     nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
2146                     nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
2147                         goto nla_put_failure;
2148                 nla_nest_end(skb, field_attr);
2149         }
2150         return 0;
2151
2152 nla_put_failure:
2153         nla_nest_cancel(skb, field_attr);
2154         return -EMSGSIZE;
2155 }
2156
2157 static int devlink_dpipe_header_put(struct sk_buff *skb,
2158                                     struct devlink_dpipe_header *header)
2159 {
2160         struct nlattr *fields_attr, *header_attr;
2161         int err;
2162
2163         header_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER);
2164         if (!header_attr)
2165                 return -EMSGSIZE;
2166
2167         if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
2168             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
2169             nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
2170                 goto nla_put_failure;
2171
2172         fields_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
2173         if (!fields_attr)
2174                 goto nla_put_failure;
2175
2176         err = devlink_dpipe_fields_put(skb, header);
2177         if (err) {
2178                 nla_nest_cancel(skb, fields_attr);
2179                 goto nla_put_failure;
2180         }
2181         nla_nest_end(skb, fields_attr);
2182         nla_nest_end(skb, header_attr);
2183         return 0;
2184
2185 nla_put_failure:
2186         err = -EMSGSIZE;
2187         nla_nest_cancel(skb, header_attr);
2188         return err;
2189 }
2190
2191 static int devlink_dpipe_headers_fill(struct genl_info *info,
2192                                       enum devlink_command cmd, int flags,
2193                                       struct devlink_dpipe_headers *
2194                                       dpipe_headers)
2195 {
2196         struct devlink *devlink = info->user_ptr[0];
2197         struct nlattr *headers_attr;
2198         struct sk_buff *skb = NULL;
2199         struct nlmsghdr *nlh;
2200         void *hdr;
2201         int i, j;
2202         int err;
2203
2204         i = 0;
2205 start_again:
2206         err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2207         if (err)
2208                 return err;
2209
2210         hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2211                           &devlink_nl_family, NLM_F_MULTI, cmd);
2212         if (!hdr) {
2213                 nlmsg_free(skb);
2214                 return -EMSGSIZE;
2215         }
2216
2217         if (devlink_nl_put_handle(skb, devlink))
2218                 goto nla_put_failure;
2219         headers_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADERS);
2220         if (!headers_attr)
2221                 goto nla_put_failure;
2222
2223         j = 0;
2224         for (; i < dpipe_headers->headers_count; i++) {
2225                 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
2226                 if (err) {
2227                         if (!j)
2228                                 goto err_table_put;
2229                         break;
2230                 }
2231                 j++;
2232         }
2233         nla_nest_end(skb, headers_attr);
2234         genlmsg_end(skb, hdr);
2235         if (i != dpipe_headers->headers_count)
2236                 goto start_again;
2237
2238 send_done:
2239         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2240                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
2241         if (!nlh) {
2242                 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2243                 if (err)
2244                         return err;
2245                 goto send_done;
2246         }
2247         return genlmsg_reply(skb, info);
2248
2249 nla_put_failure:
2250         err = -EMSGSIZE;
2251 err_table_put:
2252         nlmsg_free(skb);
2253         return err;
2254 }
2255
2256 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
2257                                             struct genl_info *info)
2258 {
2259         struct devlink *devlink = info->user_ptr[0];
2260
2261         if (!devlink->dpipe_headers)
2262                 return -EOPNOTSUPP;
2263         return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
2264                                           0, devlink->dpipe_headers);
2265 }
2266
2267 static int devlink_dpipe_table_counters_set(struct devlink *devlink,
2268                                             const char *table_name,
2269                                             bool enable)
2270 {
2271         struct devlink_dpipe_table *table;
2272
2273         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2274                                          table_name);
2275         if (!table)
2276                 return -EINVAL;
2277
2278         if (table->counter_control_extern)
2279                 return -EOPNOTSUPP;
2280
2281         if (!(table->counters_enabled ^ enable))
2282                 return 0;
2283
2284         table->counters_enabled = enable;
2285         if (table->table_ops->counters_set_update)
2286                 table->table_ops->counters_set_update(table->priv, enable);
2287         return 0;
2288 }
2289
2290 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
2291                                                    struct genl_info *info)
2292 {
2293         struct devlink *devlink = info->user_ptr[0];
2294         const char *table_name;
2295         bool counters_enable;
2296
2297         if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] ||
2298             !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED])
2299                 return -EINVAL;
2300
2301         table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2302         counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
2303
2304         return devlink_dpipe_table_counters_set(devlink, table_name,
2305                                                 counters_enable);
2306 }
2307
2308 static struct devlink_resource *
2309 devlink_resource_find(struct devlink *devlink,
2310                       struct devlink_resource *resource, u64 resource_id)
2311 {
2312         struct list_head *resource_list;
2313
2314         if (resource)
2315                 resource_list = &resource->resource_list;
2316         else
2317                 resource_list = &devlink->resource_list;
2318
2319         list_for_each_entry(resource, resource_list, list) {
2320                 struct devlink_resource *child_resource;
2321
2322                 if (resource->id == resource_id)
2323                         return resource;
2324
2325                 child_resource = devlink_resource_find(devlink, resource,
2326                                                        resource_id);
2327                 if (child_resource)
2328                         return child_resource;
2329         }
2330         return NULL;
2331 }
2332
2333 static void
2334 devlink_resource_validate_children(struct devlink_resource *resource)
2335 {
2336         struct devlink_resource *child_resource;
2337         bool size_valid = true;
2338         u64 parts_size = 0;
2339
2340         if (list_empty(&resource->resource_list))
2341                 goto out;
2342
2343         list_for_each_entry(child_resource, &resource->resource_list, list)
2344                 parts_size += child_resource->size_new;
2345
2346         if (parts_size > resource->size_new)
2347                 size_valid = false;
2348 out:
2349         resource->size_valid = size_valid;
2350 }
2351
2352 static int
2353 devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
2354                                struct netlink_ext_ack *extack)
2355 {
2356         u64 reminder;
2357         int err = 0;
2358
2359         if (size > resource->size_params.size_max) {
2360                 NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
2361                 err = -EINVAL;
2362         }
2363
2364         if (size < resource->size_params.size_min) {
2365                 NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
2366                 err = -EINVAL;
2367         }
2368
2369         div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
2370         if (reminder) {
2371                 NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
2372                 err = -EINVAL;
2373         }
2374
2375         return err;
2376 }
2377
2378 static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
2379                                        struct genl_info *info)
2380 {
2381         struct devlink *devlink = info->user_ptr[0];
2382         struct devlink_resource *resource;
2383         u64 resource_id;
2384         u64 size;
2385         int err;
2386
2387         if (!info->attrs[DEVLINK_ATTR_RESOURCE_ID] ||
2388             !info->attrs[DEVLINK_ATTR_RESOURCE_SIZE])
2389                 return -EINVAL;
2390         resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
2391
2392         resource = devlink_resource_find(devlink, NULL, resource_id);
2393         if (!resource)
2394                 return -EINVAL;
2395
2396         size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
2397         err = devlink_resource_validate_size(resource, size, info->extack);
2398         if (err)
2399                 return err;
2400
2401         resource->size_new = size;
2402         devlink_resource_validate_children(resource);
2403         if (resource->parent)
2404                 devlink_resource_validate_children(resource->parent);
2405         return 0;
2406 }
2407
2408 static int
2409 devlink_resource_size_params_put(struct devlink_resource *resource,
2410                                  struct sk_buff *skb)
2411 {
2412         struct devlink_resource_size_params *size_params;
2413
2414         size_params = &resource->size_params;
2415         if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
2416                               size_params->size_granularity, DEVLINK_ATTR_PAD) ||
2417             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
2418                               size_params->size_max, DEVLINK_ATTR_PAD) ||
2419             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
2420                               size_params->size_min, DEVLINK_ATTR_PAD) ||
2421             nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
2422                 return -EMSGSIZE;
2423         return 0;
2424 }
2425
2426 static int devlink_resource_occ_put(struct devlink_resource *resource,
2427                                     struct sk_buff *skb)
2428 {
2429         if (!resource->occ_get)
2430                 return 0;
2431         return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
2432                                  resource->occ_get(resource->occ_get_priv),
2433                                  DEVLINK_ATTR_PAD);
2434 }
2435
2436 static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
2437                                 struct devlink_resource *resource)
2438 {
2439         struct devlink_resource *child_resource;
2440         struct nlattr *child_resource_attr;
2441         struct nlattr *resource_attr;
2442
2443         resource_attr = nla_nest_start(skb, DEVLINK_ATTR_RESOURCE);
2444         if (!resource_attr)
2445                 return -EMSGSIZE;
2446
2447         if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
2448             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
2449                               DEVLINK_ATTR_PAD) ||
2450             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
2451                               DEVLINK_ATTR_PAD))
2452                 goto nla_put_failure;
2453         if (resource->size != resource->size_new)
2454                 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
2455                                   resource->size_new, DEVLINK_ATTR_PAD);
2456         if (devlink_resource_occ_put(resource, skb))
2457                 goto nla_put_failure;
2458         if (devlink_resource_size_params_put(resource, skb))
2459                 goto nla_put_failure;
2460         if (list_empty(&resource->resource_list))
2461                 goto out;
2462
2463         if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
2464                        resource->size_valid))
2465                 goto nla_put_failure;
2466
2467         child_resource_attr = nla_nest_start(skb, DEVLINK_ATTR_RESOURCE_LIST);
2468         if (!child_resource_attr)
2469                 goto nla_put_failure;
2470
2471         list_for_each_entry(child_resource, &resource->resource_list, list) {
2472                 if (devlink_resource_put(devlink, skb, child_resource))
2473                         goto resource_put_failure;
2474         }
2475
2476         nla_nest_end(skb, child_resource_attr);
2477 out:
2478         nla_nest_end(skb, resource_attr);
2479         return 0;
2480
2481 resource_put_failure:
2482         nla_nest_cancel(skb, child_resource_attr);
2483 nla_put_failure:
2484         nla_nest_cancel(skb, resource_attr);
2485         return -EMSGSIZE;
2486 }
2487
2488 static int devlink_resource_fill(struct genl_info *info,
2489                                  enum devlink_command cmd, int flags)
2490 {
2491         struct devlink *devlink = info->user_ptr[0];
2492         struct devlink_resource *resource;
2493         struct nlattr *resources_attr;
2494         struct sk_buff *skb = NULL;
2495         struct nlmsghdr *nlh;
2496         bool incomplete;
2497         void *hdr;
2498         int i;
2499         int err;
2500
2501         resource = list_first_entry(&devlink->resource_list,
2502                                     struct devlink_resource, list);
2503 start_again:
2504         err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2505         if (err)
2506                 return err;
2507
2508         hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2509                           &devlink_nl_family, NLM_F_MULTI, cmd);
2510         if (!hdr) {
2511                 nlmsg_free(skb);
2512                 return -EMSGSIZE;
2513         }
2514
2515         if (devlink_nl_put_handle(skb, devlink))
2516                 goto nla_put_failure;
2517
2518         resources_attr = nla_nest_start(skb, DEVLINK_ATTR_RESOURCE_LIST);
2519         if (!resources_attr)
2520                 goto nla_put_failure;
2521
2522         incomplete = false;
2523         i = 0;
2524         list_for_each_entry_from(resource, &devlink->resource_list, list) {
2525                 err = devlink_resource_put(devlink, skb, resource);
2526                 if (err) {
2527                         if (!i)
2528                                 goto err_resource_put;
2529                         incomplete = true;
2530                         break;
2531                 }
2532                 i++;
2533         }
2534         nla_nest_end(skb, resources_attr);
2535         genlmsg_end(skb, hdr);
2536         if (incomplete)
2537                 goto start_again;
2538 send_done:
2539         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2540                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
2541         if (!nlh) {
2542                 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2543                 if (err)
2544                         goto err_skb_send_alloc;
2545                 goto send_done;
2546         }
2547         return genlmsg_reply(skb, info);
2548
2549 nla_put_failure:
2550         err = -EMSGSIZE;
2551 err_resource_put:
2552 err_skb_send_alloc:
2553         nlmsg_free(skb);
2554         return err;
2555 }
2556
2557 static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
2558                                         struct genl_info *info)
2559 {
2560         struct devlink *devlink = info->user_ptr[0];
2561
2562         if (list_empty(&devlink->resource_list))
2563                 return -EOPNOTSUPP;
2564
2565         return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
2566 }
2567
2568 static int
2569 devlink_resources_validate(struct devlink *devlink,
2570                            struct devlink_resource *resource,
2571                            struct genl_info *info)
2572 {
2573         struct list_head *resource_list;
2574         int err = 0;
2575
2576         if (resource)
2577                 resource_list = &resource->resource_list;
2578         else
2579                 resource_list = &devlink->resource_list;
2580
2581         list_for_each_entry(resource, resource_list, list) {
2582                 if (!resource->size_valid)
2583                         return -EINVAL;
2584                 err = devlink_resources_validate(devlink, resource, info);
2585                 if (err)
2586                         return err;
2587         }
2588         return err;
2589 }
2590
2591 static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
2592 {
2593         struct devlink *devlink = info->user_ptr[0];
2594         int err;
2595
2596         if (!devlink->ops->reload)
2597                 return -EOPNOTSUPP;
2598
2599         err = devlink_resources_validate(devlink, NULL, info);
2600         if (err) {
2601                 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
2602                 return err;
2603         }
2604         return devlink->ops->reload(devlink, info->extack);
2605 }
2606
2607 static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
2608         [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
2609         [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
2610         [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
2611         [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
2612         [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
2613         [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
2614         [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
2615         [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
2616         [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
2617         [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
2618         [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
2619         [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
2620         [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
2621         [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
2622         [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
2623         [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
2624         [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
2625         [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64},
2626         [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64},
2627 };
2628
2629 static const struct genl_ops devlink_nl_ops[] = {
2630         {
2631                 .cmd = DEVLINK_CMD_GET,
2632                 .doit = devlink_nl_cmd_get_doit,
2633                 .dumpit = devlink_nl_cmd_get_dumpit,
2634                 .policy = devlink_nl_policy,
2635                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2636                 /* can be retrieved by unprivileged users */
2637         },
2638         {
2639                 .cmd = DEVLINK_CMD_PORT_GET,
2640                 .doit = devlink_nl_cmd_port_get_doit,
2641                 .dumpit = devlink_nl_cmd_port_get_dumpit,
2642                 .policy = devlink_nl_policy,
2643                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
2644                 /* can be retrieved by unprivileged users */
2645         },
2646         {
2647                 .cmd = DEVLINK_CMD_PORT_SET,
2648                 .doit = devlink_nl_cmd_port_set_doit,
2649                 .policy = devlink_nl_policy,
2650                 .flags = GENL_ADMIN_PERM,
2651                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
2652         },
2653         {
2654                 .cmd = DEVLINK_CMD_PORT_SPLIT,
2655                 .doit = devlink_nl_cmd_port_split_doit,
2656                 .policy = devlink_nl_policy,
2657                 .flags = GENL_ADMIN_PERM,
2658                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2659                                   DEVLINK_NL_FLAG_NO_LOCK,
2660         },
2661         {
2662                 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
2663                 .doit = devlink_nl_cmd_port_unsplit_doit,
2664                 .policy = devlink_nl_policy,
2665                 .flags = GENL_ADMIN_PERM,
2666                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2667                                   DEVLINK_NL_FLAG_NO_LOCK,
2668         },
2669         {
2670                 .cmd = DEVLINK_CMD_SB_GET,
2671                 .doit = devlink_nl_cmd_sb_get_doit,
2672                 .dumpit = devlink_nl_cmd_sb_get_dumpit,
2673                 .policy = devlink_nl_policy,
2674                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2675                                   DEVLINK_NL_FLAG_NEED_SB,
2676                 /* can be retrieved by unprivileged users */
2677         },
2678         {
2679                 .cmd = DEVLINK_CMD_SB_POOL_GET,
2680                 .doit = devlink_nl_cmd_sb_pool_get_doit,
2681                 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
2682                 .policy = devlink_nl_policy,
2683                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2684                                   DEVLINK_NL_FLAG_NEED_SB,
2685                 /* can be retrieved by unprivileged users */
2686         },
2687         {
2688                 .cmd = DEVLINK_CMD_SB_POOL_SET,
2689                 .doit = devlink_nl_cmd_sb_pool_set_doit,
2690                 .policy = devlink_nl_policy,
2691                 .flags = GENL_ADMIN_PERM,
2692                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2693                                   DEVLINK_NL_FLAG_NEED_SB,
2694         },
2695         {
2696                 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
2697                 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
2698                 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
2699                 .policy = devlink_nl_policy,
2700                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2701                                   DEVLINK_NL_FLAG_NEED_SB,
2702                 /* can be retrieved by unprivileged users */
2703         },
2704         {
2705                 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
2706                 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
2707                 .policy = devlink_nl_policy,
2708                 .flags = GENL_ADMIN_PERM,
2709                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2710                                   DEVLINK_NL_FLAG_NEED_SB,
2711         },
2712         {
2713                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
2714                 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
2715                 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
2716                 .policy = devlink_nl_policy,
2717                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2718                                   DEVLINK_NL_FLAG_NEED_SB,
2719                 /* can be retrieved by unprivileged users */
2720         },
2721         {
2722                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
2723                 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
2724                 .policy = devlink_nl_policy,
2725                 .flags = GENL_ADMIN_PERM,
2726                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
2727                                   DEVLINK_NL_FLAG_NEED_SB,
2728         },
2729         {
2730                 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
2731                 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
2732                 .policy = devlink_nl_policy,
2733                 .flags = GENL_ADMIN_PERM,
2734                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2735                                   DEVLINK_NL_FLAG_NEED_SB,
2736         },
2737         {
2738                 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
2739                 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
2740                 .policy = devlink_nl_policy,
2741                 .flags = GENL_ADMIN_PERM,
2742                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2743                                   DEVLINK_NL_FLAG_NEED_SB,
2744         },
2745         {
2746                 .cmd = DEVLINK_CMD_ESWITCH_GET,
2747                 .doit = devlink_nl_cmd_eswitch_get_doit,
2748                 .policy = devlink_nl_policy,
2749                 .flags = GENL_ADMIN_PERM,
2750                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2751         },
2752         {
2753                 .cmd = DEVLINK_CMD_ESWITCH_SET,
2754                 .doit = devlink_nl_cmd_eswitch_set_doit,
2755                 .policy = devlink_nl_policy,
2756                 .flags = GENL_ADMIN_PERM,
2757                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2758                                   DEVLINK_NL_FLAG_NO_LOCK,
2759         },
2760         {
2761                 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
2762                 .doit = devlink_nl_cmd_dpipe_table_get,
2763                 .policy = devlink_nl_policy,
2764                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2765                 /* can be retrieved by unprivileged users */
2766         },
2767         {
2768                 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
2769                 .doit = devlink_nl_cmd_dpipe_entries_get,
2770                 .policy = devlink_nl_policy,
2771                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2772                 /* can be retrieved by unprivileged users */
2773         },
2774         {
2775                 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
2776                 .doit = devlink_nl_cmd_dpipe_headers_get,
2777                 .policy = devlink_nl_policy,
2778                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2779                 /* can be retrieved by unprivileged users */
2780         },
2781         {
2782                 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
2783                 .doit = devlink_nl_cmd_dpipe_table_counters_set,
2784                 .policy = devlink_nl_policy,
2785                 .flags = GENL_ADMIN_PERM,
2786                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2787         },
2788         {
2789                 .cmd = DEVLINK_CMD_RESOURCE_SET,
2790                 .doit = devlink_nl_cmd_resource_set,
2791                 .policy = devlink_nl_policy,
2792                 .flags = GENL_ADMIN_PERM,
2793                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2794         },
2795         {
2796                 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
2797                 .doit = devlink_nl_cmd_resource_dump,
2798                 .policy = devlink_nl_policy,
2799                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
2800                 /* can be retrieved by unprivileged users */
2801         },
2802         {
2803                 .cmd = DEVLINK_CMD_RELOAD,
2804                 .doit = devlink_nl_cmd_reload,
2805                 .policy = devlink_nl_policy,
2806                 .flags = GENL_ADMIN_PERM,
2807                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
2808                                   DEVLINK_NL_FLAG_NO_LOCK,
2809         },
2810 };
2811
2812 static struct genl_family devlink_nl_family __ro_after_init = {
2813         .name           = DEVLINK_GENL_NAME,
2814         .version        = DEVLINK_GENL_VERSION,
2815         .maxattr        = DEVLINK_ATTR_MAX,
2816         .netnsok        = true,
2817         .pre_doit       = devlink_nl_pre_doit,
2818         .post_doit      = devlink_nl_post_doit,
2819         .module         = THIS_MODULE,
2820         .ops            = devlink_nl_ops,
2821         .n_ops          = ARRAY_SIZE(devlink_nl_ops),
2822         .mcgrps         = devlink_nl_mcgrps,
2823         .n_mcgrps       = ARRAY_SIZE(devlink_nl_mcgrps),
2824 };
2825
2826 /**
2827  *      devlink_alloc - Allocate new devlink instance resources
2828  *
2829  *      @ops: ops
2830  *      @priv_size: size of user private data
2831  *
2832  *      Allocate new devlink instance resources, including devlink index
2833  *      and name.
2834  */
2835 struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
2836 {
2837         struct devlink *devlink;
2838
2839         devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
2840         if (!devlink)
2841                 return NULL;
2842         devlink->ops = ops;
2843         devlink_net_set(devlink, &init_net);
2844         INIT_LIST_HEAD(&devlink->port_list);
2845         INIT_LIST_HEAD(&devlink->sb_list);
2846         INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
2847         INIT_LIST_HEAD(&devlink->resource_list);
2848         mutex_init(&devlink->lock);
2849         return devlink;
2850 }
2851 EXPORT_SYMBOL_GPL(devlink_alloc);
2852
2853 /**
2854  *      devlink_register - Register devlink instance
2855  *
2856  *      @devlink: devlink
2857  */
2858 int devlink_register(struct devlink *devlink, struct device *dev)
2859 {
2860         mutex_lock(&devlink_mutex);
2861         devlink->dev = dev;
2862         list_add_tail(&devlink->list, &devlink_list);
2863         devlink_notify(devlink, DEVLINK_CMD_NEW);
2864         mutex_unlock(&devlink_mutex);
2865         return 0;
2866 }
2867 EXPORT_SYMBOL_GPL(devlink_register);
2868
2869 /**
2870  *      devlink_unregister - Unregister devlink instance
2871  *
2872  *      @devlink: devlink
2873  */
2874 void devlink_unregister(struct devlink *devlink)
2875 {
2876         mutex_lock(&devlink_mutex);
2877         devlink_notify(devlink, DEVLINK_CMD_DEL);
2878         list_del(&devlink->list);
2879         mutex_unlock(&devlink_mutex);
2880 }
2881 EXPORT_SYMBOL_GPL(devlink_unregister);
2882
2883 /**
2884  *      devlink_free - Free devlink instance resources
2885  *
2886  *      @devlink: devlink
2887  */
2888 void devlink_free(struct devlink *devlink)
2889 {
2890         kfree(devlink);
2891 }
2892 EXPORT_SYMBOL_GPL(devlink_free);
2893
2894 /**
2895  *      devlink_port_register - Register devlink port
2896  *
2897  *      @devlink: devlink
2898  *      @devlink_port: devlink port
2899  *      @port_index
2900  *
2901  *      Register devlink port with provided port index. User can use
2902  *      any indexing, even hw-related one. devlink_port structure
2903  *      is convenient to be embedded inside user driver private structure.
2904  *      Note that the caller should take care of zeroing the devlink_port
2905  *      structure.
2906  */
2907 int devlink_port_register(struct devlink *devlink,
2908                           struct devlink_port *devlink_port,
2909                           unsigned int port_index)
2910 {
2911         mutex_lock(&devlink->lock);
2912         if (devlink_port_index_exists(devlink, port_index)) {
2913                 mutex_unlock(&devlink->lock);
2914                 return -EEXIST;
2915         }
2916         devlink_port->devlink = devlink;
2917         devlink_port->index = port_index;
2918         devlink_port->registered = true;
2919         list_add_tail(&devlink_port->list, &devlink->port_list);
2920         mutex_unlock(&devlink->lock);
2921         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
2922         return 0;
2923 }
2924 EXPORT_SYMBOL_GPL(devlink_port_register);
2925
2926 /**
2927  *      devlink_port_unregister - Unregister devlink port
2928  *
2929  *      @devlink_port: devlink port
2930  */
2931 void devlink_port_unregister(struct devlink_port *devlink_port)
2932 {
2933         struct devlink *devlink = devlink_port->devlink;
2934
2935         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
2936         mutex_lock(&devlink->lock);
2937         list_del(&devlink_port->list);
2938         mutex_unlock(&devlink->lock);
2939 }
2940 EXPORT_SYMBOL_GPL(devlink_port_unregister);
2941
2942 static void __devlink_port_type_set(struct devlink_port *devlink_port,
2943                                     enum devlink_port_type type,
2944                                     void *type_dev)
2945 {
2946         devlink_port->type = type;
2947         devlink_port->type_dev = type_dev;
2948         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
2949 }
2950
2951 /**
2952  *      devlink_port_type_eth_set - Set port type to Ethernet
2953  *
2954  *      @devlink_port: devlink port
2955  *      @netdev: related netdevice
2956  */
2957 void devlink_port_type_eth_set(struct devlink_port *devlink_port,
2958                                struct net_device *netdev)
2959 {
2960         return __devlink_port_type_set(devlink_port,
2961                                        DEVLINK_PORT_TYPE_ETH, netdev);
2962 }
2963 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
2964
2965 /**
2966  *      devlink_port_type_ib_set - Set port type to InfiniBand
2967  *
2968  *      @devlink_port: devlink port
2969  *      @ibdev: related IB device
2970  */
2971 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
2972                               struct ib_device *ibdev)
2973 {
2974         return __devlink_port_type_set(devlink_port,
2975                                        DEVLINK_PORT_TYPE_IB, ibdev);
2976 }
2977 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
2978
2979 /**
2980  *      devlink_port_type_clear - Clear port type
2981  *
2982  *      @devlink_port: devlink port
2983  */
2984 void devlink_port_type_clear(struct devlink_port *devlink_port)
2985 {
2986         return __devlink_port_type_set(devlink_port,
2987                                        DEVLINK_PORT_TYPE_NOTSET, NULL);
2988 }
2989 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
2990
2991 /**
2992  *      devlink_port_attrs_set - Set port attributes
2993  *
2994  *      @devlink_port: devlink port
2995  *      @flavour: flavour of the port
2996  *      @port_number: number of the port that is facing user, for example
2997  *                    the front panel port number
2998  *      @split: indicates if this is split port
2999  *      @split_subport_number: if the port is split, this is the number
3000  *                             of subport.
3001  */
3002 void devlink_port_attrs_set(struct devlink_port *devlink_port,
3003                             enum devlink_port_flavour flavour,
3004                             u32 port_number, bool split,
3005                             u32 split_subport_number)
3006 {
3007         struct devlink_port_attrs *attrs = &devlink_port->attrs;
3008
3009         attrs->set = true;
3010         attrs->flavour = flavour;
3011         attrs->port_number = port_number;
3012         attrs->split = split;
3013         attrs->split_subport_number = split_subport_number;
3014         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
3015 }
3016 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
3017
3018 int devlink_port_get_phys_port_name(struct devlink_port *devlink_port,
3019                                     char *name, size_t len)
3020 {
3021         struct devlink_port_attrs *attrs = &devlink_port->attrs;
3022         int n = 0;
3023
3024         if (!attrs->set)
3025                 return -EOPNOTSUPP;
3026
3027         switch (attrs->flavour) {
3028         case DEVLINK_PORT_FLAVOUR_PHYSICAL:
3029                 if (!attrs->split)
3030                         n = snprintf(name, len, "p%u", attrs->port_number);
3031                 else
3032                         n = snprintf(name, len, "p%us%u", attrs->port_number,
3033                                      attrs->split_subport_number);
3034                 break;
3035         case DEVLINK_PORT_FLAVOUR_CPU:
3036         case DEVLINK_PORT_FLAVOUR_DSA:
3037                 /* As CPU and DSA ports do not have a netdevice associated
3038                  * case should not ever happen.
3039                  */
3040                 WARN_ON(1);
3041                 return -EINVAL;
3042         }
3043
3044         if (n >= len)
3045                 return -EINVAL;
3046
3047         return 0;
3048 }
3049 EXPORT_SYMBOL_GPL(devlink_port_get_phys_port_name);
3050
3051 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
3052                         u32 size, u16 ingress_pools_count,
3053                         u16 egress_pools_count, u16 ingress_tc_count,
3054                         u16 egress_tc_count)
3055 {
3056         struct devlink_sb *devlink_sb;
3057         int err = 0;
3058
3059         mutex_lock(&devlink->lock);
3060         if (devlink_sb_index_exists(devlink, sb_index)) {
3061                 err = -EEXIST;
3062                 goto unlock;
3063         }
3064
3065         devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
3066         if (!devlink_sb) {
3067                 err = -ENOMEM;
3068                 goto unlock;
3069         }
3070         devlink_sb->index = sb_index;
3071         devlink_sb->size = size;
3072         devlink_sb->ingress_pools_count = ingress_pools_count;
3073         devlink_sb->egress_pools_count = egress_pools_count;
3074         devlink_sb->ingress_tc_count = ingress_tc_count;
3075         devlink_sb->egress_tc_count = egress_tc_count;
3076         list_add_tail(&devlink_sb->list, &devlink->sb_list);
3077 unlock:
3078         mutex_unlock(&devlink->lock);
3079         return err;
3080 }
3081 EXPORT_SYMBOL_GPL(devlink_sb_register);
3082
3083 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
3084 {
3085         struct devlink_sb *devlink_sb;
3086
3087         mutex_lock(&devlink->lock);
3088         devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
3089         WARN_ON(!devlink_sb);
3090         list_del(&devlink_sb->list);
3091         mutex_unlock(&devlink->lock);
3092         kfree(devlink_sb);
3093 }
3094 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
3095
3096 /**
3097  *      devlink_dpipe_headers_register - register dpipe headers
3098  *
3099  *      @devlink: devlink
3100  *      @dpipe_headers: dpipe header array
3101  *
3102  *      Register the headers supported by hardware.
3103  */
3104 int devlink_dpipe_headers_register(struct devlink *devlink,
3105                                    struct devlink_dpipe_headers *dpipe_headers)
3106 {
3107         mutex_lock(&devlink->lock);
3108         devlink->dpipe_headers = dpipe_headers;
3109         mutex_unlock(&devlink->lock);
3110         return 0;
3111 }
3112 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register);
3113
3114 /**
3115  *      devlink_dpipe_headers_unregister - unregister dpipe headers
3116  *
3117  *      @devlink: devlink
3118  *
3119  *      Unregister the headers supported by hardware.
3120  */
3121 void devlink_dpipe_headers_unregister(struct devlink *devlink)
3122 {
3123         mutex_lock(&devlink->lock);
3124         devlink->dpipe_headers = NULL;
3125         mutex_unlock(&devlink->lock);
3126 }
3127 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister);
3128
3129 /**
3130  *      devlink_dpipe_table_counter_enabled - check if counter allocation
3131  *                                            required
3132  *      @devlink: devlink
3133  *      @table_name: tables name
3134  *
3135  *      Used by driver to check if counter allocation is required.
3136  *      After counter allocation is turned on the table entries
3137  *      are updated to include counter statistics.
3138  *
3139  *      After that point on the driver must respect the counter
3140  *      state so that each entry added to the table is added
3141  *      with a counter.
3142  */
3143 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
3144                                          const char *table_name)
3145 {
3146         struct devlink_dpipe_table *table;
3147         bool enabled;
3148
3149         rcu_read_lock();
3150         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3151                                          table_name);
3152         enabled = false;
3153         if (table)
3154                 enabled = table->counters_enabled;
3155         rcu_read_unlock();
3156         return enabled;
3157 }
3158 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
3159
3160 /**
3161  *      devlink_dpipe_table_register - register dpipe table
3162  *
3163  *      @devlink: devlink
3164  *      @table_name: table name
3165  *      @table_ops: table ops
3166  *      @priv: priv
3167  *      @counter_control_extern: external control for counters
3168  */
3169 int devlink_dpipe_table_register(struct devlink *devlink,
3170                                  const char *table_name,
3171                                  struct devlink_dpipe_table_ops *table_ops,
3172                                  void *priv, bool counter_control_extern)
3173 {
3174         struct devlink_dpipe_table *table;
3175
3176         if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name))
3177                 return -EEXIST;
3178
3179         if (WARN_ON(!table_ops->size_get))
3180                 return -EINVAL;
3181
3182         table = kzalloc(sizeof(*table), GFP_KERNEL);
3183         if (!table)
3184                 return -ENOMEM;
3185
3186         table->name = table_name;
3187         table->table_ops = table_ops;
3188         table->priv = priv;
3189         table->counter_control_extern = counter_control_extern;
3190
3191         mutex_lock(&devlink->lock);
3192         list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
3193         mutex_unlock(&devlink->lock);
3194         return 0;
3195 }
3196 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register);
3197
3198 /**
3199  *      devlink_dpipe_table_unregister - unregister dpipe table
3200  *
3201  *      @devlink: devlink
3202  *      @table_name: table name
3203  */
3204 void devlink_dpipe_table_unregister(struct devlink *devlink,
3205                                     const char *table_name)
3206 {
3207         struct devlink_dpipe_table *table;
3208
3209         mutex_lock(&devlink->lock);
3210         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3211                                          table_name);
3212         if (!table)
3213                 goto unlock;
3214         list_del_rcu(&table->list);
3215         mutex_unlock(&devlink->lock);
3216         kfree_rcu(table, rcu);
3217         return;
3218 unlock:
3219         mutex_unlock(&devlink->lock);
3220 }
3221 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
3222
3223 /**
3224  *      devlink_resource_register - devlink resource register
3225  *
3226  *      @devlink: devlink
3227  *      @resource_name: resource's name
3228  *      @top_hierarchy: top hierarchy
3229  *      @reload_required: reload is required for new configuration to
3230  *                        apply
3231  *      @resource_size: resource's size
3232  *      @resource_id: resource's id
3233  *      @parent_reosurce_id: resource's parent id
3234  *      @size params: size parameters
3235  */
3236 int devlink_resource_register(struct devlink *devlink,
3237                               const char *resource_name,
3238                               u64 resource_size,
3239                               u64 resource_id,
3240                               u64 parent_resource_id,
3241                               const struct devlink_resource_size_params *size_params)
3242 {
3243         struct devlink_resource *resource;
3244         struct list_head *resource_list;
3245         bool top_hierarchy;
3246         int err = 0;
3247
3248         top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
3249
3250         mutex_lock(&devlink->lock);
3251         resource = devlink_resource_find(devlink, NULL, resource_id);
3252         if (resource) {
3253                 err = -EINVAL;
3254                 goto out;
3255         }
3256
3257         resource = kzalloc(sizeof(*resource), GFP_KERNEL);
3258         if (!resource) {
3259                 err = -ENOMEM;
3260                 goto out;
3261         }
3262
3263         if (top_hierarchy) {
3264                 resource_list = &devlink->resource_list;
3265         } else {
3266                 struct devlink_resource *parent_resource;
3267
3268                 parent_resource = devlink_resource_find(devlink, NULL,
3269                                                         parent_resource_id);
3270                 if (parent_resource) {
3271                         resource_list = &parent_resource->resource_list;
3272                         resource->parent = parent_resource;
3273                 } else {
3274                         kfree(resource);
3275                         err = -EINVAL;
3276                         goto out;
3277                 }
3278         }
3279
3280         resource->name = resource_name;
3281         resource->size = resource_size;
3282         resource->size_new = resource_size;
3283         resource->id = resource_id;
3284         resource->size_valid = true;
3285         memcpy(&resource->size_params, size_params,
3286                sizeof(resource->size_params));
3287         INIT_LIST_HEAD(&resource->resource_list);
3288         list_add_tail(&resource->list, resource_list);
3289 out:
3290         mutex_unlock(&devlink->lock);
3291         return err;
3292 }
3293 EXPORT_SYMBOL_GPL(devlink_resource_register);
3294
3295 /**
3296  *      devlink_resources_unregister - free all resources
3297  *
3298  *      @devlink: devlink
3299  *      @resource: resource
3300  */
3301 void devlink_resources_unregister(struct devlink *devlink,
3302                                   struct devlink_resource *resource)
3303 {
3304         struct devlink_resource *tmp, *child_resource;
3305         struct list_head *resource_list;
3306
3307         if (resource)
3308                 resource_list = &resource->resource_list;
3309         else
3310                 resource_list = &devlink->resource_list;
3311
3312         if (!resource)
3313                 mutex_lock(&devlink->lock);
3314
3315         list_for_each_entry_safe(child_resource, tmp, resource_list, list) {
3316                 devlink_resources_unregister(devlink, child_resource);
3317                 list_del(&child_resource->list);
3318                 kfree(child_resource);
3319         }
3320
3321         if (!resource)
3322                 mutex_unlock(&devlink->lock);
3323 }
3324 EXPORT_SYMBOL_GPL(devlink_resources_unregister);
3325
3326 /**
3327  *      devlink_resource_size_get - get and update size
3328  *
3329  *      @devlink: devlink
3330  *      @resource_id: the requested resource id
3331  *      @p_resource_size: ptr to update
3332  */
3333 int devlink_resource_size_get(struct devlink *devlink,
3334                               u64 resource_id,
3335                               u64 *p_resource_size)
3336 {
3337         struct devlink_resource *resource;
3338         int err = 0;
3339
3340         mutex_lock(&devlink->lock);
3341         resource = devlink_resource_find(devlink, NULL, resource_id);
3342         if (!resource) {
3343                 err = -EINVAL;
3344                 goto out;
3345         }
3346         *p_resource_size = resource->size_new;
3347         resource->size = resource->size_new;
3348 out:
3349         mutex_unlock(&devlink->lock);
3350         return err;
3351 }
3352 EXPORT_SYMBOL_GPL(devlink_resource_size_get);
3353
3354 /**
3355  *      devlink_dpipe_table_resource_set - set the resource id
3356  *
3357  *      @devlink: devlink
3358  *      @table_name: table name
3359  *      @resource_id: resource id
3360  *      @resource_units: number of resource's units consumed per table's entry
3361  */
3362 int devlink_dpipe_table_resource_set(struct devlink *devlink,
3363                                      const char *table_name, u64 resource_id,
3364                                      u64 resource_units)
3365 {
3366         struct devlink_dpipe_table *table;
3367         int err = 0;
3368
3369         mutex_lock(&devlink->lock);
3370         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3371                                          table_name);
3372         if (!table) {
3373                 err = -EINVAL;
3374                 goto out;
3375         }
3376         table->resource_id = resource_id;
3377         table->resource_units = resource_units;
3378         table->resource_valid = true;
3379 out:
3380         mutex_unlock(&devlink->lock);
3381         return err;
3382 }
3383 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set);
3384
3385 /**
3386  *      devlink_resource_occ_get_register - register occupancy getter
3387  *
3388  *      @devlink: devlink
3389  *      @resource_id: resource id
3390  *      @occ_get: occupancy getter callback
3391  *      @occ_get_priv: occupancy getter callback priv
3392  */
3393 void devlink_resource_occ_get_register(struct devlink *devlink,
3394                                        u64 resource_id,
3395                                        devlink_resource_occ_get_t *occ_get,
3396                                        void *occ_get_priv)
3397 {
3398         struct devlink_resource *resource;
3399
3400         mutex_lock(&devlink->lock);
3401         resource = devlink_resource_find(devlink, NULL, resource_id);
3402         if (WARN_ON(!resource))
3403                 goto out;
3404         WARN_ON(resource->occ_get);
3405
3406         resource->occ_get = occ_get;
3407         resource->occ_get_priv = occ_get_priv;
3408 out:
3409         mutex_unlock(&devlink->lock);
3410 }
3411 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
3412
3413 /**
3414  *      devlink_resource_occ_get_unregister - unregister occupancy getter
3415  *
3416  *      @devlink: devlink
3417  *      @resource_id: resource id
3418  */
3419 void devlink_resource_occ_get_unregister(struct devlink *devlink,
3420                                          u64 resource_id)
3421 {
3422         struct devlink_resource *resource;
3423
3424         mutex_lock(&devlink->lock);
3425         resource = devlink_resource_find(devlink, NULL, resource_id);
3426         if (WARN_ON(!resource))
3427                 goto out;
3428         WARN_ON(!resource->occ_get);
3429
3430         resource->occ_get = NULL;
3431         resource->occ_get_priv = NULL;
3432 out:
3433         mutex_unlock(&devlink->lock);
3434 }
3435 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
3436
3437 static int __init devlink_module_init(void)
3438 {
3439         return genl_register_family(&devlink_nl_family);
3440 }
3441
3442 static void __exit devlink_module_exit(void)
3443 {
3444         genl_unregister_family(&devlink_nl_family);
3445 }
3446
3447 module_init(devlink_module_init);
3448 module_exit(devlink_module_exit);
3449
3450 MODULE_LICENSE("GPL v2");
3451 MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
3452 MODULE_DESCRIPTION("Network physical device Netlink interface");
3453 MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);