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