GNU Linux-libre 6.8.7-gnu
[releases.git] / net / core / netdev-genl.c
1 // SPDX-License-Identifier: GPL-2.0-only
2
3 #include <linux/netdevice.h>
4 #include <linux/notifier.h>
5 #include <linux/rtnetlink.h>
6 #include <net/net_namespace.h>
7 #include <net/sock.h>
8 #include <net/xdp.h>
9 #include <net/xdp_sock.h>
10 #include <net/netdev_rx_queue.h>
11 #include <net/busy_poll.h>
12
13 #include "netdev-genl-gen.h"
14 #include "dev.h"
15
16 struct netdev_nl_dump_ctx {
17         unsigned long   ifindex;
18         unsigned int    rxq_idx;
19         unsigned int    txq_idx;
20         unsigned int    napi_id;
21 };
22
23 static struct netdev_nl_dump_ctx *netdev_dump_ctx(struct netlink_callback *cb)
24 {
25         NL_ASSERT_DUMP_CTX_FITS(struct netdev_nl_dump_ctx);
26
27         return (struct netdev_nl_dump_ctx *)cb->ctx;
28 }
29
30 static int
31 netdev_nl_dev_fill(struct net_device *netdev, struct sk_buff *rsp,
32                    const struct genl_info *info)
33 {
34         u64 xsk_features = 0;
35         u64 xdp_rx_meta = 0;
36         void *hdr;
37
38         hdr = genlmsg_iput(rsp, info);
39         if (!hdr)
40                 return -EMSGSIZE;
41
42 #define XDP_METADATA_KFUNC(_, flag, __, xmo) \
43         if (netdev->xdp_metadata_ops && netdev->xdp_metadata_ops->xmo) \
44                 xdp_rx_meta |= flag;
45 XDP_METADATA_KFUNC_xxx
46 #undef XDP_METADATA_KFUNC
47
48         if (netdev->xsk_tx_metadata_ops) {
49                 if (netdev->xsk_tx_metadata_ops->tmo_fill_timestamp)
50                         xsk_features |= NETDEV_XSK_FLAGS_TX_TIMESTAMP;
51                 if (netdev->xsk_tx_metadata_ops->tmo_request_checksum)
52                         xsk_features |= NETDEV_XSK_FLAGS_TX_CHECKSUM;
53         }
54
55         if (nla_put_u32(rsp, NETDEV_A_DEV_IFINDEX, netdev->ifindex) ||
56             nla_put_u64_64bit(rsp, NETDEV_A_DEV_XDP_FEATURES,
57                               netdev->xdp_features, NETDEV_A_DEV_PAD) ||
58             nla_put_u64_64bit(rsp, NETDEV_A_DEV_XDP_RX_METADATA_FEATURES,
59                               xdp_rx_meta, NETDEV_A_DEV_PAD) ||
60             nla_put_u64_64bit(rsp, NETDEV_A_DEV_XSK_FEATURES,
61                               xsk_features, NETDEV_A_DEV_PAD)) {
62                 genlmsg_cancel(rsp, hdr);
63                 return -EINVAL;
64         }
65
66         if (netdev->xdp_features & NETDEV_XDP_ACT_XSK_ZEROCOPY) {
67                 if (nla_put_u32(rsp, NETDEV_A_DEV_XDP_ZC_MAX_SEGS,
68                                 netdev->xdp_zc_max_segs)) {
69                         genlmsg_cancel(rsp, hdr);
70                         return -EINVAL;
71                 }
72         }
73
74         genlmsg_end(rsp, hdr);
75
76         return 0;
77 }
78
79 static void
80 netdev_genl_dev_notify(struct net_device *netdev, int cmd)
81 {
82         struct genl_info info;
83         struct sk_buff *ntf;
84
85         if (!genl_has_listeners(&netdev_nl_family, dev_net(netdev),
86                                 NETDEV_NLGRP_MGMT))
87                 return;
88
89         genl_info_init_ntf(&info, &netdev_nl_family, cmd);
90
91         ntf = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
92         if (!ntf)
93                 return;
94
95         if (netdev_nl_dev_fill(netdev, ntf, &info)) {
96                 nlmsg_free(ntf);
97                 return;
98         }
99
100         genlmsg_multicast_netns(&netdev_nl_family, dev_net(netdev), ntf,
101                                 0, NETDEV_NLGRP_MGMT, GFP_KERNEL);
102 }
103
104 int netdev_nl_dev_get_doit(struct sk_buff *skb, struct genl_info *info)
105 {
106         struct net_device *netdev;
107         struct sk_buff *rsp;
108         u32 ifindex;
109         int err;
110
111         if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_DEV_IFINDEX))
112                 return -EINVAL;
113
114         ifindex = nla_get_u32(info->attrs[NETDEV_A_DEV_IFINDEX]);
115
116         rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
117         if (!rsp)
118                 return -ENOMEM;
119
120         rtnl_lock();
121
122         netdev = __dev_get_by_index(genl_info_net(info), ifindex);
123         if (netdev)
124                 err = netdev_nl_dev_fill(netdev, rsp, info);
125         else
126                 err = -ENODEV;
127
128         rtnl_unlock();
129
130         if (err)
131                 goto err_free_msg;
132
133         return genlmsg_reply(rsp, info);
134
135 err_free_msg:
136         nlmsg_free(rsp);
137         return err;
138 }
139
140 int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
141 {
142         struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
143         struct net *net = sock_net(skb->sk);
144         struct net_device *netdev;
145         int err = 0;
146
147         rtnl_lock();
148         for_each_netdev_dump(net, netdev, ctx->ifindex) {
149                 err = netdev_nl_dev_fill(netdev, skb, genl_info_dump(cb));
150                 if (err < 0)
151                         break;
152         }
153         rtnl_unlock();
154
155         return err;
156 }
157
158 static int
159 netdev_nl_napi_fill_one(struct sk_buff *rsp, struct napi_struct *napi,
160                         const struct genl_info *info)
161 {
162         void *hdr;
163         pid_t pid;
164
165         if (WARN_ON_ONCE(!napi->dev))
166                 return -EINVAL;
167         if (!(napi->dev->flags & IFF_UP))
168                 return 0;
169
170         hdr = genlmsg_iput(rsp, info);
171         if (!hdr)
172                 return -EMSGSIZE;
173
174         if (napi->napi_id >= MIN_NAPI_ID &&
175             nla_put_u32(rsp, NETDEV_A_NAPI_ID, napi->napi_id))
176                 goto nla_put_failure;
177
178         if (nla_put_u32(rsp, NETDEV_A_NAPI_IFINDEX, napi->dev->ifindex))
179                 goto nla_put_failure;
180
181         if (napi->irq >= 0 && nla_put_u32(rsp, NETDEV_A_NAPI_IRQ, napi->irq))
182                 goto nla_put_failure;
183
184         if (napi->thread) {
185                 pid = task_pid_nr(napi->thread);
186                 if (nla_put_u32(rsp, NETDEV_A_NAPI_PID, pid))
187                         goto nla_put_failure;
188         }
189
190         genlmsg_end(rsp, hdr);
191
192         return 0;
193
194 nla_put_failure:
195         genlmsg_cancel(rsp, hdr);
196         return -EMSGSIZE;
197 }
198
199 int netdev_nl_napi_get_doit(struct sk_buff *skb, struct genl_info *info)
200 {
201         struct napi_struct *napi;
202         struct sk_buff *rsp;
203         u32 napi_id;
204         int err;
205
206         if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_NAPI_ID))
207                 return -EINVAL;
208
209         napi_id = nla_get_u32(info->attrs[NETDEV_A_NAPI_ID]);
210
211         rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
212         if (!rsp)
213                 return -ENOMEM;
214
215         rtnl_lock();
216
217         napi = napi_by_id(napi_id);
218         if (napi)
219                 err = netdev_nl_napi_fill_one(rsp, napi, info);
220         else
221                 err = -EINVAL;
222
223         rtnl_unlock();
224
225         if (err)
226                 goto err_free_msg;
227
228         return genlmsg_reply(rsp, info);
229
230 err_free_msg:
231         nlmsg_free(rsp);
232         return err;
233 }
234
235 static int
236 netdev_nl_napi_dump_one(struct net_device *netdev, struct sk_buff *rsp,
237                         const struct genl_info *info,
238                         struct netdev_nl_dump_ctx *ctx)
239 {
240         struct napi_struct *napi;
241         int err = 0;
242
243         if (!(netdev->flags & IFF_UP))
244                 return err;
245
246         list_for_each_entry(napi, &netdev->napi_list, dev_list) {
247                 if (ctx->napi_id && napi->napi_id >= ctx->napi_id)
248                         continue;
249
250                 err = netdev_nl_napi_fill_one(rsp, napi, info);
251                 if (err)
252                         return err;
253                 ctx->napi_id = napi->napi_id;
254         }
255         return err;
256 }
257
258 int netdev_nl_napi_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
259 {
260         struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
261         const struct genl_info *info = genl_info_dump(cb);
262         struct net *net = sock_net(skb->sk);
263         struct net_device *netdev;
264         u32 ifindex = 0;
265         int err = 0;
266
267         if (info->attrs[NETDEV_A_NAPI_IFINDEX])
268                 ifindex = nla_get_u32(info->attrs[NETDEV_A_NAPI_IFINDEX]);
269
270         rtnl_lock();
271         if (ifindex) {
272                 netdev = __dev_get_by_index(net, ifindex);
273                 if (netdev)
274                         err = netdev_nl_napi_dump_one(netdev, skb, info, ctx);
275                 else
276                         err = -ENODEV;
277         } else {
278                 for_each_netdev_dump(net, netdev, ctx->ifindex) {
279                         err = netdev_nl_napi_dump_one(netdev, skb, info, ctx);
280                         if (err < 0)
281                                 break;
282                         ctx->napi_id = 0;
283                 }
284         }
285         rtnl_unlock();
286
287         return err;
288 }
289
290 static int
291 netdev_nl_queue_fill_one(struct sk_buff *rsp, struct net_device *netdev,
292                          u32 q_idx, u32 q_type, const struct genl_info *info)
293 {
294         struct netdev_rx_queue *rxq;
295         struct netdev_queue *txq;
296         void *hdr;
297
298         hdr = genlmsg_iput(rsp, info);
299         if (!hdr)
300                 return -EMSGSIZE;
301
302         if (nla_put_u32(rsp, NETDEV_A_QUEUE_ID, q_idx) ||
303             nla_put_u32(rsp, NETDEV_A_QUEUE_TYPE, q_type) ||
304             nla_put_u32(rsp, NETDEV_A_QUEUE_IFINDEX, netdev->ifindex))
305                 goto nla_put_failure;
306
307         switch (q_type) {
308         case NETDEV_QUEUE_TYPE_RX:
309                 rxq = __netif_get_rx_queue(netdev, q_idx);
310                 if (rxq->napi && nla_put_u32(rsp, NETDEV_A_QUEUE_NAPI_ID,
311                                              rxq->napi->napi_id))
312                         goto nla_put_failure;
313                 break;
314         case NETDEV_QUEUE_TYPE_TX:
315                 txq = netdev_get_tx_queue(netdev, q_idx);
316                 if (txq->napi && nla_put_u32(rsp, NETDEV_A_QUEUE_NAPI_ID,
317                                              txq->napi->napi_id))
318                         goto nla_put_failure;
319         }
320
321         genlmsg_end(rsp, hdr);
322
323         return 0;
324
325 nla_put_failure:
326         genlmsg_cancel(rsp, hdr);
327         return -EMSGSIZE;
328 }
329
330 static int netdev_nl_queue_validate(struct net_device *netdev, u32 q_id,
331                                     u32 q_type)
332 {
333         switch (q_type) {
334         case NETDEV_QUEUE_TYPE_RX:
335                 if (q_id >= netdev->real_num_rx_queues)
336                         return -EINVAL;
337                 return 0;
338         case NETDEV_QUEUE_TYPE_TX:
339                 if (q_id >= netdev->real_num_tx_queues)
340                         return -EINVAL;
341         }
342         return 0;
343 }
344
345 static int
346 netdev_nl_queue_fill(struct sk_buff *rsp, struct net_device *netdev, u32 q_idx,
347                      u32 q_type, const struct genl_info *info)
348 {
349         int err = 0;
350
351         if (!(netdev->flags & IFF_UP))
352                 return err;
353
354         err = netdev_nl_queue_validate(netdev, q_idx, q_type);
355         if (err)
356                 return err;
357
358         return netdev_nl_queue_fill_one(rsp, netdev, q_idx, q_type, info);
359 }
360
361 int netdev_nl_queue_get_doit(struct sk_buff *skb, struct genl_info *info)
362 {
363         u32 q_id, q_type, ifindex;
364         struct net_device *netdev;
365         struct sk_buff *rsp;
366         int err;
367
368         if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_QUEUE_ID) ||
369             GENL_REQ_ATTR_CHECK(info, NETDEV_A_QUEUE_TYPE) ||
370             GENL_REQ_ATTR_CHECK(info, NETDEV_A_QUEUE_IFINDEX))
371                 return -EINVAL;
372
373         q_id = nla_get_u32(info->attrs[NETDEV_A_QUEUE_ID]);
374         q_type = nla_get_u32(info->attrs[NETDEV_A_QUEUE_TYPE]);
375         ifindex = nla_get_u32(info->attrs[NETDEV_A_QUEUE_IFINDEX]);
376
377         rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
378         if (!rsp)
379                 return -ENOMEM;
380
381         rtnl_lock();
382
383         netdev = __dev_get_by_index(genl_info_net(info), ifindex);
384         if (netdev)
385                 err = netdev_nl_queue_fill(rsp, netdev, q_id, q_type, info);
386         else
387                 err = -ENODEV;
388
389         rtnl_unlock();
390
391         if (err)
392                 goto err_free_msg;
393
394         return genlmsg_reply(rsp, info);
395
396 err_free_msg:
397         nlmsg_free(rsp);
398         return err;
399 }
400
401 static int
402 netdev_nl_queue_dump_one(struct net_device *netdev, struct sk_buff *rsp,
403                          const struct genl_info *info,
404                          struct netdev_nl_dump_ctx *ctx)
405 {
406         int err = 0;
407         int i;
408
409         if (!(netdev->flags & IFF_UP))
410                 return err;
411
412         for (i = ctx->rxq_idx; i < netdev->real_num_rx_queues;) {
413                 err = netdev_nl_queue_fill_one(rsp, netdev, i,
414                                                NETDEV_QUEUE_TYPE_RX, info);
415                 if (err)
416                         return err;
417                 ctx->rxq_idx = i++;
418         }
419         for (i = ctx->txq_idx; i < netdev->real_num_tx_queues;) {
420                 err = netdev_nl_queue_fill_one(rsp, netdev, i,
421                                                NETDEV_QUEUE_TYPE_TX, info);
422                 if (err)
423                         return err;
424                 ctx->txq_idx = i++;
425         }
426
427         return err;
428 }
429
430 int netdev_nl_queue_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
431 {
432         struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
433         const struct genl_info *info = genl_info_dump(cb);
434         struct net *net = sock_net(skb->sk);
435         struct net_device *netdev;
436         u32 ifindex = 0;
437         int err = 0;
438
439         if (info->attrs[NETDEV_A_QUEUE_IFINDEX])
440                 ifindex = nla_get_u32(info->attrs[NETDEV_A_QUEUE_IFINDEX]);
441
442         rtnl_lock();
443         if (ifindex) {
444                 netdev = __dev_get_by_index(net, ifindex);
445                 if (netdev)
446                         err = netdev_nl_queue_dump_one(netdev, skb, info, ctx);
447                 else
448                         err = -ENODEV;
449         } else {
450                 for_each_netdev_dump(net, netdev, ctx->ifindex) {
451                         err = netdev_nl_queue_dump_one(netdev, skb, info, ctx);
452                         if (err < 0)
453                                 break;
454                         ctx->rxq_idx = 0;
455                         ctx->txq_idx = 0;
456                 }
457         }
458         rtnl_unlock();
459
460         return err;
461 }
462
463 static int netdev_genl_netdevice_event(struct notifier_block *nb,
464                                        unsigned long event, void *ptr)
465 {
466         struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
467
468         switch (event) {
469         case NETDEV_REGISTER:
470                 netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_ADD_NTF);
471                 break;
472         case NETDEV_UNREGISTER:
473                 netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_DEL_NTF);
474                 break;
475         case NETDEV_XDP_FEAT_CHANGE:
476                 netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_CHANGE_NTF);
477                 break;
478         }
479
480         return NOTIFY_OK;
481 }
482
483 static struct notifier_block netdev_genl_nb = {
484         .notifier_call  = netdev_genl_netdevice_event,
485 };
486
487 static int __init netdev_genl_init(void)
488 {
489         int err;
490
491         err = register_netdevice_notifier(&netdev_genl_nb);
492         if (err)
493                 return err;
494
495         err = genl_register_family(&netdev_nl_family);
496         if (err)
497                 goto err_unreg_ntf;
498
499         return 0;
500
501 err_unreg_ntf:
502         unregister_netdevice_notifier(&netdev_genl_nb);
503         return err;
504 }
505
506 subsys_initcall(netdev_genl_init);