at v4.13 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 nlmsg_free(skb); 1685 return -EMSGSIZE; 1686 } 1687 1688 if (devlink_nl_put_handle(skb, devlink)) 1689 goto nla_put_failure; 1690 tables_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLES); 1691 if (!tables_attr) 1692 goto nla_put_failure; 1693 1694 i = 0; 1695 incomplete = false; 1696 list_for_each_entry_from(table, dpipe_tables, list) { 1697 if (!table_name) { 1698 err = devlink_dpipe_table_put(skb, table); 1699 if (err) { 1700 if (!i) 1701 goto err_table_put; 1702 incomplete = true; 1703 break; 1704 } 1705 } else { 1706 if (!strcmp(table->name, table_name)) { 1707 err = devlink_dpipe_table_put(skb, table); 1708 if (err) 1709 break; 1710 } 1711 } 1712 i++; 1713 } 1714 1715 nla_nest_end(skb, tables_attr); 1716 genlmsg_end(skb, hdr); 1717 if (incomplete) 1718 goto start_again; 1719 1720send_done: 1721 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, 1722 NLMSG_DONE, 0, flags | NLM_F_MULTI); 1723 if (!nlh) { 1724 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 1725 if (err) 1726 goto err_skb_send_alloc; 1727 goto send_done; 1728 } 1729 1730 return genlmsg_reply(skb, info); 1731 1732nla_put_failure: 1733 err = -EMSGSIZE; 1734err_table_put: 1735err_skb_send_alloc: 1736 genlmsg_cancel(skb, hdr); 1737 nlmsg_free(skb); 1738 return err; 1739} 1740 1741static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb, 1742 struct genl_info *info) 1743{ 1744 struct devlink *devlink = info->user_ptr[0]; 1745 const char *table_name = NULL; 1746 1747 if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]) 1748 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); 1749 1750 return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0, 1751 &devlink->dpipe_table_list, 1752 table_name); 1753} 1754 1755static int devlink_dpipe_value_put(struct sk_buff *skb, 1756 struct devlink_dpipe_value *value) 1757{ 1758 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE, 1759 value->value_size, value->value)) 1760 return -EMSGSIZE; 1761 if (value->mask) 1762 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK, 1763 value->value_size, value->mask)) 1764 return -EMSGSIZE; 1765 if (value->mapping_valid) 1766 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING, 1767 value->mapping_value)) 1768 return -EMSGSIZE; 1769 return 0; 1770} 1771 1772static int devlink_dpipe_action_value_put(struct sk_buff *skb, 1773 struct devlink_dpipe_value *value) 1774{ 1775 if (!value->action) 1776 return -EINVAL; 1777 if (devlink_dpipe_action_put(skb, value->action)) 1778 return -EMSGSIZE; 1779 if (devlink_dpipe_value_put(skb, value)) 1780 return -EMSGSIZE; 1781 return 0; 1782} 1783 1784static int devlink_dpipe_action_values_put(struct sk_buff *skb, 1785 struct devlink_dpipe_value *values, 1786 unsigned int values_count) 1787{ 1788 struct nlattr *action_attr; 1789 int i; 1790 int err; 1791 1792 for (i = 0; i < values_count; i++) { 1793 action_attr = nla_nest_start(skb, 1794 DEVLINK_ATTR_DPIPE_ACTION_VALUE); 1795 if (!action_attr) 1796 return -EMSGSIZE; 1797 err = devlink_dpipe_action_value_put(skb, &values[i]); 1798 if (err) 1799 goto err_action_value_put; 1800 nla_nest_end(skb, action_attr); 1801 } 1802 return 0; 1803 1804err_action_value_put: 1805 nla_nest_cancel(skb, action_attr); 1806 return err; 1807} 1808 1809static int devlink_dpipe_match_value_put(struct sk_buff *skb, 1810 struct devlink_dpipe_value *value) 1811{ 1812 if (!value->match) 1813 return -EINVAL; 1814 if (devlink_dpipe_match_put(skb, value->match)) 1815 return -EMSGSIZE; 1816 if (devlink_dpipe_value_put(skb, value)) 1817 return -EMSGSIZE; 1818 return 0; 1819} 1820 1821static int devlink_dpipe_match_values_put(struct sk_buff *skb, 1822 struct devlink_dpipe_value *values, 1823 unsigned int values_count) 1824{ 1825 struct nlattr *match_attr; 1826 int i; 1827 int err; 1828 1829 for (i = 0; i < values_count; i++) { 1830 match_attr = nla_nest_start(skb, 1831 DEVLINK_ATTR_DPIPE_MATCH_VALUE); 1832 if (!match_attr) 1833 return -EMSGSIZE; 1834 err = devlink_dpipe_match_value_put(skb, &values[i]); 1835 if (err) 1836 goto err_match_value_put; 1837 nla_nest_end(skb, match_attr); 1838 } 1839 return 0; 1840 1841err_match_value_put: 1842 nla_nest_cancel(skb, match_attr); 1843 return err; 1844} 1845 1846static int devlink_dpipe_entry_put(struct sk_buff *skb, 1847 struct devlink_dpipe_entry *entry) 1848{ 1849 struct nlattr *entry_attr, *matches_attr, *actions_attr; 1850 int err; 1851 1852 entry_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_ENTRY); 1853 if (!entry_attr) 1854 return -EMSGSIZE; 1855 1856 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index, 1857 DEVLINK_ATTR_PAD)) 1858 goto nla_put_failure; 1859 if (entry->counter_valid) 1860 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER, 1861 entry->counter, DEVLINK_ATTR_PAD)) 1862 goto nla_put_failure; 1863 1864 matches_attr = nla_nest_start(skb, 1865 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES); 1866 if (!matches_attr) 1867 goto nla_put_failure; 1868 1869 err = devlink_dpipe_match_values_put(skb, entry->match_values, 1870 entry->match_values_count); 1871 if (err) { 1872 nla_nest_cancel(skb, matches_attr); 1873 goto err_match_values_put; 1874 } 1875 nla_nest_end(skb, matches_attr); 1876 1877 actions_attr = nla_nest_start(skb, 1878 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES); 1879 if (!actions_attr) 1880 goto nla_put_failure; 1881 1882 err = devlink_dpipe_action_values_put(skb, entry->action_values, 1883 entry->action_values_count); 1884 if (err) { 1885 nla_nest_cancel(skb, actions_attr); 1886 goto err_action_values_put; 1887 } 1888 nla_nest_end(skb, actions_attr); 1889 1890 nla_nest_end(skb, entry_attr); 1891 return 0; 1892 1893nla_put_failure: 1894 err = -EMSGSIZE; 1895err_match_values_put: 1896err_action_values_put: 1897 nla_nest_cancel(skb, entry_attr); 1898 return err; 1899} 1900 1901static struct devlink_dpipe_table * 1902devlink_dpipe_table_find(struct list_head *dpipe_tables, 1903 const char *table_name) 1904{ 1905 struct devlink_dpipe_table *table; 1906 1907 list_for_each_entry_rcu(table, dpipe_tables, list) { 1908 if (!strcmp(table->name, table_name)) 1909 return table; 1910 } 1911 return NULL; 1912} 1913 1914int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx) 1915{ 1916 struct devlink *devlink; 1917 int err; 1918 1919 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb, 1920 dump_ctx->info); 1921 if (err) 1922 return err; 1923 1924 dump_ctx->hdr = genlmsg_put(dump_ctx->skb, 1925 dump_ctx->info->snd_portid, 1926 dump_ctx->info->snd_seq, 1927 &devlink_nl_family, NLM_F_MULTI, 1928 dump_ctx->cmd); 1929 if (!dump_ctx->hdr) 1930 goto nla_put_failure; 1931 1932 devlink = dump_ctx->info->user_ptr[0]; 1933 if (devlink_nl_put_handle(dump_ctx->skb, devlink)) 1934 goto nla_put_failure; 1935 dump_ctx->nest = nla_nest_start(dump_ctx->skb, 1936 DEVLINK_ATTR_DPIPE_ENTRIES); 1937 if (!dump_ctx->nest) 1938 goto nla_put_failure; 1939 return 0; 1940 1941nla_put_failure: 1942 genlmsg_cancel(dump_ctx->skb, dump_ctx->hdr); 1943 nlmsg_free(dump_ctx->skb); 1944 return -EMSGSIZE; 1945} 1946EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare); 1947 1948int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx, 1949 struct devlink_dpipe_entry *entry) 1950{ 1951 return devlink_dpipe_entry_put(dump_ctx->skb, entry); 1952} 1953EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append); 1954 1955int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx) 1956{ 1957 nla_nest_end(dump_ctx->skb, dump_ctx->nest); 1958 genlmsg_end(dump_ctx->skb, dump_ctx->hdr); 1959 return 0; 1960} 1961EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close); 1962 1963static int devlink_dpipe_entries_fill(struct genl_info *info, 1964 enum devlink_command cmd, int flags, 1965 struct devlink_dpipe_table *table) 1966{ 1967 struct devlink_dpipe_dump_ctx dump_ctx; 1968 struct nlmsghdr *nlh; 1969 int err; 1970 1971 dump_ctx.skb = NULL; 1972 dump_ctx.cmd = cmd; 1973 dump_ctx.info = info; 1974 1975 err = table->table_ops->entries_dump(table->priv, 1976 table->counters_enabled, 1977 &dump_ctx); 1978 if (err) 1979 goto err_entries_dump; 1980 1981send_done: 1982 nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq, 1983 NLMSG_DONE, 0, flags | NLM_F_MULTI); 1984 if (!nlh) { 1985 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info); 1986 if (err) 1987 goto err_skb_send_alloc; 1988 goto send_done; 1989 } 1990 return genlmsg_reply(dump_ctx.skb, info); 1991 1992err_entries_dump: 1993err_skb_send_alloc: 1994 genlmsg_cancel(dump_ctx.skb, dump_ctx.hdr); 1995 nlmsg_free(dump_ctx.skb); 1996 return err; 1997} 1998 1999static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb, 2000 struct genl_info *info) 2001{ 2002 struct devlink *devlink = info->user_ptr[0]; 2003 struct devlink_dpipe_table *table; 2004 const char *table_name; 2005 2006 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]) 2007 return -EINVAL; 2008 2009 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); 2010 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 2011 table_name); 2012 if (!table) 2013 return -EINVAL; 2014 2015 if (!table->table_ops->entries_dump) 2016 return -EINVAL; 2017 2018 return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET, 2019 0, table); 2020} 2021 2022static int devlink_dpipe_fields_put(struct sk_buff *skb, 2023 const struct devlink_dpipe_header *header) 2024{ 2025 struct devlink_dpipe_field *field; 2026 struct nlattr *field_attr; 2027 int i; 2028 2029 for (i = 0; i < header->fields_count; i++) { 2030 field = &header->fields[i]; 2031 field_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_FIELD); 2032 if (!field_attr) 2033 return -EMSGSIZE; 2034 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) || 2035 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || 2036 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) || 2037 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type)) 2038 goto nla_put_failure; 2039 nla_nest_end(skb, field_attr); 2040 } 2041 return 0; 2042 2043nla_put_failure: 2044 nla_nest_cancel(skb, field_attr); 2045 return -EMSGSIZE; 2046} 2047 2048static int devlink_dpipe_header_put(struct sk_buff *skb, 2049 struct devlink_dpipe_header *header) 2050{ 2051 struct nlattr *fields_attr, *header_attr; 2052 int err; 2053 2054 header_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER); 2055 if (!header_attr) 2056 return -EMSGSIZE; 2057 2058 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) || 2059 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || 2060 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) 2061 goto nla_put_failure; 2062 2063 fields_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER_FIELDS); 2064 if (!fields_attr) 2065 goto nla_put_failure; 2066 2067 err = devlink_dpipe_fields_put(skb, header); 2068 if (err) { 2069 nla_nest_cancel(skb, fields_attr); 2070 goto nla_put_failure; 2071 } 2072 nla_nest_end(skb, fields_attr); 2073 nla_nest_end(skb, header_attr); 2074 return 0; 2075 2076nla_put_failure: 2077 err = -EMSGSIZE; 2078 nla_nest_cancel(skb, header_attr); 2079 return err; 2080} 2081 2082static int devlink_dpipe_headers_fill(struct genl_info *info, 2083 enum devlink_command cmd, int flags, 2084 struct devlink_dpipe_headers * 2085 dpipe_headers) 2086{ 2087 struct devlink *devlink = info->user_ptr[0]; 2088 struct nlattr *headers_attr; 2089 struct sk_buff *skb = NULL; 2090 struct nlmsghdr *nlh; 2091 void *hdr; 2092 int i, j; 2093 int err; 2094 2095 i = 0; 2096start_again: 2097 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 2098 if (err) 2099 return err; 2100 2101 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, 2102 &devlink_nl_family, NLM_F_MULTI, cmd); 2103 if (!hdr) { 2104 nlmsg_free(skb); 2105 return -EMSGSIZE; 2106 } 2107 2108 if (devlink_nl_put_handle(skb, devlink)) 2109 goto nla_put_failure; 2110 headers_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADERS); 2111 if (!headers_attr) 2112 goto nla_put_failure; 2113 2114 j = 0; 2115 for (; i < dpipe_headers->headers_count; i++) { 2116 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]); 2117 if (err) { 2118 if (!j) 2119 goto err_table_put; 2120 break; 2121 } 2122 j++; 2123 } 2124 nla_nest_end(skb, headers_attr); 2125 genlmsg_end(skb, hdr); 2126 if (i != dpipe_headers->headers_count) 2127 goto start_again; 2128 2129send_done: 2130 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, 2131 NLMSG_DONE, 0, flags | NLM_F_MULTI); 2132 if (!nlh) { 2133 err = devlink_dpipe_send_and_alloc_skb(&skb, info); 2134 if (err) 2135 goto err_skb_send_alloc; 2136 goto send_done; 2137 } 2138 return genlmsg_reply(skb, info); 2139 2140nla_put_failure: 2141 err = -EMSGSIZE; 2142err_table_put: 2143err_skb_send_alloc: 2144 genlmsg_cancel(skb, hdr); 2145 nlmsg_free(skb); 2146 return err; 2147} 2148 2149static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb, 2150 struct genl_info *info) 2151{ 2152 struct devlink *devlink = info->user_ptr[0]; 2153 2154 if (!devlink->dpipe_headers) 2155 return -EOPNOTSUPP; 2156 return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET, 2157 0, devlink->dpipe_headers); 2158} 2159 2160static int devlink_dpipe_table_counters_set(struct devlink *devlink, 2161 const char *table_name, 2162 bool enable) 2163{ 2164 struct devlink_dpipe_table *table; 2165 2166 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 2167 table_name); 2168 if (!table) 2169 return -EINVAL; 2170 2171 if (table->counter_control_extern) 2172 return -EOPNOTSUPP; 2173 2174 if (!(table->counters_enabled ^ enable)) 2175 return 0; 2176 2177 table->counters_enabled = enable; 2178 if (table->table_ops->counters_set_update) 2179 table->table_ops->counters_set_update(table->priv, enable); 2180 return 0; 2181} 2182 2183static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb, 2184 struct genl_info *info) 2185{ 2186 struct devlink *devlink = info->user_ptr[0]; 2187 const char *table_name; 2188 bool counters_enable; 2189 2190 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] || 2191 !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]) 2192 return -EINVAL; 2193 2194 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); 2195 counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]); 2196 2197 return devlink_dpipe_table_counters_set(devlink, table_name, 2198 counters_enable); 2199} 2200 2201static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { 2202 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, 2203 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING }, 2204 [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 }, 2205 [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 }, 2206 [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 }, 2207 [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 }, 2208 [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 }, 2209 [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 }, 2210 [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 }, 2211 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 }, 2212 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 }, 2213 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 }, 2214 [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 }, 2215 [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 }, 2216 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 }, 2217 [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING }, 2218 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 }, 2219}; 2220 2221static const struct genl_ops devlink_nl_ops[] = { 2222 { 2223 .cmd = DEVLINK_CMD_GET, 2224 .doit = devlink_nl_cmd_get_doit, 2225 .dumpit = devlink_nl_cmd_get_dumpit, 2226 .policy = devlink_nl_policy, 2227 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2228 /* can be retrieved by unprivileged users */ 2229 }, 2230 { 2231 .cmd = DEVLINK_CMD_PORT_GET, 2232 .doit = devlink_nl_cmd_port_get_doit, 2233 .dumpit = devlink_nl_cmd_port_get_dumpit, 2234 .policy = devlink_nl_policy, 2235 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 2236 /* can be retrieved by unprivileged users */ 2237 }, 2238 { 2239 .cmd = DEVLINK_CMD_PORT_SET, 2240 .doit = devlink_nl_cmd_port_set_doit, 2241 .policy = devlink_nl_policy, 2242 .flags = GENL_ADMIN_PERM, 2243 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 2244 }, 2245 { 2246 .cmd = DEVLINK_CMD_PORT_SPLIT, 2247 .doit = devlink_nl_cmd_port_split_doit, 2248 .policy = devlink_nl_policy, 2249 .flags = GENL_ADMIN_PERM, 2250 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2251 }, 2252 { 2253 .cmd = DEVLINK_CMD_PORT_UNSPLIT, 2254 .doit = devlink_nl_cmd_port_unsplit_doit, 2255 .policy = devlink_nl_policy, 2256 .flags = GENL_ADMIN_PERM, 2257 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2258 }, 2259 { 2260 .cmd = DEVLINK_CMD_SB_GET, 2261 .doit = devlink_nl_cmd_sb_get_doit, 2262 .dumpit = devlink_nl_cmd_sb_get_dumpit, 2263 .policy = devlink_nl_policy, 2264 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | 2265 DEVLINK_NL_FLAG_NEED_SB, 2266 /* can be retrieved by unprivileged users */ 2267 }, 2268 { 2269 .cmd = DEVLINK_CMD_SB_POOL_GET, 2270 .doit = devlink_nl_cmd_sb_pool_get_doit, 2271 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit, 2272 .policy = devlink_nl_policy, 2273 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | 2274 DEVLINK_NL_FLAG_NEED_SB, 2275 /* can be retrieved by unprivileged users */ 2276 }, 2277 { 2278 .cmd = DEVLINK_CMD_SB_POOL_SET, 2279 .doit = devlink_nl_cmd_sb_pool_set_doit, 2280 .policy = devlink_nl_policy, 2281 .flags = GENL_ADMIN_PERM, 2282 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | 2283 DEVLINK_NL_FLAG_NEED_SB, 2284 }, 2285 { 2286 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET, 2287 .doit = devlink_nl_cmd_sb_port_pool_get_doit, 2288 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit, 2289 .policy = devlink_nl_policy, 2290 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT | 2291 DEVLINK_NL_FLAG_NEED_SB, 2292 /* can be retrieved by unprivileged users */ 2293 }, 2294 { 2295 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET, 2296 .doit = devlink_nl_cmd_sb_port_pool_set_doit, 2297 .policy = devlink_nl_policy, 2298 .flags = GENL_ADMIN_PERM, 2299 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT | 2300 DEVLINK_NL_FLAG_NEED_SB, 2301 }, 2302 { 2303 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET, 2304 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit, 2305 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit, 2306 .policy = devlink_nl_policy, 2307 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT | 2308 DEVLINK_NL_FLAG_NEED_SB, 2309 /* can be retrieved by unprivileged users */ 2310 }, 2311 { 2312 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET, 2313 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit, 2314 .policy = devlink_nl_policy, 2315 .flags = GENL_ADMIN_PERM, 2316 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT | 2317 DEVLINK_NL_FLAG_NEED_SB, 2318 }, 2319 { 2320 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT, 2321 .doit = devlink_nl_cmd_sb_occ_snapshot_doit, 2322 .policy = devlink_nl_policy, 2323 .flags = GENL_ADMIN_PERM, 2324 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | 2325 DEVLINK_NL_FLAG_NEED_SB | 2326 DEVLINK_NL_FLAG_LOCK_PORTS, 2327 }, 2328 { 2329 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR, 2330 .doit = devlink_nl_cmd_sb_occ_max_clear_doit, 2331 .policy = devlink_nl_policy, 2332 .flags = GENL_ADMIN_PERM, 2333 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | 2334 DEVLINK_NL_FLAG_NEED_SB | 2335 DEVLINK_NL_FLAG_LOCK_PORTS, 2336 }, 2337 { 2338 .cmd = DEVLINK_CMD_ESWITCH_GET, 2339 .doit = devlink_nl_cmd_eswitch_get_doit, 2340 .policy = devlink_nl_policy, 2341 .flags = GENL_ADMIN_PERM, 2342 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2343 }, 2344 { 2345 .cmd = DEVLINK_CMD_ESWITCH_SET, 2346 .doit = devlink_nl_cmd_eswitch_set_doit, 2347 .policy = devlink_nl_policy, 2348 .flags = GENL_ADMIN_PERM, 2349 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2350 }, 2351 { 2352 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET, 2353 .doit = devlink_nl_cmd_dpipe_table_get, 2354 .policy = devlink_nl_policy, 2355 .flags = GENL_ADMIN_PERM, 2356 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2357 }, 2358 { 2359 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET, 2360 .doit = devlink_nl_cmd_dpipe_entries_get, 2361 .policy = devlink_nl_policy, 2362 .flags = GENL_ADMIN_PERM, 2363 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2364 }, 2365 { 2366 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET, 2367 .doit = devlink_nl_cmd_dpipe_headers_get, 2368 .policy = devlink_nl_policy, 2369 .flags = GENL_ADMIN_PERM, 2370 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2371 }, 2372 { 2373 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, 2374 .doit = devlink_nl_cmd_dpipe_table_counters_set, 2375 .policy = devlink_nl_policy, 2376 .flags = GENL_ADMIN_PERM, 2377 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, 2378 }, 2379}; 2380 2381static struct genl_family devlink_nl_family __ro_after_init = { 2382 .name = DEVLINK_GENL_NAME, 2383 .version = DEVLINK_GENL_VERSION, 2384 .maxattr = DEVLINK_ATTR_MAX, 2385 .netnsok = true, 2386 .pre_doit = devlink_nl_pre_doit, 2387 .post_doit = devlink_nl_post_doit, 2388 .module = THIS_MODULE, 2389 .ops = devlink_nl_ops, 2390 .n_ops = ARRAY_SIZE(devlink_nl_ops), 2391 .mcgrps = devlink_nl_mcgrps, 2392 .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps), 2393}; 2394 2395/** 2396 * devlink_alloc - Allocate new devlink instance resources 2397 * 2398 * @ops: ops 2399 * @priv_size: size of user private data 2400 * 2401 * Allocate new devlink instance resources, including devlink index 2402 * and name. 2403 */ 2404struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size) 2405{ 2406 struct devlink *devlink; 2407 2408 devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL); 2409 if (!devlink) 2410 return NULL; 2411 devlink->ops = ops; 2412 devlink_net_set(devlink, &init_net); 2413 INIT_LIST_HEAD(&devlink->port_list); 2414 INIT_LIST_HEAD(&devlink->sb_list); 2415 INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list); 2416 return devlink; 2417} 2418EXPORT_SYMBOL_GPL(devlink_alloc); 2419 2420/** 2421 * devlink_register - Register devlink instance 2422 * 2423 * @devlink: devlink 2424 */ 2425int devlink_register(struct devlink *devlink, struct device *dev) 2426{ 2427 mutex_lock(&devlink_mutex); 2428 devlink->dev = dev; 2429 list_add_tail(&devlink->list, &devlink_list); 2430 devlink_notify(devlink, DEVLINK_CMD_NEW); 2431 mutex_unlock(&devlink_mutex); 2432 return 0; 2433} 2434EXPORT_SYMBOL_GPL(devlink_register); 2435 2436/** 2437 * devlink_unregister - Unregister devlink instance 2438 * 2439 * @devlink: devlink 2440 */ 2441void devlink_unregister(struct devlink *devlink) 2442{ 2443 mutex_lock(&devlink_mutex); 2444 devlink_notify(devlink, DEVLINK_CMD_DEL); 2445 list_del(&devlink->list); 2446 mutex_unlock(&devlink_mutex); 2447} 2448EXPORT_SYMBOL_GPL(devlink_unregister); 2449 2450/** 2451 * devlink_free - Free devlink instance resources 2452 * 2453 * @devlink: devlink 2454 */ 2455void devlink_free(struct devlink *devlink) 2456{ 2457 kfree(devlink); 2458} 2459EXPORT_SYMBOL_GPL(devlink_free); 2460 2461/** 2462 * devlink_port_register - Register devlink port 2463 * 2464 * @devlink: devlink 2465 * @devlink_port: devlink port 2466 * @port_index 2467 * 2468 * Register devlink port with provided port index. User can use 2469 * any indexing, even hw-related one. devlink_port structure 2470 * is convenient to be embedded inside user driver private structure. 2471 * Note that the caller should take care of zeroing the devlink_port 2472 * structure. 2473 */ 2474int devlink_port_register(struct devlink *devlink, 2475 struct devlink_port *devlink_port, 2476 unsigned int port_index) 2477{ 2478 mutex_lock(&devlink_port_mutex); 2479 if (devlink_port_index_exists(devlink, port_index)) { 2480 mutex_unlock(&devlink_port_mutex); 2481 return -EEXIST; 2482 } 2483 devlink_port->devlink = devlink; 2484 devlink_port->index = port_index; 2485 devlink_port->registered = true; 2486 list_add_tail(&devlink_port->list, &devlink->port_list); 2487 mutex_unlock(&devlink_port_mutex); 2488 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 2489 return 0; 2490} 2491EXPORT_SYMBOL_GPL(devlink_port_register); 2492 2493/** 2494 * devlink_port_unregister - Unregister devlink port 2495 * 2496 * @devlink_port: devlink port 2497 */ 2498void devlink_port_unregister(struct devlink_port *devlink_port) 2499{ 2500 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL); 2501 mutex_lock(&devlink_port_mutex); 2502 list_del(&devlink_port->list); 2503 mutex_unlock(&devlink_port_mutex); 2504} 2505EXPORT_SYMBOL_GPL(devlink_port_unregister); 2506 2507static void __devlink_port_type_set(struct devlink_port *devlink_port, 2508 enum devlink_port_type type, 2509 void *type_dev) 2510{ 2511 devlink_port->type = type; 2512 devlink_port->type_dev = type_dev; 2513 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 2514} 2515 2516/** 2517 * devlink_port_type_eth_set - Set port type to Ethernet 2518 * 2519 * @devlink_port: devlink port 2520 * @netdev: related netdevice 2521 */ 2522void devlink_port_type_eth_set(struct devlink_port *devlink_port, 2523 struct net_device *netdev) 2524{ 2525 return __devlink_port_type_set(devlink_port, 2526 DEVLINK_PORT_TYPE_ETH, netdev); 2527} 2528EXPORT_SYMBOL_GPL(devlink_port_type_eth_set); 2529 2530/** 2531 * devlink_port_type_ib_set - Set port type to InfiniBand 2532 * 2533 * @devlink_port: devlink port 2534 * @ibdev: related IB device 2535 */ 2536void devlink_port_type_ib_set(struct devlink_port *devlink_port, 2537 struct ib_device *ibdev) 2538{ 2539 return __devlink_port_type_set(devlink_port, 2540 DEVLINK_PORT_TYPE_IB, ibdev); 2541} 2542EXPORT_SYMBOL_GPL(devlink_port_type_ib_set); 2543 2544/** 2545 * devlink_port_type_clear - Clear port type 2546 * 2547 * @devlink_port: devlink port 2548 */ 2549void devlink_port_type_clear(struct devlink_port *devlink_port) 2550{ 2551 return __devlink_port_type_set(devlink_port, 2552 DEVLINK_PORT_TYPE_NOTSET, NULL); 2553} 2554EXPORT_SYMBOL_GPL(devlink_port_type_clear); 2555 2556/** 2557 * devlink_port_split_set - Set port is split 2558 * 2559 * @devlink_port: devlink port 2560 * @split_group: split group - identifies group split port is part of 2561 */ 2562void devlink_port_split_set(struct devlink_port *devlink_port, 2563 u32 split_group) 2564{ 2565 devlink_port->split = true; 2566 devlink_port->split_group = split_group; 2567 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); 2568} 2569EXPORT_SYMBOL_GPL(devlink_port_split_set); 2570 2571int devlink_sb_register(struct devlink *devlink, unsigned int sb_index, 2572 u32 size, u16 ingress_pools_count, 2573 u16 egress_pools_count, u16 ingress_tc_count, 2574 u16 egress_tc_count) 2575{ 2576 struct devlink_sb *devlink_sb; 2577 int err = 0; 2578 2579 mutex_lock(&devlink_mutex); 2580 if (devlink_sb_index_exists(devlink, sb_index)) { 2581 err = -EEXIST; 2582 goto unlock; 2583 } 2584 2585 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL); 2586 if (!devlink_sb) { 2587 err = -ENOMEM; 2588 goto unlock; 2589 } 2590 devlink_sb->index = sb_index; 2591 devlink_sb->size = size; 2592 devlink_sb->ingress_pools_count = ingress_pools_count; 2593 devlink_sb->egress_pools_count = egress_pools_count; 2594 devlink_sb->ingress_tc_count = ingress_tc_count; 2595 devlink_sb->egress_tc_count = egress_tc_count; 2596 list_add_tail(&devlink_sb->list, &devlink->sb_list); 2597unlock: 2598 mutex_unlock(&devlink_mutex); 2599 return err; 2600} 2601EXPORT_SYMBOL_GPL(devlink_sb_register); 2602 2603void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index) 2604{ 2605 struct devlink_sb *devlink_sb; 2606 2607 mutex_lock(&devlink_mutex); 2608 devlink_sb = devlink_sb_get_by_index(devlink, sb_index); 2609 WARN_ON(!devlink_sb); 2610 list_del(&devlink_sb->list); 2611 mutex_unlock(&devlink_mutex); 2612 kfree(devlink_sb); 2613} 2614EXPORT_SYMBOL_GPL(devlink_sb_unregister); 2615 2616/** 2617 * devlink_dpipe_headers_register - register dpipe headers 2618 * 2619 * @devlink: devlink 2620 * @dpipe_headers: dpipe header array 2621 * 2622 * Register the headers supported by hardware. 2623 */ 2624int devlink_dpipe_headers_register(struct devlink *devlink, 2625 struct devlink_dpipe_headers *dpipe_headers) 2626{ 2627 mutex_lock(&devlink_mutex); 2628 devlink->dpipe_headers = dpipe_headers; 2629 mutex_unlock(&devlink_mutex); 2630 return 0; 2631} 2632EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register); 2633 2634/** 2635 * devlink_dpipe_headers_unregister - unregister dpipe headers 2636 * 2637 * @devlink: devlink 2638 * 2639 * Unregister the headers supported by hardware. 2640 */ 2641void devlink_dpipe_headers_unregister(struct devlink *devlink) 2642{ 2643 mutex_lock(&devlink_mutex); 2644 devlink->dpipe_headers = NULL; 2645 mutex_unlock(&devlink_mutex); 2646} 2647EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister); 2648 2649/** 2650 * devlink_dpipe_table_counter_enabled - check if counter allocation 2651 * required 2652 * @devlink: devlink 2653 * @table_name: tables name 2654 * 2655 * Used by driver to check if counter allocation is required. 2656 * After counter allocation is turned on the table entries 2657 * are updated to include counter statistics. 2658 * 2659 * After that point on the driver must respect the counter 2660 * state so that each entry added to the table is added 2661 * with a counter. 2662 */ 2663bool devlink_dpipe_table_counter_enabled(struct devlink *devlink, 2664 const char *table_name) 2665{ 2666 struct devlink_dpipe_table *table; 2667 bool enabled; 2668 2669 rcu_read_lock(); 2670 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 2671 table_name); 2672 enabled = false; 2673 if (table) 2674 enabled = table->counters_enabled; 2675 rcu_read_unlock(); 2676 return enabled; 2677} 2678EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled); 2679 2680/** 2681 * devlink_dpipe_table_register - register dpipe table 2682 * 2683 * @devlink: devlink 2684 * @table_name: table name 2685 * @table_ops: table ops 2686 * @priv: priv 2687 * @size: size 2688 * @counter_control_extern: external control for counters 2689 */ 2690int devlink_dpipe_table_register(struct devlink *devlink, 2691 const char *table_name, 2692 struct devlink_dpipe_table_ops *table_ops, 2693 void *priv, u64 size, 2694 bool counter_control_extern) 2695{ 2696 struct devlink_dpipe_table *table; 2697 2698 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name)) 2699 return -EEXIST; 2700 2701 table = kzalloc(sizeof(*table), GFP_KERNEL); 2702 if (!table) 2703 return -ENOMEM; 2704 2705 table->name = table_name; 2706 table->table_ops = table_ops; 2707 table->priv = priv; 2708 table->size = size; 2709 table->counter_control_extern = counter_control_extern; 2710 2711 mutex_lock(&devlink_mutex); 2712 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list); 2713 mutex_unlock(&devlink_mutex); 2714 return 0; 2715} 2716EXPORT_SYMBOL_GPL(devlink_dpipe_table_register); 2717 2718/** 2719 * devlink_dpipe_table_unregister - unregister dpipe table 2720 * 2721 * @devlink: devlink 2722 * @table_name: table name 2723 */ 2724void devlink_dpipe_table_unregister(struct devlink *devlink, 2725 const char *table_name) 2726{ 2727 struct devlink_dpipe_table *table; 2728 2729 mutex_lock(&devlink_mutex); 2730 table = devlink_dpipe_table_find(&devlink->dpipe_table_list, 2731 table_name); 2732 if (!table) 2733 goto unlock; 2734 list_del_rcu(&table->list); 2735 mutex_unlock(&devlink_mutex); 2736 kfree_rcu(table, rcu); 2737 return; 2738unlock: 2739 mutex_unlock(&devlink_mutex); 2740} 2741EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister); 2742 2743static int __init devlink_module_init(void) 2744{ 2745 return genl_register_family(&devlink_nl_family); 2746} 2747 2748static void __exit devlink_module_exit(void) 2749{ 2750 genl_unregister_family(&devlink_nl_family); 2751} 2752 2753module_init(devlink_module_init); 2754module_exit(devlink_module_exit); 2755 2756MODULE_LICENSE("GPL v2"); 2757MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>"); 2758MODULE_DESCRIPTION("Network physical device Netlink interface"); 2759MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);