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); 507