at v4.12-rc1 72 kB view raw
1/* 2 * net/core/devlink.c - Network physical/parent device Netlink interface 3 * 4 * Heavily inspired by net/wireless/ 5 * Copyright (c) 2016 Mellanox Technologies. All rights reserved. 6 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 */ 13 14#include <linux/kernel.h> 15#include <linux/module.h> 16#include <linux/types.h> 17#include <linux/slab.h> 18#include <linux/gfp.h> 19#include <linux/device.h> 20#include <linux/list.h> 21#include <linux/netdevice.h> 22#include <rdma/ib_verbs.h> 23#include <net/netlink.h> 24#include <net/genetlink.h> 25#include <net/rtnetlink.h> 26#include <net/net_namespace.h> 27#include <net/sock.h> 28#include <net/devlink.h> 29#define CREATE_TRACE_POINTS 30#include <trace/events/devlink.h> 31 32EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg); 33 34static LIST_HEAD(devlink_list); 35 36/* devlink_mutex 37 * 38 * An overall lock guarding every operation coming from userspace. 39 * It also guards devlink devices list and it is taken when 40 * driver registers/unregisters it. 41 */ 42static DEFINE_MUTEX(devlink_mutex); 43 44/* devlink_port_mutex 45 * 46 * Shared lock to guard lists of ports in all devlink devices. 47 */ 48static DEFINE_MUTEX(devlink_port_mutex); 49 50static struct net *devlink_net(const struct devlink *devlink) 51{ 52 return read_pnet(&devlink->_net); 53} 54 55static void devlink_net_set(struct devlink *devlink, struct net *net) 56{ 57 write_pnet(&devlink->_net, net); 58} 59 60static struct devlink *devlink_get_from_attrs(struct net *net, 61 struct nlattr **attrs) 62{ 63 struct devlink *devlink; 64 char *busname; 65 char *devname; 66 67 if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME]) 68 return ERR_PTR(-EINVAL); 69 70 busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]); 71 devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]); 72 73 list_for_each_entry(devlink, &devlink_list, list) { 74 if (strcmp(devlink->dev->bus->name, busname) == 0 && 75 strcmp(dev_name(devlink->dev), devname) == 0 && 76 net_eq(devlink_net(devlink), net)) 77 return devlink; 78 } 79 80 return ERR_PTR(-ENODEV); 81} 82 83static struct devlink *devlink_get_from_info(struct genl_info *info) 84{ 85 return devlink_get_from_attrs(genl_info_net(info), info->attrs); 86} 87 88static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink, 89 int port_index) 90{ 91 struct devlink_port *devlink_port; 92 93 list_for_each_entry(devlink_port, &devlink->port_list, list) { 94 if (devlink_port->index == port_index) 95 return devlink_port; 96 } 97 return NULL; 98} 99 100static bool devlink_port_index_exists(struct devlink *devlink, int port_index) 101{ 102 return devlink_port_get_by_index(devlink, port_index); 103} 104 105static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink, 106 struct nlattr **attrs) 107{ 108 if (attrs[DEVLINK_ATTR_PORT_INDEX]) { 109 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]); 110 struct devlink_port *devlink_port; 111 112 devlink_port = devlink_port_get_by_index(devlink, port_index); 113 if (!devlink_port) 114 return ERR_PTR(-ENODEV); 115 return devlink_port; 116 } 117 return ERR_PTR(-EINVAL); 118} 119 120static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink, 121 struct genl_info *info) 122{ 123 return devlink_port_get_from_attrs(devlink, info->attrs); 124} 125 126struct devlink_sb { 127 struct list_head list; 128 unsigned int index; 129 u32 size; 130 u16 ingress_pools_count; 131 u16 egress_pools_count; 132 u16 ingress_tc_count; 133 u16 egress_tc_count; 134}; 135 136static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb) 137{ 138 return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count; 139} 140 141static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink, 142 unsigned int sb_index) 143{ 144 struct devlink_sb *devlink_sb; 145 146 list_for_each_entry(devlink_sb, &devlink->sb_list, list) { 147 if (devlink_sb->index == sb_index) 148 return devlink_sb; 149 } 150 return NULL; 151} 152 153static bool devlink_sb_index_exists(struct devlink *devlink, 154 unsigned int sb_index) 155{ 156 return devlink_sb_get_by_index(devlink, sb_index); 157} 158 159static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink, 160 struct nlattr **attrs) 161{ 162 if (attrs[DEVLINK_ATTR_SB_INDEX]) { 163 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]); 164 struct devlink_sb *devlink_sb; 165 166 devlink_sb = devlink_sb_get_by_index(devlink, sb_index); 167 if (!devlink_sb) 168 return ERR_PTR(-ENODEV); 169 return devlink_sb; 170 } 171 return ERR_PTR(-EINVAL); 172} 173 174static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink, 175 struct genl_info *info) 176{ 177 return devlink_sb_get_from_attrs(devlink, info->attrs); 178} 179 180static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb, 181 struct nlattr **attrs, 182 u16 *p_pool_index) 183{ 184 u16 val; 185 186 if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX]) 187 return -EINVAL; 188 189 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]); 190 if (val >= devlink_sb_pool_count(devlink_sb)) 191 return -EINVAL; 192 *p_pool_index = val; 193 return 0; 194} 195 196static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb, 197 struct genl_info *info, 198 u16 *p_pool_index) 199{ 200 return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs, 201 p_pool_index); 202} 203 204static int 205devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs, 206 enum devlink_sb_pool_type *p_pool_type) 207{ 208 u8 val; 209 210 if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE]) 211 return -EINVAL; 212 213 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]); 214 if (val != DEVLINK_SB_POOL_TYPE_INGRESS && 215 val != DEVLINK_SB_POOL_TYPE_EGRESS) 216 return -EINVAL; 217 *p_pool_type = val; 218 return 0; 219} 220 221static int 222devlink_sb_pool_type_get_from_info(struct genl_info *info, 223 enum devlink_sb_pool_type *p_pool_type) 224{ 225 return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type); 226} 227 228static int 229devlink_sb_th_type_get_from_attrs(struct nlattr **attrs, 230 enum devlink_sb_threshold_type *p_th_type) 231{ 232 u8 val; 233 234 if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]) 235 return -EINVAL; 236 237 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]); 238 if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC && 239 val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC) 240 return -EINVAL; 241 *p_th_type = val; 242 return 0; 243} 244 245static int 246devlink_sb_th_type_get_from_info(struct genl_info *info, 247 enum devlink_sb_threshold_type *p_th_type) 248{ 249 return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type); 250} 251 252static int 253devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb, 254 struct nlattr **attrs, 255 enum devlink_sb_pool_type pool_type, 256 u16 *p_tc_index) 257{ 258 u16 val; 259 260 if (!attrs[DEVLINK_ATTR_SB_TC_INDEX]) 261 return -EINVAL; 262 263 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]); 264 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS && 265 val >= devlink_sb->ingress_tc_count) 266 return -EINVAL; 267 if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS && 268 val >= devlink_sb->egress_tc_count) 269 return -EINVAL; 270 *p_tc_index = val; 271 return 0; 272} 273 274static int 275devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb, 276 struct genl_info *info, 277 enum devlink_sb_pool_type pool_type, 278 u16 *p_tc_index) 279{ 280 return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs, 281 pool_type, p_tc_index); 282} 283 284#define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0) 285#define DEVLINK_NL_FLAG_NEED_PORT BIT(1) 286#define DEVLINK_NL_FLAG_NEED_SB BIT(2) 287#define DEVLINK_NL_FLAG_LOCK_PORTS BIT(3) 288 /* port is not needed but we need to ensure they don't 289 * change in the middle of command 290 */ 291 292static int devlink_nl_pre_doit(const struct genl_ops *ops, 293 struct sk_buff *skb, struct genl_info *info) 294{ 295 struct devlink *devlink; 296 297 mutex_lock(&devlink_mutex); 298 devlink = devlink_get_from_info(info); 299 if (IS_ERR(devlink)) { 300 mutex_unlock(&devlink_mutex); 301 return PTR_ERR(devlink); 302 } 303 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) { 304 info->user_ptr[0] = devlink; 305 } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) { 306 struct devlink_port *devlink_port; 307 308 mutex_lock(&devlink_port_mutex); 309 devlink_port = devlink_port_get_from_info(devlink, info); 310 if (IS_ERR(devlink_port)) { 311 mutex_unlock(&devlink_port_mutex); 312 mutex_unlock(&devlink_mutex); 313 return PTR_ERR(devlink_port); 314 } 315 info->user_ptr[0] = devlink_port; 316 } 317 if (ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS) { 318 mutex_lock(&devlink_port_mutex); 319 } 320 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) { 321 struct devlink_sb *devlink_sb; 322 323 devlink_sb = devlink_sb_get_from_info(devlink, info); 324 if (IS_ERR(devlink_sb)) { 325 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) 326 mutex_unlock(&devlink_port_mutex); 327 mutex_unlock(&devlink_mutex); 328 return PTR_ERR(devlink_sb); 329 } 330 info->user_ptr[1] = devlink_sb; 331 } 332 return 0; 333} 334 335static void devlink_nl_post_doit(const struct genl_ops *ops, 336 struct sk_buff *skb, struct genl_info *info) 337{ 338 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT || 339 ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS) 340 mutex_unlock(&devlink_port_mutex); 341 mutex_unlock(&devlink_mutex); 342} 343 344static struct genl_family devlink_nl_family; 345 346enum devlink_multicast_groups { 347 DEVLINK_MCGRP_CONFIG, 348}; 349 350static const struct genl_multicast_group devlink_nl_mcgrps[] = { 351 [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME }, 352}; 353 354static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink) 355{ 356 if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name)) 357 return -EMSGSIZE; 358 if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev))) 359 return -EMSGSIZE; 360 return 0; 361} 362 363static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink, 364 enum devlink_command cmd, u32 portid, 365 u32 seq, int flags) 366{ 367 void *hdr; 368 369 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 370 if (!hdr) 371 return -EMSGSIZE; 372 373 if (devlink_nl_put_handle(msg, devlink)) 374 goto nla_put_failure; 375 376 genlmsg_end(msg, hdr); 377 return 0; 378 379nla_put_failure: 380 genlmsg_cancel(msg, hdr); 381 return -EMSGSIZE; 382} 383 384static void devlink_notify(struct devlink *devlink, enum devlink_command cmd) 385{ 386 struct sk_buff *msg; 387 int err; 388 389 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL); 390 391 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 392 if (!msg) 393 return; 394 395 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0); 396 if (err) { 397 nlmsg_free(msg); 398 return; 399 } 400 401 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 402 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 403} 404 405static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink, 406 struct devlink_port *devlink_port, 407 enum devlink_command cmd, u32 portid, 408 u32 seq, int flags) 409{ 410 void *hdr; 411 412 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 413 if (!hdr) 414 return -EMSGSIZE; 415 416 if (devlink_nl_put_handle(msg, devlink)) 417 goto nla_put_failure; 418 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) 419 goto nla_put_failure; 420 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type)) 421 goto nla_put_failure; 422 if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET && 423 nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE, 424 devlink_port->desired_type)) 425 goto nla_put_failure; 426 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) { 427 struct net_device *netdev = devlink_port->type_dev; 428 429 if (netdev && 430 (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX, 431 netdev->ifindex) || 432 nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME, 433 netdev->name))) 434 goto nla_put_failure; 435 } 436 if (devlink_port->type == DEVLINK_PORT_TYPE_IB) { 437 struct ib_device *ibdev = devlink_port->type_dev; 438 439 if (ibdev && 440 nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME, 441 ibdev->name)) 442 goto nla_put_failure; 443 } 444 if (devlink_port->split && 445 nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP, 446 devlink_port->split_group)) 447 goto nla_put_failure; 448 449 genlmsg_end(msg, hdr); 450 return 0; 451 452nla_put_failure: 453 genlmsg_cancel(msg, hdr); 454 return -EMSGSIZE; 455} 456 457static void devlink_port_notify(struct devlink_port *devlink_port, 458 enum devlink_command cmd) 459{ 460 struct devlink *devlink = devlink_port->devlink; 461 struct sk_buff *msg; 462 int err; 463 464 if (!devlink_port->registered) 465 return; 466 467 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL); 468 469 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 470 if (!msg) 471 return; 472 473 err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0); 474 if (err) { 475 nlmsg_free(msg); 476 return; 477 } 478 479 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), 480 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 481} 482 483static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info) 484{ 485 struct devlink *devlink = info->user_ptr[0]; 486 struct sk_buff *msg; 487 int err; 488 489 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 490 if (!msg) 491 return -ENOMEM; 492 493 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, 494 info->snd_portid, info->snd_seq, 0); 495 if (err) { 496 nlmsg_free(msg); 497 return err; 498 } 499 500 return genlmsg_reply(msg, info); 501} 502 503static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg, 504 struct netlink_callback *cb) 505{ 506 struct devlink *devlink; 507 int start = cb->args[0]; 508 int idx = 0; 509 int err; 510 511 mutex_lock(&devlink_mutex); 512 list_for_each_entry(devlink, &devlink_list, list) { 513 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 514 continue; 515 if (idx < start) { 516 idx++; 517 continue; 518 } 519 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, 520 NETLINK_CB(cb->skb).portid, 521 cb->nlh->nlmsg_seq, NLM_F_MULTI); 522 if (err) 523 goto out; 524 idx++; 525 } 526out: 527 mutex_unlock(&devlink_mutex); 528 529 cb->args[0] = idx; 530 return msg->len; 531} 532 533static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb, 534 struct genl_info *info) 535{ 536 struct devlink_port *devlink_port = info->user_ptr[0]; 537 struct devlink *devlink = devlink_port->devlink; 538 struct sk_buff *msg; 539 int err; 540 541 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 542 if (!msg) 543 return -ENOMEM; 544 545 err = devlink_nl_port_fill(msg, devlink, devlink_port, 546 DEVLINK_CMD_PORT_NEW, 547 info->snd_portid, info->snd_seq, 0); 548 if (err) { 549 nlmsg_free(msg); 550 return err; 551 } 552 553 return genlmsg_reply(msg, info); 554} 555 556static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg, 557 struct netlink_callback *cb) 558{ 559 struct devlink *devlink; 560 struct devlink_port *devlink_port; 561 int start = cb->args[0]; 562 int idx = 0; 563 int err; 564 565 mutex_lock(&devlink_mutex); 566 mutex_lock(&devlink_port_mutex); 567 list_for_each_entry(devlink, &devlink_list, list) { 568 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 569 continue; 570 list_for_each_entry(devlink_port, &devlink->port_list, list) { 571 if (idx < start) { 572 idx++; 573 continue; 574 } 575 err = devlink_nl_port_fill(msg, devlink, devlink_port, 576 DEVLINK_CMD_NEW, 577 NETLINK_CB(cb->skb).portid, 578 cb->nlh->nlmsg_seq, 579 NLM_F_MULTI); 580 if (err) 581 goto out; 582 idx++; 583 } 584 } 585out: 586 mutex_unlock(&devlink_port_mutex); 587 mutex_unlock(&devlink_mutex); 588 589 cb->args[0] = idx; 590 return msg->len; 591} 592 593static int devlink_port_type_set(struct devlink *devlink, 594 struct devlink_port *devlink_port, 595 enum devlink_port_type port_type) 596 597{ 598 int err; 599 600 if (devlink->ops && devlink->ops->port_type_set) { 601 if (port_type == DEVLINK_PORT_TYPE_NOTSET) 602 return -EINVAL; 603 if (port_type == devlink_port->type) 604 return 0; 605 err = devlink->ops->port_type_set(devlink_port, port_type); 606 if (err) 607 return err; 608 devlink_port->desired_type = port_type; 609 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 610 return 0; 611 } 612 return -EOPNOTSUPP; 613} 614 615static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb, 616 struct genl_info *info) 617{ 618 struct devlink_port *devlink_port = info->user_ptr[0]; 619 struct devlink *devlink = devlink_port->devlink; 620 int err; 621 622 if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) { 623 enum devlink_port_type port_type; 624 625 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]); 626 err = devlink_port_type_set(devlink, devlink_port, port_type); 627 if (err) 628 return err; 629 } 630 return 0; 631} 632 633static int devlink_port_split(struct devlink *devlink, 634 u32 port_index, u32 count) 635 636{ 637 if (devlink->ops && devlink->ops->port_split) 638 return devlink->ops->port_split(devlink, port_index, count); 639 return -EOPNOTSUPP; 640} 641 642static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb, 643 struct genl_info *info) 644{ 645 struct devlink *devlink = info->user_ptr[0]; 646 u32 port_index; 647 u32 count; 648 649 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] || 650 !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]) 651 return -EINVAL; 652 653 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 654 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]); 655 return devlink_port_split(devlink, port_index, count); 656} 657 658static int devlink_port_unsplit(struct devlink *devlink, u32 port_index) 659 660{ 661 if (devlink->ops && devlink->ops->port_unsplit) 662 return devlink->ops->port_unsplit(devlink, port_index); 663 return -EOPNOTSUPP; 664} 665 666static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb, 667 struct genl_info *info) 668{ 669 struct devlink *devlink = info->user_ptr[0]; 670 u32 port_index; 671 672 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX]) 673 return -EINVAL; 674 675 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 676 return devlink_port_unsplit(devlink, port_index); 677} 678 679static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink, 680 struct devlink_sb *devlink_sb, 681 enum devlink_command cmd, u32 portid, 682 u32 seq, int flags) 683{ 684 void *hdr; 685 686 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 687 if (!hdr) 688 return -EMSGSIZE; 689 690 if (devlink_nl_put_handle(msg, devlink)) 691 goto nla_put_failure; 692 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) 693 goto nla_put_failure; 694 if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size)) 695 goto nla_put_failure; 696 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT, 697 devlink_sb->ingress_pools_count)) 698 goto nla_put_failure; 699 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT, 700 devlink_sb->egress_pools_count)) 701 goto nla_put_failure; 702 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT, 703 devlink_sb->ingress_tc_count)) 704 goto nla_put_failure; 705 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT, 706 devlink_sb->egress_tc_count)) 707 goto nla_put_failure; 708 709 genlmsg_end(msg, hdr); 710 return 0; 711 712nla_put_failure: 713 genlmsg_cancel(msg, hdr); 714 return -EMSGSIZE; 715} 716 717static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb, 718 struct genl_info *info) 719{ 720 struct devlink *devlink = info->user_ptr[0]; 721 struct devlink_sb *devlink_sb = info->user_ptr[1]; 722 struct sk_buff *msg; 723 int err; 724 725 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 726 if (!msg) 727 return -ENOMEM; 728 729 err = devlink_nl_sb_fill(msg, devlink, devlink_sb, 730 DEVLINK_CMD_SB_NEW, 731 info->snd_portid, info->snd_seq, 0); 732 if (err) { 733 nlmsg_free(msg); 734 return err; 735 } 736 737 return genlmsg_reply(msg, info); 738} 739 740static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg, 741 struct netlink_callback *cb) 742{ 743 struct devlink *devlink; 744 struct devlink_sb *devlink_sb; 745 int start = cb->args[0]; 746 int idx = 0; 747 int err; 748 749 mutex_lock(&devlink_mutex); 750 list_for_each_entry(devlink, &devlink_list, list) { 751 if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) 752 continue; 753 list_for_each_entry(devlink_sb, &devlink->sb_list, list) { 754 if (idx < start) { 755 idx++; 756 continue; 757 } 758 err = devlink_nl_sb_fill(msg, devlink, devlink_sb, 759 DEVLINK_CMD_SB_NEW, 760 NETLINK_CB(cb->skb).portid, 761 cb->nlh->nlmsg_seq, 762 NLM_F_MULTI); 763 if (err) 764 goto out; 765 idx++; 766 } 767 } 768out: 769 mutex_unlock(&devlink_mutex); 770 771 cb->args[0] = idx; 772 return msg->len; 773} 774 775static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink, 776 struct devlink_sb *devlink_sb, 777 u16 pool_index, enum devlink_command cmd, 778 u32 portid, u32 seq, int flags) 779{ 780 struct devlink_sb_pool_info pool_info; 781 void *hdr; 782 int err; 783 784 err = devlink->ops->sb_pool_get(devlink, devlink_sb->index, 785 pool_index, &pool_info); 786 if (err) 787 return err; 788 789 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 790 if (!hdr) 791 return -EMSGSIZE; 792 793 if (devlink_nl_put_handle(msg, devlink)) 794 goto nla_put_failure; 795 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) 796 goto nla_put_failure; 797 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index)) 798 goto nla_put_failure; 799 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type)) 800 goto nla_put_failure; 801 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size)) 802 goto nla_put_failure; 803 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE, 804 pool_info.threshold_type)) 805 goto nla_put_failure; 806 807 genlmsg_end(msg, hdr); 808 return 0; 809 810nla_put_failure: 811 genlmsg_cancel(msg, hdr); 812 return -EMSGSIZE; 813} 814 815static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb, 816 struct genl_info *info) 817{ 818 struct devlink *devlink = info->user_ptr[0]; 819 struct devlink_sb *devlink_sb = info->user_ptr[1]; 820 struct sk_buff *msg; 821 u16 pool_index; 822 int err; 823 824 err = devlink_sb_pool_index_get_from_info(devlink_sb, info, 825 &pool_index); 826 if (err) 827 return err; 828 829 if (!devlink->ops || !devlink->ops->sb_pool_get) 830 return -EOPNOTSUPP; 831 832 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 833 if (!msg) 834 return -ENOMEM; 835 836 err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index, 837 DEVLINK_CMD_SB_POOL_NEW, 838 info->snd_portid, info->snd_seq, 0); 839 if (err) { 840 nlmsg_free(msg); 841 return err; 842 } 843 844 return genlmsg_reply(msg, info); 845} 846 847static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx, 848 struct devlink *devlink, 849 struct devlink_sb *devlink_sb, 850 u32 portid, u32 seq) 851{ 852 u16 pool_count = devlink_sb_pool_count(devlink_sb); 853 u16 pool_index; 854 int err; 855 856 for (pool_index = 0; pool_index < pool_count; pool_index++) { 857 if (*p_idx < start) { 858 (*p_idx)++; 859 continue; 860 } 861 err = devlink_nl_sb_pool_fill(msg, devlink, 862 devlink_sb, 863 pool_index, 864 DEVLINK_CMD_SB_POOL_NEW, 865 portid, seq, NLM_F_MULTI); 866 if (err) 867 return err; 868 (*p_idx)++; 869 } 870 return 0; 871} 872 873static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg, 874 struct netlink_callback *cb) 875{ 876 struct devlink *devlink; 877 struct devlink_sb *devlink_sb; 878 int start = cb->args[0]; 879 int idx = 0; 880 int err; 881 882 mutex_lock(&devlink_mutex); 883 list_for_each_entry(devlink, &devlink_list, list) { 884 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) || 885 !devlink->ops || !devlink->ops->sb_pool_get) 886 continue; 887 list_for_each_entry(devlink_sb, &devlink->sb_list, list) { 888 err = __sb_pool_get_dumpit(msg, start, &idx, devlink, 889 devlink_sb, 890 NETLINK_CB(cb->skb).portid, 891 cb->nlh->nlmsg_seq); 892 if (err && err != -EOPNOTSUPP) 893 goto out; 894 } 895 } 896out: 897 mutex_unlock(&devlink_mutex); 898 899 cb->args[0] = idx; 900 return msg->len; 901} 902 903static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index, 904 u16 pool_index, u32 size, 905 enum devlink_sb_threshold_type threshold_type) 906 907{ 908 const struct devlink_ops *ops = devlink->ops; 909 910 if (ops && ops->sb_pool_set) 911 return ops->sb_pool_set(devlink, sb_index, pool_index, 912 size, threshold_type); 913 return -EOPNOTSUPP; 914} 915 916static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb, 917 struct genl_info *info) 918{ 919 struct devlink *devlink = info->user_ptr[0]; 920 struct devlink_sb *devlink_sb = info->user_ptr[1]; 921 enum devlink_sb_threshold_type threshold_type; 922 u16 pool_index; 923 u32 size; 924 int err; 925 926 err = devlink_sb_pool_index_get_from_info(devlink_sb, info, 927 &pool_index); 928 if (err) 929 return err; 930 931 err = devlink_sb_th_type_get_from_info(info, &threshold_type); 932 if (err) 933 return err; 934 935 if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]) 936 return -EINVAL; 937 938 size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]); 939 return devlink_sb_pool_set(devlink, devlink_sb->index, 940 pool_index, size, threshold_type); 941} 942 943static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg, 944 struct devlink *devlink, 945 struct devlink_port *devlink_port, 946 struct devlink_sb *devlink_sb, 947 u16 pool_index, 948 enum devlink_command cmd, 949 u32 portid, u32 seq, int flags) 950{ 951 const struct devlink_ops *ops = devlink->ops; 952 u32 threshold; 953 void *hdr; 954 int err; 955 956 err = ops->sb_port_pool_get(devlink_port, devlink_sb->index, 957 pool_index, &threshold); 958 if (err) 959 return err; 960 961 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 962 if (!hdr) 963 return -EMSGSIZE; 964 965 if (devlink_nl_put_handle(msg, devlink)) 966 goto nla_put_failure; 967 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) 968 goto nla_put_failure; 969 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) 970 goto nla_put_failure; 971 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index)) 972 goto nla_put_failure; 973 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold)) 974 goto nla_put_failure; 975 976 if (ops->sb_occ_port_pool_get) { 977 u32 cur; 978 u32 max; 979 980 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index, 981 pool_index, &cur, &max); 982 if (err && err != -EOPNOTSUPP) 983 return err; 984 if (!err) { 985 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur)) 986 goto nla_put_failure; 987 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max)) 988 goto nla_put_failure; 989 } 990 } 991 992 genlmsg_end(msg, hdr); 993 return 0; 994 995nla_put_failure: 996 genlmsg_cancel(msg, hdr); 997 return -EMSGSIZE; 998} 999 1000static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb, 1001 struct genl_info *info) 1002{ 1003 struct devlink_port *devlink_port = info->user_ptr[0]; 1004 struct devlink *devlink = devlink_port->devlink; 1005 struct devlink_sb *devlink_sb = info->user_ptr[1]; 1006 struct sk_buff *msg; 1007 u16 pool_index; 1008 int err; 1009 1010 err = devlink_sb_pool_index_get_from_info(devlink_sb, info, 1011 &pool_index); 1012 if (err) 1013 return err; 1014 1015 if (!devlink->ops || !devlink->ops->sb_port_pool_get) 1016 return -EOPNOTSUPP; 1017 1018 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1019 if (!msg) 1020 return -ENOMEM; 1021 1022 err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port, 1023 devlink_sb, pool_index, 1024 DEVLINK_CMD_SB_PORT_POOL_NEW, 1025 info->snd_portid, info->snd_seq, 0); 1026 if (err) { 1027 nlmsg_free(msg); 1028 return err; 1029 } 1030 1031 return genlmsg_reply(msg, info); 1032} 1033 1034static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx, 1035 struct devlink *devlink, 1036 struct devlink_sb *devlink_sb, 1037 u32 portid, u32 seq) 1038{ 1039 struct devlink_port *devlink_port; 1040 u16 pool_count = devlink_sb_pool_count(devlink_sb); 1041 u16 pool_index; 1042 int err; 1043 1044 list_for_each_entry(devlink_port, &devlink->port_list, list) { 1045 for (pool_index = 0; pool_index < pool_count; pool_index++) { 1046 if (*p_idx < start) { 1047 (*p_idx)++; 1048 continue; 1049 } 1050 err = devlink_nl_sb_port_pool_fill(msg, devlink, 1051 devlink_port, 1052 devlink_sb, 1053 pool_index, 1054 DEVLINK_CMD_SB_PORT_POOL_NEW, 1055 portid, seq, 1056 NLM_F_MULTI); 1057 if (err) 1058 return err; 1059 (*p_idx)++; 1060 } 1061 } 1062 return 0; 1063} 1064 1065static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg, 1066 struct netlink_callback *cb) 1067{ 1068 struct devlink *devlink; 1069 struct devlink_sb *devlink_sb; 1070 int start = cb->args[0]; 1071 int idx = 0; 1072 int err; 1073 1074 mutex_lock(&devlink_mutex); 1075 mutex_lock(&devlink_port_mutex); 1076 list_for_each_entry(devlink, &devlink_list, list) { 1077 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) || 1078 !devlink->ops || !devlink->ops->sb_port_pool_get) 1079 continue; 1080 list_for_each_entry(devlink_sb, &devlink->sb_list, list) { 1081 err = __sb_port_pool_get_dumpit(msg, start, &idx, 1082 devlink, devlink_sb, 1083 NETLINK_CB(cb->skb).portid, 1084 cb->nlh->nlmsg_seq); 1085 if (err && err != -EOPNOTSUPP) 1086 goto out; 1087 } 1088 } 1089out: 1090 mutex_unlock(&devlink_port_mutex); 1091 mutex_unlock(&devlink_mutex); 1092 1093 cb->args[0] = idx; 1094 return msg->len; 1095} 1096 1097static int devlink_sb_port_pool_set(struct devlink_port *devlink_port, 1098 unsigned int sb_index, u16 pool_index, 1099 u32 threshold) 1100 1101{ 1102 const struct devlink_ops *ops = devlink_port->devlink->ops; 1103 1104 if (ops && ops->sb_port_pool_set) 1105 return ops->sb_port_pool_set(devlink_port, sb_index, 1106 pool_index, threshold); 1107 return -EOPNOTSUPP; 1108} 1109 1110static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb, 1111 struct genl_info *info) 1112{ 1113 struct devlink_port *devlink_port = info->user_ptr[0]; 1114 struct devlink_sb *devlink_sb = info->user_ptr[1]; 1115 u16 pool_index; 1116 u32 threshold; 1117 int err; 1118 1119 err = devlink_sb_pool_index_get_from_info(devlink_sb, info, 1120 &pool_index); 1121 if (err) 1122 return err; 1123 1124 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD]) 1125 return -EINVAL; 1126 1127 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]); 1128 return devlink_sb_port_pool_set(devlink_port, devlink_sb->index, 1129 pool_index, threshold); 1130} 1131 1132static int 1133devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink, 1134 struct devlink_port *devlink_port, 1135 struct devlink_sb *devlink_sb, u16 tc_index, 1136 enum devlink_sb_pool_type pool_type, 1137 enum devlink_command cmd, 1138 u32 portid, u32 seq, int flags) 1139{ 1140 const struct devlink_ops *ops = devlink->ops; 1141 u16 pool_index; 1142 u32 threshold; 1143 void *hdr; 1144 int err; 1145 1146 err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index, 1147 tc_index, pool_type, 1148 &pool_index, &threshold); 1149 if (err) 1150 return err; 1151 1152 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 1153 if (!hdr) 1154 return -EMSGSIZE; 1155 1156 if (devlink_nl_put_handle(msg, devlink)) 1157 goto nla_put_failure; 1158 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) 1159 goto nla_put_failure; 1160 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) 1161 goto nla_put_failure; 1162 if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index)) 1163 goto nla_put_failure; 1164 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type)) 1165 goto nla_put_failure; 1166 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index)) 1167 goto nla_put_failure; 1168 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold)) 1169 goto nla_put_failure; 1170 1171 if (ops->sb_occ_tc_port_bind_get) { 1172 u32 cur; 1173 u32 max; 1174 1175 err = ops->sb_occ_tc_port_bind_get(devlink_port, 1176 devlink_sb->index, 1177 tc_index, pool_type, 1178 &cur, &max); 1179 if (err && err != -EOPNOTSUPP) 1180 return err; 1181 if (!err) { 1182 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur)) 1183 goto nla_put_failure; 1184 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max)) 1185 goto nla_put_failure; 1186 } 1187 } 1188 1189 genlmsg_end(msg, hdr); 1190 return 0; 1191 1192nla_put_failure: 1193 genlmsg_cancel(msg, hdr); 1194 return -EMSGSIZE; 1195} 1196 1197static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb, 1198 struct genl_info *info) 1199{ 1200 struct devlink_port *devlink_port = info->user_ptr[0]; 1201 struct devlink *devlink = devlink_port->devlink; 1202 struct devlink_sb *devlink_sb = info->user_ptr[1]; 1203 struct sk_buff *msg; 1204 enum devlink_sb_pool_type pool_type; 1205 u16 tc_index; 1206 int err; 1207 1208 err = devlink_sb_pool_type_get_from_info(info, &pool_type); 1209 if (err) 1210 return err; 1211 1212 err = devlink_sb_tc_index_get_from_info(devlink_sb, info, 1213 pool_type, &tc_index); 1214 if (err) 1215 return err; 1216 1217 if (!devlink->ops || !devlink->ops->sb_tc_pool_bind_get) 1218 return -EOPNOTSUPP; 1219 1220 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1221 if (!msg) 1222 return -ENOMEM; 1223 1224 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port, 1225 devlink_sb, tc_index, pool_type, 1226 DEVLINK_CMD_SB_TC_POOL_BIND_NEW, 1227 info->snd_portid, 1228 info->snd_seq, 0); 1229 if (err) { 1230 nlmsg_free(msg); 1231 return err; 1232 } 1233 1234 return genlmsg_reply(msg, info); 1235} 1236 1237static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg, 1238 int start, int *p_idx, 1239 struct devlink *devlink, 1240 struct devlink_sb *devlink_sb, 1241 u32 portid, u32 seq) 1242{ 1243 struct devlink_port *devlink_port; 1244 u16 tc_index; 1245 int err; 1246 1247 list_for_each_entry(devlink_port, &devlink->port_list, list) { 1248 for (tc_index = 0; 1249 tc_index < devlink_sb->ingress_tc_count; tc_index++) { 1250 if (*p_idx < start) { 1251 (*p_idx)++; 1252 continue; 1253 } 1254 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, 1255 devlink_port, 1256 devlink_sb, 1257 tc_index, 1258 DEVLINK_SB_POOL_TYPE_INGRESS, 1259 DEVLINK_CMD_SB_TC_POOL_BIND_NEW, 1260 portid, seq, 1261 NLM_F_MULTI); 1262 if (err) 1263 return err; 1264 (*p_idx)++; 1265 } 1266 for (tc_index = 0; 1267 tc_index < devlink_sb->egress_tc_count; tc_index++) { 1268 if (*p_idx < start) { 1269 (*p_idx)++; 1270 continue; 1271 } 1272 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, 1273 devlink_port, 1274 devlink_sb, 1275 tc_index, 1276 DEVLINK_SB_POOL_TYPE_EGRESS, 1277 DEVLINK_CMD_SB_TC_POOL_BIND_NEW, 1278 portid, seq, 1279 NLM_F_MULTI); 1280 if (err) 1281 return err; 1282 (*p_idx)++; 1283 } 1284 } 1285 return 0; 1286} 1287 1288static int 1289devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg, 1290 struct netlink_callback *cb) 1291{ 1292 struct devlink *devlink; 1293 struct devlink_sb *devlink_sb; 1294 int start = cb->args[0]; 1295 int idx = 0; 1296 int err; 1297 1298 mutex_lock(&devlink_mutex); 1299 mutex_lock(&devlink_port_mutex); 1300 list_for_each_entry(devlink, &devlink_list, list) { 1301 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) || 1302 !devlink->ops || !devlink->ops->sb_tc_pool_bind_get) 1303 continue; 1304 list_for_each_entry(devlink_sb, &devlink->sb_list, list) { 1305 err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx, 1306 devlink, 1307 devlink_sb, 1308 NETLINK_CB(cb->skb).portid, 1309 cb->nlh->nlmsg_seq); 1310 if (err && err != -EOPNOTSUPP) 1311 goto out; 1312 } 1313 } 1314out: 1315 mutex_unlock(&devlink_port_mutex); 1316 mutex_unlock(&devlink_mutex); 1317 1318 cb->args[0] = idx; 1319 return msg->len; 1320} 1321 1322static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port, 1323 unsigned int sb_index, u16 tc_index, 1324 enum devlink_sb_pool_type pool_type, 1325 u16 pool_index, u32 threshold) 1326 1327{ 1328 const struct devlink_ops *ops = devlink_port->devlink->ops; 1329 1330 if (ops && ops->sb_tc_pool_bind_set) 1331 return ops->sb_tc_pool_bind_set(devlink_port, sb_index, 1332 tc_index, pool_type, 1333 pool_index, threshold); 1334 return -EOPNOTSUPP; 1335} 1336 1337static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb, 1338 struct genl_info *info) 1339{ 1340 struct devlink_port *devlink_port = info->user_ptr[0]; 1341 struct devlink_sb *devlink_sb = info->user_ptr[1]; 1342 enum devlink_sb_pool_type pool_type; 1343 u16 tc_index; 1344 u16 pool_index; 1345 u32 threshold; 1346 int err; 1347 1348 err = devlink_sb_pool_type_get_from_info(info, &pool_type); 1349 if (err) 1350 return err; 1351 1352 err = devlink_sb_tc_index_get_from_info(devlink_sb, info, 1353 pool_type, &tc_index); 1354 if (err) 1355 return err; 1356 1357 err = devlink_sb_pool_index_get_from_info(devlink_sb, info, 1358 &pool_index); 1359 if (err) 1360 return err; 1361 1362 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD]) 1363 return -EINVAL; 1364 1365 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]); 1366 return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index, 1367 tc_index, pool_type, 1368 pool_index, threshold); 1369} 1370 1371static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb, 1372 struct genl_info *info) 1373{ 1374 struct devlink *devlink = info->user_ptr[0]; 1375 struct devlink_sb *devlink_sb = info->user_ptr[1]; 1376 const struct devlink_ops *ops = devlink->ops; 1377 1378 if (ops && ops->sb_occ_snapshot) 1379 return ops->sb_occ_snapshot(devlink, devlink_sb->index); 1380 return -EOPNOTSUPP; 1381} 1382 1383static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb, 1384 struct genl_info *info) 1385{ 1386 struct devlink *devlink = info->user_ptr[0]; 1387 struct devlink_sb *devlink_sb = info->user_ptr[1]; 1388 const struct devlink_ops *ops = devlink->ops; 1389 1390 if (ops && ops->sb_occ_max_clear) 1391 return ops->sb_occ_max_clear(devlink, devlink_sb->index); 1392 return -EOPNOTSUPP; 1393} 1394 1395static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink, 1396 enum devlink_command cmd, u32 portid, 1397 u32 seq, int flags) 1398{ 1399 const struct devlink_ops *ops = devlink->ops; 1400 u8 inline_mode, encap_mode; 1401 void *hdr; 1402 int err = 0; 1403 u16 mode; 1404 1405 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 1406 if (!hdr) 1407 return -EMSGSIZE; 1408 1409 err = devlink_nl_put_handle(msg, devlink); 1410 if (err) 1411 goto nla_put_failure; 1412 1413 if (ops->eswitch_mode_get) { 1414 err = ops->eswitch_mode_get(devlink, &mode); 1415 if (err) 1416 goto nla_put_failure; 1417 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode); 1418 if (err) 1419 goto nla_put_failure; 1420 } 1421 1422 if (ops->eswitch_inline_mode_get) { 1423 err = ops->eswitch_inline_mode_get(devlink, &inline_mode); 1424 if (err) 1425 goto nla_put_failure; 1426 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE, 1427 inline_mode); 1428 if (err) 1429 goto nla_put_failure; 1430 } 1431 1432 if (ops->eswitch_encap_mode_get) { 1433 err = ops->eswitch_encap_mode_get(devlink, &encap_mode); 1434 if (err) 1435 goto nla_put_failure; 1436 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode); 1437 if (err) 1438 goto nla_put_failure; 1439 } 1440 1441 genlmsg_end(msg, hdr); 1442 return 0; 1443 1444nla_put_failure: 1445 genlmsg_cancel(msg, hdr); 1446 return err; 1447} 1448 1449static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb, 1450 struct genl_info *info) 1451{ 1452 struct devlink *devlink = info->user_ptr[0]; 1453 const struct devlink_ops *ops = devlink->ops; 1454 struct sk_buff *msg; 1455 int err; 1456 1457 if (!ops) 1458 return -EOPNOTSUPP; 1459 1460 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1461 if (!msg) 1462 return -ENOMEM; 1463 1464 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET, 1465 info->snd_portid, info->snd_seq, 0); 1466 1467 if (err) { 1468 nlmsg_free(msg); 1469 return err; 1470 } 1471 1472 return genlmsg_reply(msg, info); 1473} 1474 1475static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb, 1476 struct genl_info *info) 1477{ 1478 struct devlink *devlink = info->user_ptr[0]; 1479 const struct devlink_ops *ops = devlink->ops; 1480 u8 inline_mode, encap_mode; 1481 int err = 0; 1482 u16 mode; 1483 1484 if (!ops) 1485 return -EOPNOTSUPP; 1486 1487 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) { 1488 if (!ops->eswitch_mode_set) 1489 return -EOPNOTSUPP; 1490 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]); 1491 err = ops->eswitch_mode_set(devlink, mode); 1492 if (err) 1493 return err; 1494 } 1495 1496 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) { 1497 if (!ops->eswitch_inline_mode_set) 1498 return -EOPNOTSUPP; 1499 inline_mode = nla_get_u8( 1500 info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]); 1501 err = ops->eswitch_inline_mode_set(devlink, inline_mode); 1502 if (err) 1503 return err; 1504 } 1505 1506 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) { 1507 if (!ops->eswitch_encap_mode_set) 1508 return -EOPNOTSUPP; 1509 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]); 1510 err = ops->eswitch_encap_mode_set(devlink, encap_mode); 1511 if (err) 1512 return err; 1513 } 1514 1515 return 0; 1516} 1517 1518int devlink_dpipe_match_put(struct sk_buff *skb, 1519 struct devlink_dpipe_match *match) 1520{ 1521 struct devlink_dpipe_header *header = match->header; 1522 struct devlink_dpipe_field *field = &header->fields[match->field_id]; 1523 struct nlattr *match_attr; 1524 1525 match_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_MATCH); 1526 if (!match_attr) 1527 return -EMSGSIZE; 1528 1529 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) || 1530 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) || 1531 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || 1532 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || 1533 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) 1534 goto nla_put_failure; 1535 1536 nla_nest_end(skb, match_attr); 1537 return 0; 1538 1539nla_put_failure: 1540 nla_nest_cancel(skb, match_attr); 1541 return -EMSGSIZE; 1542} 1543EXPORT_SYMBOL_GPL(devlink_dpipe_match_put); 1544 1545static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table, 1546 struct sk_buff *skb) 1547{ 1548 struct nlattr *matches_attr; 1549 1550 matches_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE_MATCHES); 1551 if (!matches_attr) 1552 return -EMSGSIZE; 1553 1554 if (table->table_ops->matches_dump(table->priv, skb)) 1555 goto nla_put_failure; 1556 1557 nla_nest_end(skb, matches_attr); 1558 return 0; 1559 1560nla_put_failure: 1561 nla_nest_cancel(skb, matches_attr); 1562 return -EMSGSIZE; 1563} 1564 1565int devlink_dpipe_action_put(struct sk_buff *skb, 1566 struct devlink_dpipe_action *action) 1567{ 1568 struct devlink_dpipe_header *header = action->header; 1569 struct devlink_dpipe_field *field = &header->fields[action->field_id]; 1570 struct nlattr *action_attr; 1571 1572 action_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_ACTION); 1573 if (!action_attr) 1574 return -EMSGSIZE; 1575 1576 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) || 1577 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) || 1578 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || 1579 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || 1580 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) 1581 goto nla_put_failure; 1582 1583 nla_nest_end(skb, action_attr); 1584 return 0; 1585 1586nla_put_failure: 1587 nla_nest_cancel(skb, action_attr); 1588 return -EMSGSIZE; 1589} 1590EXPORT_SYMBOL_GPL(devlink_dpipe_action_put); 1591 1592static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table, 1593 struct sk_buff *skb) 1594{ 1595 struct nlattr *actions_attr; 1596 1597 actions_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE_ACTIONS); 1598 if (!actions_attr) 1599 return -EMSGSIZE; 1600 1601 if (table->table_ops->actions_dump(table->priv, skb)) 1602 goto nla_put_failure; 1603 1604 nla_nest_end(skb, actions_attr); 1605 return 0; 1606 1607nla_put_failure: 1608 nla_nest_cancel(skb, actions_attr); 1609 return -EMSGSIZE; 1610} 1611 1612static int devlink_dpipe_table_put(struct sk_buff *skb, 1613 struct devlink_dpipe_table *table) 1614{ 1615 struct nlattr *table_attr; 1616 1617 table_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE); 1618 if (!table_attr) 1619 return -EMSGSIZE; 1620 1621 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) || 1622 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table->size, 1623 DEVLINK_ATTR_PAD)) 1624 goto nla_put_failure; 1625 if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED, 1626 table->counters_enabled)) 1627 goto nla_put_failure; 1628 1629 if (devlink_dpipe_matches_put(table, skb)) 1630 goto nla_put_failure; 1631 1632 if (devlink_dpipe_actions_put(table, skb)) 1633 goto nla_put_failure; 1634 1635 nla_nest_end(skb, table_attr); 1636 return 0; 1637 1638nla_put_failure: 1639 nla_nest_cancel(skb, table_attr); 1640 return -EMSGSIZE; 1641} 1642 1643static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb, 1644 struct genl_info *info) 1645{ 1646 int err; 1647 1648 if (*pskb) { 1649 err = genlmsg_reply(*pskb, info); 1650 if (err) 1651 return err; 1652 } 1653 *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 1654 if (!*pskb) 1655 return -ENOMEM; 1656 return 0; 1657} 1658 1659static int devlink_dpipe_tables_fill(struct genl_info *info, 1660 enum devlink_command cmd, int flags, 1661 struct list_head *dpipe_tables, 1662 const char *table_name) 1663{ 1664 struct devlink *devlink = info->user_ptr[0]; 1665 struct devlink_dpipe_table *table; 1666 struct nlattr *tables_attr; 1667 struct sk_buff *skb = NULL; 1668 struct nlmsghdr *nlh; 1669 bool incomplete; 1670 void *hdr; 1671 int i; 1672 int err; 1673 1674 table = list_first_entry(dpipe_tables, 1675 struct devlink_dpipe_table, list); 1676start_again: 1677 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 1678 if (err) 1679 return err; 1680 1681 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, 1682 &devlink_nl_family, NLM_F_MULTI, cmd); 1683 if (!hdr) 1684 return -EMSGSIZE; 1685 1686 if (devlink_nl_put_handle(skb, devlink)) 1687 goto nla_put_failure; 1688 tables_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLES); 1689 if (!tables_attr) 1690 goto nla_put_failure; 1691 1692 i = 0; 1693 incomplete = false; 1694 list_for_each_entry_from(table, dpipe_tables, list) { 1695 if (!table_name) { 1696 err = devlink_dpipe_table_put(skb, table); 1697 if (err) { 1698 if (!i) 1699 goto err_table_put; 1700 incomplete = true; 1701 break; 1702 } 1703 } else { 1704 if (!strcmp(table->name, table_name)) { 1705 err = devlink_dpipe_table_put(skb, table); 1706 if (err) 1707 break; 1708 } 1709 } 1710 i++; 1711 } 1712 1713 nla_nest_end(skb, tables_attr); 1714 genlmsg_end(skb, hdr); 1715 if (incomplete) 1716 goto start_again; 1717 1718send_done: 1719 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, 1720 NLMSG_DONE, 0, flags | NLM_F_MULTI); 1721 if (!nlh) { 1722 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 1723 if (err) 1724 goto err_skb_send_alloc; 1725 goto send_done; 1726 } 1727 1728 return genlmsg_reply(skb, info); 1729 1730nla_put_failure: 1731 err = -EMSGSIZE; 1732err_table_put: 1733err_skb_send_alloc: 1734 genlmsg_cancel(skb, hdr); 1735 nlmsg_free(skb); 1736 return err; 1737} 1738 1739static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb, 1740 struct genl_info *info) 1741{ 1742 struct devlink *devlink = info->user_ptr[0]; 1743 const char *table_name = NULL; 1744 1745 if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]) 1746 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); 1747 1748 return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0, 1749 &devlink->dpipe_table_list, 1750 table_name); 1751} 1752 1753static int devlink_dpipe_value_put(struct sk_buff *skb, 1754 struct devlink_dpipe_value *value) 1755{ 1756 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE, 1757 value->value_size, value->value)) 1758 return -EMSGSIZE; 1759 if (value->mask) 1760 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK, 1761 value->value_size, value->mask)) 1762 return -EMSGSIZE; 1763 if (value->mapping_valid) 1764 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING, 1765 value->mapping_value)) 1766 return -EMSGSIZE; 1767 return 0; 1768} 1769 1770static int devlink_dpipe_action_value_put(struct sk_buff *skb, 1771 struct devlink_dpipe_value *value) 1772{ 1773 if (!value->action) 1774 return -EINVAL; 1775 if (devlink_dpipe_action_put(skb, value->action)) 1776 return -EMSGSIZE; 1777 if (devlink_dpipe_value_put(skb, value)) 1778 return -EMSGSIZE; 1779 return 0; 1780} 1781 1782static int devlink_dpipe_action_values_put(struct sk_buff *skb, 1783 struct devlink_dpipe_value *values, 1784 unsigned int values_count) 1785{ 1786 struct nlattr *action_attr; 1787 int i; 1788 int err; 1789 1790 for (i = 0; i < values_count; i++) { 1791 action_attr = nla_nest_start(skb, 1792 DEVLINK_ATTR_DPIPE_ACTION_VALUE); 1793 if (!action_attr) 1794 return -EMSGSIZE; 1795 err = devlink_dpipe_action_value_put(skb, &values[i]); 1796 if (err) 1797 goto err_action_value_put; 1798 nla_nest_end(skb, action_attr); 1799 } 1800 return 0; 1801 1802err_action_value_put: 1803 nla_nest_cancel(skb, action_attr); 1804 return err; 1805} 1806 1807static int devlink_dpipe_match_value_put(struct sk_buff *skb, 1808 struct devlink_dpipe_value *value) 1809{ 1810 if (!value->match) 1811 return -EINVAL; 1812 if (devlink_dpipe_match_put(skb, value->match)) 1813 return -EMSGSIZE; 1814 if (devlink_dpipe_value_put(skb, value)) 1815 return -EMSGSIZE; 1816 return 0; 1817} 1818 1819static int devlink_dpipe_match_values_put(struct sk_buff *skb, 1820 struct devlink_dpipe_value *values, 1821 unsigned int values_count) 1822{ 1823 struct nlattr *match_attr; 1824 int i; 1825 int err; 1826 1827 for (i = 0; i < values_count; i++) { 1828 match_attr = nla_nest_start(skb, 1829 DEVLINK_ATTR_DPIPE_MATCH_VALUE); 1830 if (!match_attr) 1831 return -EMSGSIZE; 1832 err = devlink_dpipe_match_value_put(skb, &values[i]); 1833 if (err) 1834 goto err_match_value_put; 1835 nla_nest_end(skb, match_attr); 1836 } 1837 return 0; 1838 1839err_match_value_put: 1840 nla_nest_cancel(skb, match_attr); 1841 return err; 1842} 1843 1844static int devlink_dpipe_entry_put(struct sk_buff *skb, 1845 struct devlink_dpipe_entry *entry) 1846{ 1847 struct nlattr *entry_attr, *matches_attr, *actions_attr; 1848 int err; 1849 1850 entry_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_ENTRY); 1851 if (!entry_attr) 1852 return -EMSGSIZE; 1853 1854 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index, 1855 DEVLINK_ATTR_PAD)) 1856 goto nla_put_failure; 1857 if (entry->counter_valid) 1858 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER, 1859 entry->counter, DEVLINK_ATTR_PAD)) 1860 goto nla_put_failure; 1861 1862 matches_attr = nla_nest_start(skb, 1863 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES); 1864 if (!matches_attr) 1865 goto nla_put_failure; 1866 1867 err = devlink_dpipe_match_values_put(skb, entry->match_values, 1868 entry->match_values_count); 1869 if (err) { 1870 nla_nest_cancel(skb, matches_attr); 1871 goto err_match_values_put; 1872 } 1873 nla_nest_end(skb, matches_attr); 1874 1875 actions_attr = nla_nest_start(skb, 1876 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES); 1877 if (!actions_attr) 1878 goto nla_put_failure; 1879 1880 err = devlink_dpipe_action_values_put(skb, entry->action_values, 1881 entry->action_values_count); 1882 if (err) { 1883 nla_nest_cancel(skb, actions_attr); 1884 goto err_action_values_put; 1885 } 1886 nla_nest_end(skb, actions_attr); 1887 1888 nla_nest_end(skb, entry_attr); 1889 return 0; 1890 1891nla_put_failure: 1892 err = -EMSGSIZE; 1893err_match_values_put: 1894err_action_values_put: 1895 nla_nest_cancel(skb, entry_attr); 1896 return err; 1897} 1898 1899static struct devlink_dpipe_table * 1900devlink_dpipe_table_find(struct list_head *dpipe_tables, 1901 const char *table_name) 1902{ 1903 struct devlink_dpipe_table *table; 1904 1905 list_for_each_entry_rcu(table, dpipe_tables, list) { 1906 if (!strcmp(table->name, table_name)) 1907 return table; 1908 } 1909 return NULL; 1910} 1911 1912int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx) 1913{ 1914 struct devlink *devlink; 1915 int err; 1916 1917 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb, 1918 dump_ctx->info); 1919 if (err) 1920 return err; 1921 1922 dump_ctx->hdr = genlmsg_put(dump_ctx->skb, 1923 dump_ctx->info->snd_portid, 1924 dump_ctx->info->snd_seq, 1925 &devlink_nl_family, NLM_F_MULTI, 1926 dump_ctx->cmd); 1927 if (!dump_ctx->hdr) 1928 goto nla_put_failure; 1929 1930 devlink = dump_ctx->info->user_ptr[0]; 1931 if (devlink_nl_put_handle(dump_ctx->skb, devlink)) 1932 goto nla_put_failure; 1933 dump_ctx->nest = nla_nest_start(dump_ctx->skb, 1934 DEVLINK_ATTR_DPIPE_ENTRIES); 1935 if (!dump_ctx->nest) 1936 goto nla_put_failure; 1937 return 0; 1938 1939nla_put_failure: 1940 genlmsg_cancel(dump_ctx->skb, dump_ctx->hdr); 1941 nlmsg_free(dump_ctx->skb); 1942 return -EMSGSIZE; 1943} 1944EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare); 1945 1946int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx, 1947 struct devlink_dpipe_entry *entry) 1948{ 1949 return devlink_dpipe_entry_put(dump_ctx->skb, entry); 1950} 1951EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append); 1952 1953int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx) 1954{ 1955 nla_nest_end(dump_ctx->skb, dump_ctx->nest); 1956 genlmsg_end(dump_ctx->skb, dump_ctx->hdr); 1957 return 0; 1958} 1959EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close); 1960 1961static int devlink_dpipe_entries_fill(struct genl_info *info, 1962 enum devlink_command cmd, int flags, 1963 struct devlink_dpipe_table *table) 1964{ 1965 struct devlink_dpipe_dump_ctx dump_ctx; 1966 struct nlmsghdr *nlh; 1967 int err; 1968 1969 dump_ctx.skb = NULL; 1970 dump_ctx.cmd = cmd; 1971 dump_ctx.info = info; 1972 1973 err = table->table_ops->entries_dump(table->priv, 1974 table->counters_enabled, 1975 &dump_ctx); 1976 if (err) 1977 goto err_entries_dump; 1978 1979send_done: 1980 nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq, 1981 NLMSG_DONE, 0, flags | NLM_F_MULTI); 1982 if (!nlh) { 1983 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info); 1984 if (err) 1985 goto err_skb_send_alloc; 1986 goto send_done; 1987 } 1988 return genlmsg_reply(dump_ctx.skb, info); 1989 1990err_entries_dump: 1991err_skb_send_alloc: 1992 genlmsg_cancel(dump_ctx.skb, dump_ctx.hdr); 1993 nlmsg_free(dump_ctx.skb); 1994 return err; 1995} 1996 1997static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb, 1998 struct genl_info *info) 1999{ 2000 struct devlink *devlink = info->user_ptr[0]; 2001 struct devlink_dpipe_table *table; 2002 const char *table_name; 2003 2004 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]) 2005 return -EINVAL; 2006 2007 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); 2008 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 2009 table_name); 2010 if (!table) 2011 return -EINVAL; 2012 2013 if (!table->table_ops->entries_dump) 2014 return -EINVAL; 2015 2016 return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET, 2017 0, table); 2018} 2019 2020static int devlink_dpipe_fields_put(struct sk_buff *skb, 2021 const struct devlink_dpipe_header *header) 2022{ 2023 struct devlink_dpipe_field *field; 2024 struct nlattr *field_attr; 2025 int i; 2026 2027 for (i = 0; i < header->fields_count; i++) { 2028 field = &header->fields[i]; 2029 field_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_FIELD); 2030 if (!field_attr) 2031 return -EMSGSIZE; 2032 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) || 2033 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || 2034 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) || 2035 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type)) 2036 goto nla_put_failure; 2037 nla_nest_end(skb, field_attr); 2038 } 2039 return 0; 2040 2041nla_put_failure: 2042 nla_nest_cancel(skb, field_attr); 2043 return -EMSGSIZE; 2044} 2045 2046static int devlink_dpipe_header_put(struct sk_buff *skb, 2047 struct devlink_dpipe_header *header) 2048{ 2049 struct nlattr *fields_attr, *header_attr; 2050 int err; 2051 2052 header_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER); 2053 if (!header_attr) 2054 return -EMSGSIZE; 2055 2056 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) || 2057 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || 2058 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) 2059 goto nla_put_failure; 2060 2061 fields_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER_FIELDS); 2062 if (!fields_attr) 2063 goto nla_put_failure; 2064 2065 err = devlink_dpipe_fields_put(skb, header); 2066 if (err) { 2067 nla_nest_cancel(skb, fields_attr); 2068 goto nla_put_failure; 2069 } 2070 nla_nest_end(skb, fields_attr); 2071 nla_nest_end(skb, header_attr); 2072 return 0; 2073 2074nla_put_failure: 2075 err = -EMSGSIZE; 2076 nla_nest_cancel(skb, header_attr); 2077 return err; 2078} 2079 2080static int devlink_dpipe_headers_fill(struct genl_info *info, 2081 enum devlink_command cmd, int flags, 2082 struct devlink_dpipe_headers * 2083 dpipe_headers) 2084{ 2085 struct devlink *devlink = info->user_ptr[0]; 2086 struct nlattr *headers_attr; 2087 struct sk_buff *skb = NULL; 2088 struct nlmsghdr *nlh; 2089 void *hdr; 2090 int i, j; 2091 int err; 2092 2093 i = 0; 2094start_again: 2095 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 2096 if (err) 2097 return err; 2098 2099 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, 2100 &devlink_nl_family, NLM_F_MULTI, cmd); 2101 if (!hdr) 2102 return -EMSGSIZE; 2103 2104 if (devlink_nl_put_handle(skb, devlink)) 2105 goto nla_put_failure; 2106 headers_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADERS); 2107 if (!headers_attr) 2108 goto nla_put_failure; 2109 2110 j = 0; 2111 for (; i < dpipe_headers->headers_count; i++) { 2112 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]); 2113 if (err) { 2114 if (!j) 2115 goto err_table_put; 2116 break; 2117 } 2118 j++; 2119 } 2120 nla_nest_end(skb, headers_attr); 2121 genlmsg_end(skb, hdr); 2122 if (i != dpipe_headers->headers_count) 2123 goto start_again; 2124 2125send_done: 2126 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, 2127 NLMSG_DONE, 0, flags | NLM_F_MULTI); 2128 if (!nlh) { 2129 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 2130 if (err) 2131 goto err_skb_send_alloc; 2132 goto send_done; 2133 } 2134 return genlmsg_reply(skb, info); 2135 2136nla_put_failure: 2137 err = -EMSGSIZE; 2138err_table_put: 2139err_skb_send_alloc: 2140 genlmsg_cancel(skb, hdr); 2141 nlmsg_free(skb); 2142 return err; 2143} 2144 2145static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb, 2146 struct genl_info *info) 2147{ 2148 struct devlink *devlink = info->user_ptr[0]; 2149 2150 if (!devlink->dpipe_headers) 2151 return -EOPNOTSUPP; 2152 return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET, 2153 0, devlink->dpipe_headers); 2154} 2155 2156static int devlink_dpipe_table_counters_set(struct devlink *devlink, 2157 const char *table_name, 2158 bool enable) 2159{ 2160 struct devlink_dpipe_table *table; 2161 2162 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 2163 table_name); 2164 if (!table) 2165 return -EINVAL; 2166 2167 if (table->counter_control_extern) 2168 return -EOPNOTSUPP; 2169 2170 if (!(table->counters_enabled ^ enable)) 2171 return 0; 2172 2173 table->counters_enabled = enable; 2174 if (table->table_ops->counters_set_update) 2175 table->table_ops->counters_set_update(table->priv, enable); 2176 return 0; 2177} 2178 2179static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb, 2180 struct genl_info *info) 2181{ 2182 struct devlink *devlink = info->user_ptr[0]; 2183 const char *table_name; 2184 bool counters_enable; 2185 2186 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] || 2187 !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]) 2188 return -EINVAL; 2189 2190 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); 2191 counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]); 2192 2193 return devlink_dpipe_table_counters_set(devlink, table_name, 2194 counters_enable); 2195} 2196 2197static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { 2198 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, 2199 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING }, 2200 [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 }, 2201 [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 }, 2202 [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 }, 2203 [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 }, 2204 [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 }, 2205 [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 }, 2206 [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 }, 2207 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 }, 2208 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 }, 2209 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 }, 2210 [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 }, 2211 [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 }, 2212 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 }, 2213 [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING }, 2214 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 }, 2215}; 2216 2217static const struct genl_ops devlink_nl_ops[] = { 2218 { 2219 .cmd = DEVLINK_CMD_GET, 2220 .doit = devlink_nl_cmd_get_doit, 2221 .dumpit = devlink_nl_cmd_get_dumpit, 2222 .policy = devlink_nl_policy, 2223 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2224 /* can be retrieved by unprivileged users */ 2225 }, 2226 { 2227 .cmd = DEVLINK_CMD_PORT_GET, 2228 .doit = devlink_nl_cmd_port_get_doit, 2229 .dumpit = devlink_nl_cmd_port_get_dumpit, 2230 .policy = devlink_nl_policy, 2231 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 2232 /* can be retrieved by unprivileged users */ 2233 }, 2234 { 2235 .cmd = DEVLINK_CMD_PORT_SET, 2236 .doit = devlink_nl_cmd_port_set_doit, 2237 .policy = devlink_nl_policy, 2238 .flags = GENL_ADMIN_PERM, 2239 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 2240 }, 2241 { 2242 .cmd = DEVLINK_CMD_PORT_SPLIT, 2243 .doit = devlink_nl_cmd_port_split_doit, 2244 .policy = devlink_nl_policy, 2245 .flags = GENL_ADMIN_PERM, 2246 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2247 }, 2248 { 2249 .cmd = DEVLINK_CMD_PORT_UNSPLIT, 2250 .doit = devlink_nl_cmd_port_unsplit_doit, 2251 .policy = devlink_nl_policy, 2252 .flags = GENL_ADMIN_PERM, 2253 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2254 }, 2255 { 2256 .cmd = DEVLINK_CMD_SB_GET, 2257 .doit = devlink_nl_cmd_sb_get_doit, 2258 .dumpit = devlink_nl_cmd_sb_get_dumpit, 2259 .policy = devlink_nl_policy, 2260 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | 2261 DEVLINK_NL_FLAG_NEED_SB, 2262 /* can be retrieved by unprivileged users */ 2263 }, 2264 { 2265 .cmd = DEVLINK_CMD_SB_POOL_GET, 2266 .doit = devlink_nl_cmd_sb_pool_get_doit, 2267 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit, 2268 .policy = devlink_nl_policy, 2269 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | 2270 DEVLINK_NL_FLAG_NEED_SB, 2271 /* can be retrieved by unprivileged users */ 2272 }, 2273 { 2274 .cmd = DEVLINK_CMD_SB_POOL_SET, 2275 .doit = devlink_nl_cmd_sb_pool_set_doit, 2276 .policy = devlink_nl_policy, 2277 .flags = GENL_ADMIN_PERM, 2278 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | 2279 DEVLINK_NL_FLAG_NEED_SB, 2280 }, 2281 { 2282 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET, 2283 .doit = devlink_nl_cmd_sb_port_pool_get_doit, 2284 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit, 2285 .policy = devlink_nl_policy, 2286 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT | 2287 DEVLINK_NL_FLAG_NEED_SB, 2288 /* can be retrieved by unprivileged users */ 2289 }, 2290 { 2291 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET, 2292 .doit = devlink_nl_cmd_sb_port_pool_set_doit, 2293 .policy = devlink_nl_policy, 2294 .flags = GENL_ADMIN_PERM, 2295 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT | 2296 DEVLINK_NL_FLAG_NEED_SB, 2297 }, 2298 { 2299 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET, 2300 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit, 2301 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit, 2302 .policy = devlink_nl_policy, 2303 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT | 2304 DEVLINK_NL_FLAG_NEED_SB, 2305 /* can be retrieved by unprivileged users */ 2306 }, 2307 { 2308 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET, 2309 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit, 2310 .policy = devlink_nl_policy, 2311 .flags = GENL_ADMIN_PERM, 2312 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT | 2313 DEVLINK_NL_FLAG_NEED_SB, 2314 }, 2315 { 2316 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT, 2317 .doit = devlink_nl_cmd_sb_occ_snapshot_doit, 2318 .policy = devlink_nl_policy, 2319 .flags = GENL_ADMIN_PERM, 2320 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | 2321 DEVLINK_NL_FLAG_NEED_SB | 2322 DEVLINK_NL_FLAG_LOCK_PORTS, 2323 }, 2324 { 2325 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR, 2326 .doit = devlink_nl_cmd_sb_occ_max_clear_doit, 2327 .policy = devlink_nl_policy, 2328 .flags = GENL_ADMIN_PERM, 2329 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | 2330 DEVLINK_NL_FLAG_NEED_SB | 2331 DEVLINK_NL_FLAG_LOCK_PORTS, 2332 }, 2333 { 2334 .cmd = DEVLINK_CMD_ESWITCH_GET, 2335 .doit = devlink_nl_cmd_eswitch_get_doit, 2336 .policy = devlink_nl_policy, 2337 .flags = GENL_ADMIN_PERM, 2338 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2339 }, 2340 { 2341 .cmd = DEVLINK_CMD_ESWITCH_SET, 2342 .doit = devlink_nl_cmd_eswitch_set_doit, 2343 .policy = devlink_nl_policy, 2344 .flags = GENL_ADMIN_PERM, 2345 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2346 }, 2347 { 2348 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET, 2349 .doit = devlink_nl_cmd_dpipe_table_get, 2350 .policy = devlink_nl_policy, 2351 .flags = GENL_ADMIN_PERM, 2352 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2353 }, 2354 { 2355 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET, 2356 .doit = devlink_nl_cmd_dpipe_entries_get, 2357 .policy = devlink_nl_policy, 2358 .flags = GENL_ADMIN_PERM, 2359 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2360 }, 2361 { 2362 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET, 2363 .doit = devlink_nl_cmd_dpipe_headers_get, 2364 .policy = devlink_nl_policy, 2365 .flags = GENL_ADMIN_PERM, 2366 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2367 }, 2368 { 2369 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, 2370 .doit = devlink_nl_cmd_dpipe_table_counters_set, 2371 .policy = devlink_nl_policy, 2372 .flags = GENL_ADMIN_PERM, 2373 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2374 }, 2375}; 2376 2377static struct genl_family devlink_nl_family __ro_after_init = { 2378 .name = DEVLINK_GENL_NAME, 2379 .version = DEVLINK_GENL_VERSION, 2380 .maxattr = DEVLINK_ATTR_MAX, 2381 .netnsok = true, 2382 .pre_doit = devlink_nl_pre_doit, 2383 .post_doit = devlink_nl_post_doit, 2384 .module = THIS_MODULE, 2385 .ops = devlink_nl_ops, 2386 .n_ops = ARRAY_SIZE(devlink_nl_ops), 2387 .mcgrps = devlink_nl_mcgrps, 2388 .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps), 2389}; 2390 2391/** 2392 * devlink_alloc - Allocate new devlink instance resources 2393 * 2394 * @ops: ops 2395 * @priv_size: size of user private data 2396 * 2397 * Allocate new devlink instance resources, including devlink index 2398 * and name. 2399 */ 2400struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size) 2401{ 2402 struct devlink *devlink; 2403 2404 devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL); 2405 if (!devlink) 2406 return NULL; 2407 devlink->ops = ops; 2408 devlink_net_set(devlink, &init_net); 2409 INIT_LIST_HEAD(&devlink->port_list); 2410 INIT_LIST_HEAD(&devlink->sb_list); 2411 INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list); 2412 return devlink; 2413} 2414EXPORT_SYMBOL_GPL(devlink_alloc); 2415 2416/** 2417 * devlink_register - Register devlink instance 2418 * 2419 * @devlink: devlink 2420 */ 2421int devlink_register(struct devlink *devlink, struct device *dev) 2422{ 2423 mutex_lock(&devlink_mutex); 2424 devlink->dev = dev; 2425 list_add_tail(&devlink->list, &devlink_list); 2426 devlink_notify(devlink, DEVLINK_CMD_NEW); 2427 mutex_unlock(&devlink_mutex); 2428 return 0; 2429} 2430EXPORT_SYMBOL_GPL(devlink_register); 2431 2432/** 2433 * devlink_unregister - Unregister devlink instance 2434 * 2435 * @devlink: devlink 2436 */ 2437void devlink_unregister(struct devlink *devlink) 2438{ 2439 mutex_lock(&devlink_mutex); 2440 devlink_notify(devlink, DEVLINK_CMD_DEL); 2441 list_del(&devlink->list); 2442 mutex_unlock(&devlink_mutex); 2443} 2444EXPORT_SYMBOL_GPL(devlink_unregister); 2445 2446/** 2447 * devlink_free - Free devlink instance resources 2448 * 2449 * @devlink: devlink 2450 */ 2451void devlink_free(struct devlink *devlink) 2452{ 2453 kfree(devlink); 2454} 2455EXPORT_SYMBOL_GPL(devlink_free); 2456 2457/** 2458 * devlink_port_register - Register devlink port 2459 * 2460 * @devlink: devlink 2461 * @devlink_port: devlink port 2462 * @port_index 2463 * 2464 * Register devlink port with provided port index. User can use 2465 * any indexing, even hw-related one. devlink_port structure 2466 * is convenient to be embedded inside user driver private structure. 2467 * Note that the caller should take care of zeroing the devlink_port 2468 * structure. 2469 */ 2470int devlink_port_register(struct devlink *devlink, 2471 struct devlink_port *devlink_port, 2472 unsigned int port_index) 2473{ 2474 mutex_lock(&devlink_port_mutex); 2475 if (devlink_port_index_exists(devlink, port_index)) { 2476 mutex_unlock(&devlink_port_mutex); 2477 return -EEXIST; 2478 } 2479 devlink_port->devlink = devlink; 2480 devlink_port->index = port_index; 2481 devlink_port->registered = true; 2482 list_add_tail(&devlink_port->list, &devlink->port_list); 2483 mutex_unlock(&devlink_port_mutex); 2484 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 2485 return 0; 2486} 2487EXPORT_SYMBOL_GPL(devlink_port_register); 2488 2489/** 2490 * devlink_port_unregister - Unregister devlink port 2491 * 2492 * @devlink_port: devlink port 2493 */ 2494void devlink_port_unregister(struct devlink_port *devlink_port) 2495{ 2496 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL); 2497 mutex_lock(&devlink_port_mutex); 2498 list_del(&devlink_port->list); 2499 mutex_unlock(&devlink_port_mutex); 2500} 2501EXPORT_SYMBOL_GPL(devlink_port_unregister); 2502 2503static void __devlink_port_type_set(struct devlink_port *devlink_port, 2504 enum devlink_port_type type, 2505 void *type_dev) 2506{ 2507 devlink_port->type = type; 2508 devlink_port->type_dev = type_dev; 2509 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 2510} 2511 2512/** 2513 * devlink_port_type_eth_set - Set port type to Ethernet 2514 * 2515 * @devlink_port: devlink port 2516 * @netdev: related netdevice 2517 */ 2518void devlink_port_type_eth_set(struct devlink_port *devlink_port, 2519 struct net_device *netdev) 2520{ 2521 return __devlink_port_type_set(devlink_port, 2522 DEVLINK_PORT_TYPE_ETH, netdev); 2523} 2524EXPORT_SYMBOL_GPL(devlink_port_type_eth_set); 2525 2526/** 2527 * devlink_port_type_ib_set - Set port type to InfiniBand 2528 * 2529 * @devlink_port: devlink port 2530 * @ibdev: related IB device 2531 */ 2532void devlink_port_type_ib_set(struct devlink_port *devlink_port, 2533 struct ib_device *ibdev) 2534{ 2535 return __devlink_port_type_set(devlink_port, 2536 DEVLINK_PORT_TYPE_IB, ibdev); 2537} 2538EXPORT_SYMBOL_GPL(devlink_port_type_ib_set); 2539 2540/** 2541 * devlink_port_type_clear - Clear port type 2542 * 2543 * @devlink_port: devlink port 2544 */ 2545void devlink_port_type_clear(struct devlink_port *devlink_port) 2546{ 2547 return __devlink_port_type_set(devlink_port, 2548 DEVLINK_PORT_TYPE_NOTSET, NULL); 2549} 2550EXPORT_SYMBOL_GPL(devlink_port_type_clear); 2551 2552/** 2553 * devlink_port_split_set - Set port is split 2554 * 2555 * @devlink_port: devlink port 2556 * @split_group: split group - identifies group split port is part of 2557 */ 2558void devlink_port_split_set(struct devlink_port *devlink_port, 2559 u32 split_group) 2560{ 2561 devlink_port->split = true; 2562 devlink_port->split_group = split_group; 2563 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 2564} 2565EXPORT_SYMBOL_GPL(devlink_port_split_set); 2566 2567int devlink_sb_register(struct devlink *devlink, unsigned int sb_index, 2568 u32 size, u16 ingress_pools_count, 2569 u16 egress_pools_count, u16 ingress_tc_count, 2570 u16 egress_tc_count) 2571{ 2572 struct devlink_sb *devlink_sb; 2573 int err = 0; 2574 2575 mutex_lock(&devlink_mutex); 2576 if (devlink_sb_index_exists(devlink, sb_index)) { 2577 err = -EEXIST; 2578 goto unlock; 2579 } 2580 2581 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL); 2582 if (!devlink_sb) { 2583 err = -ENOMEM; 2584 goto unlock; 2585 } 2586 devlink_sb->index = sb_index; 2587 devlink_sb->size = size; 2588 devlink_sb->ingress_pools_count = ingress_pools_count; 2589 devlink_sb->egress_pools_count = egress_pools_count; 2590 devlink_sb->ingress_tc_count = ingress_tc_count; 2591 devlink_sb->egress_tc_count = egress_tc_count; 2592 list_add_tail(&devlink_sb->list, &devlink->sb_list); 2593unlock: 2594 mutex_unlock(&devlink_mutex); 2595 return err; 2596} 2597EXPORT_SYMBOL_GPL(devlink_sb_register); 2598 2599void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index) 2600{ 2601 struct devlink_sb *devlink_sb; 2602 2603 mutex_lock(&devlink_mutex); 2604 devlink_sb = devlink_sb_get_by_index(devlink, sb_index); 2605 WARN_ON(!devlink_sb); 2606 list_del(&devlink_sb->list); 2607 mutex_unlock(&devlink_mutex); 2608 kfree(devlink_sb); 2609} 2610EXPORT_SYMBOL_GPL(devlink_sb_unregister); 2611 2612/** 2613 * devlink_dpipe_headers_register - register dpipe headers 2614 * 2615 * @devlink: devlink 2616 * @dpipe_headers: dpipe header array 2617 * 2618 * Register the headers supported by hardware. 2619 */ 2620int devlink_dpipe_headers_register(struct devlink *devlink, 2621 struct devlink_dpipe_headers *dpipe_headers) 2622{ 2623 mutex_lock(&devlink_mutex); 2624 devlink->dpipe_headers = dpipe_headers; 2625 mutex_unlock(&devlink_mutex); 2626 return 0; 2627} 2628EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register); 2629 2630/** 2631 * devlink_dpipe_headers_unregister - unregister dpipe headers 2632 * 2633 * @devlink: devlink 2634 * 2635 * Unregister the headers supported by hardware. 2636 */ 2637void devlink_dpipe_headers_unregister(struct devlink *devlink) 2638{ 2639 mutex_lock(&devlink_mutex); 2640 devlink->dpipe_headers = NULL; 2641 mutex_unlock(&devlink_mutex); 2642} 2643EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister); 2644 2645/** 2646 * devlink_dpipe_table_counter_enabled - check if counter allocation 2647 * required 2648 * @devlink: devlink 2649 * @table_name: tables name 2650 * 2651 * Used by driver to check if counter allocation is required. 2652 * After counter allocation is turned on the table entries 2653 * are updated to include counter statistics. 2654 * 2655 * After that point on the driver must respect the counter 2656 * state so that each entry added to the table is added 2657 * with a counter. 2658 */ 2659bool devlink_dpipe_table_counter_enabled(struct devlink *devlink, 2660 const char *table_name) 2661{ 2662 struct devlink_dpipe_table *table; 2663 bool enabled; 2664 2665 rcu_read_lock(); 2666 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 2667 table_name); 2668 enabled = false; 2669 if (table) 2670 enabled = table->counters_enabled; 2671 rcu_read_unlock(); 2672 return enabled; 2673} 2674EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled); 2675 2676/** 2677 * devlink_dpipe_table_register - register dpipe table 2678 * 2679 * @devlink: devlink 2680 * @table_name: table name 2681 * @table_ops: table ops 2682 * @priv: priv 2683 * @size: size 2684 * @counter_control_extern: external control for counters 2685 */ 2686int devlink_dpipe_table_register(struct devlink *devlink, 2687 const char *table_name, 2688 struct devlink_dpipe_table_ops *table_ops, 2689 void *priv, u64 size, 2690 bool counter_control_extern) 2691{ 2692 struct devlink_dpipe_table *table; 2693 2694 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name)) 2695 return -EEXIST; 2696 2697 table = kzalloc(sizeof(*table), GFP_KERNEL); 2698 if (!table) 2699 return -ENOMEM; 2700 2701 table->name = table_name; 2702 table->table_ops = table_ops; 2703 table->priv = priv; 2704 table->size = size; 2705 table->counter_control_extern = counter_control_extern; 2706 2707 mutex_lock(&devlink_mutex); 2708 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list); 2709 mutex_unlock(&devlink_mutex); 2710 return 0; 2711} 2712EXPORT_SYMBOL_GPL(devlink_dpipe_table_register); 2713 2714/** 2715 * devlink_dpipe_table_unregister - unregister dpipe table 2716 * 2717 * @devlink: devlink 2718 * @table_name: table name 2719 */ 2720void devlink_dpipe_table_unregister(struct devlink *devlink, 2721 const char *table_name) 2722{ 2723 struct devlink_dpipe_table *table; 2724 2725 mutex_lock(&devlink_mutex); 2726 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 2727 table_name); 2728 if (!table) 2729 goto unlock; 2730 list_del_rcu(&table->list); 2731 mutex_unlock(&devlink_mutex); 2732 kfree_rcu(table, rcu); 2733 return; 2734unlock: 2735 mutex_unlock(&devlink_mutex); 2736} 2737EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister); 2738 2739static int __init devlink_module_init(void) 2740{ 2741 return genl_register_family(&devlink_nl_family); 2742} 2743 2744static void __exit devlink_module_exit(void) 2745{ 2746 genl_unregister_family(&devlink_nl_family); 2747} 2748 2749module_init(devlink_module_init); 2750module_exit(devlink_module_exit); 2751 2752MODULE_LICENSE("GPL v2"); 2753MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>"); 2754MODULE_DESCRIPTION("Network physical device Netlink interface"); 2755MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);