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