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