switchdev.c (25595B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * net/switchdev/switchdev.c - Switch device API 4 * Copyright (c) 2014-2015 Jiri Pirko <jiri@resnulli.us> 5 * Copyright (c) 2014-2015 Scott Feldman <sfeldma@gmail.com> 6 */ 7 8#include <linux/kernel.h> 9#include <linux/types.h> 10#include <linux/init.h> 11#include <linux/mutex.h> 12#include <linux/notifier.h> 13#include <linux/netdevice.h> 14#include <linux/etherdevice.h> 15#include <linux/if_bridge.h> 16#include <linux/list.h> 17#include <linux/workqueue.h> 18#include <linux/if_vlan.h> 19#include <linux/rtnetlink.h> 20#include <net/switchdev.h> 21 22static LIST_HEAD(deferred); 23static DEFINE_SPINLOCK(deferred_lock); 24 25typedef void switchdev_deferred_func_t(struct net_device *dev, 26 const void *data); 27 28struct switchdev_deferred_item { 29 struct list_head list; 30 struct net_device *dev; 31 netdevice_tracker dev_tracker; 32 switchdev_deferred_func_t *func; 33 unsigned long data[]; 34}; 35 36static struct switchdev_deferred_item *switchdev_deferred_dequeue(void) 37{ 38 struct switchdev_deferred_item *dfitem; 39 40 spin_lock_bh(&deferred_lock); 41 if (list_empty(&deferred)) { 42 dfitem = NULL; 43 goto unlock; 44 } 45 dfitem = list_first_entry(&deferred, 46 struct switchdev_deferred_item, list); 47 list_del(&dfitem->list); 48unlock: 49 spin_unlock_bh(&deferred_lock); 50 return dfitem; 51} 52 53/** 54 * switchdev_deferred_process - Process ops in deferred queue 55 * 56 * Called to flush the ops currently queued in deferred ops queue. 57 * rtnl_lock must be held. 58 */ 59void switchdev_deferred_process(void) 60{ 61 struct switchdev_deferred_item *dfitem; 62 63 ASSERT_RTNL(); 64 65 while ((dfitem = switchdev_deferred_dequeue())) { 66 dfitem->func(dfitem->dev, dfitem->data); 67 dev_put_track(dfitem->dev, &dfitem->dev_tracker); 68 kfree(dfitem); 69 } 70} 71EXPORT_SYMBOL_GPL(switchdev_deferred_process); 72 73static void switchdev_deferred_process_work(struct work_struct *work) 74{ 75 rtnl_lock(); 76 switchdev_deferred_process(); 77 rtnl_unlock(); 78} 79 80static DECLARE_WORK(deferred_process_work, switchdev_deferred_process_work); 81 82static int switchdev_deferred_enqueue(struct net_device *dev, 83 const void *data, size_t data_len, 84 switchdev_deferred_func_t *func) 85{ 86 struct switchdev_deferred_item *dfitem; 87 88 dfitem = kmalloc(struct_size(dfitem, data, data_len), GFP_ATOMIC); 89 if (!dfitem) 90 return -ENOMEM; 91 dfitem->dev = dev; 92 dfitem->func = func; 93 memcpy(dfitem->data, data, data_len); 94 dev_hold_track(dev, &dfitem->dev_tracker, GFP_ATOMIC); 95 spin_lock_bh(&deferred_lock); 96 list_add_tail(&dfitem->list, &deferred); 97 spin_unlock_bh(&deferred_lock); 98 schedule_work(&deferred_process_work); 99 return 0; 100} 101 102static int switchdev_port_attr_notify(enum switchdev_notifier_type nt, 103 struct net_device *dev, 104 const struct switchdev_attr *attr, 105 struct netlink_ext_ack *extack) 106{ 107 int err; 108 int rc; 109 110 struct switchdev_notifier_port_attr_info attr_info = { 111 .attr = attr, 112 .handled = false, 113 }; 114 115 rc = call_switchdev_blocking_notifiers(nt, dev, 116 &attr_info.info, extack); 117 err = notifier_to_errno(rc); 118 if (err) { 119 WARN_ON(!attr_info.handled); 120 return err; 121 } 122 123 if (!attr_info.handled) 124 return -EOPNOTSUPP; 125 126 return 0; 127} 128 129static int switchdev_port_attr_set_now(struct net_device *dev, 130 const struct switchdev_attr *attr, 131 struct netlink_ext_ack *extack) 132{ 133 return switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_SET, dev, attr, 134 extack); 135} 136 137static void switchdev_port_attr_set_deferred(struct net_device *dev, 138 const void *data) 139{ 140 const struct switchdev_attr *attr = data; 141 int err; 142 143 err = switchdev_port_attr_set_now(dev, attr, NULL); 144 if (err && err != -EOPNOTSUPP) 145 netdev_err(dev, "failed (err=%d) to set attribute (id=%d)\n", 146 err, attr->id); 147 if (attr->complete) 148 attr->complete(dev, err, attr->complete_priv); 149} 150 151static int switchdev_port_attr_set_defer(struct net_device *dev, 152 const struct switchdev_attr *attr) 153{ 154 return switchdev_deferred_enqueue(dev, attr, sizeof(*attr), 155 switchdev_port_attr_set_deferred); 156} 157 158/** 159 * switchdev_port_attr_set - Set port attribute 160 * 161 * @dev: port device 162 * @attr: attribute to set 163 * @extack: netlink extended ack, for error message propagation 164 * 165 * rtnl_lock must be held and must not be in atomic section, 166 * in case SWITCHDEV_F_DEFER flag is not set. 167 */ 168int switchdev_port_attr_set(struct net_device *dev, 169 const struct switchdev_attr *attr, 170 struct netlink_ext_ack *extack) 171{ 172 if (attr->flags & SWITCHDEV_F_DEFER) 173 return switchdev_port_attr_set_defer(dev, attr); 174 ASSERT_RTNL(); 175 return switchdev_port_attr_set_now(dev, attr, extack); 176} 177EXPORT_SYMBOL_GPL(switchdev_port_attr_set); 178 179static size_t switchdev_obj_size(const struct switchdev_obj *obj) 180{ 181 switch (obj->id) { 182 case SWITCHDEV_OBJ_ID_PORT_VLAN: 183 return sizeof(struct switchdev_obj_port_vlan); 184 case SWITCHDEV_OBJ_ID_PORT_MDB: 185 return sizeof(struct switchdev_obj_port_mdb); 186 case SWITCHDEV_OBJ_ID_HOST_MDB: 187 return sizeof(struct switchdev_obj_port_mdb); 188 default: 189 BUG(); 190 } 191 return 0; 192} 193 194static int switchdev_port_obj_notify(enum switchdev_notifier_type nt, 195 struct net_device *dev, 196 const struct switchdev_obj *obj, 197 struct netlink_ext_ack *extack) 198{ 199 int rc; 200 int err; 201 202 struct switchdev_notifier_port_obj_info obj_info = { 203 .obj = obj, 204 .handled = false, 205 }; 206 207 rc = call_switchdev_blocking_notifiers(nt, dev, &obj_info.info, extack); 208 err = notifier_to_errno(rc); 209 if (err) { 210 WARN_ON(!obj_info.handled); 211 return err; 212 } 213 if (!obj_info.handled) 214 return -EOPNOTSUPP; 215 return 0; 216} 217 218static void switchdev_port_obj_add_deferred(struct net_device *dev, 219 const void *data) 220{ 221 const struct switchdev_obj *obj = data; 222 int err; 223 224 ASSERT_RTNL(); 225 err = switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD, 226 dev, obj, NULL); 227 if (err && err != -EOPNOTSUPP) 228 netdev_err(dev, "failed (err=%d) to add object (id=%d)\n", 229 err, obj->id); 230 if (obj->complete) 231 obj->complete(dev, err, obj->complete_priv); 232} 233 234static int switchdev_port_obj_add_defer(struct net_device *dev, 235 const struct switchdev_obj *obj) 236{ 237 return switchdev_deferred_enqueue(dev, obj, switchdev_obj_size(obj), 238 switchdev_port_obj_add_deferred); 239} 240 241/** 242 * switchdev_port_obj_add - Add port object 243 * 244 * @dev: port device 245 * @obj: object to add 246 * @extack: netlink extended ack 247 * 248 * rtnl_lock must be held and must not be in atomic section, 249 * in case SWITCHDEV_F_DEFER flag is not set. 250 */ 251int switchdev_port_obj_add(struct net_device *dev, 252 const struct switchdev_obj *obj, 253 struct netlink_ext_ack *extack) 254{ 255 if (obj->flags & SWITCHDEV_F_DEFER) 256 return switchdev_port_obj_add_defer(dev, obj); 257 ASSERT_RTNL(); 258 return switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD, 259 dev, obj, extack); 260} 261EXPORT_SYMBOL_GPL(switchdev_port_obj_add); 262 263static int switchdev_port_obj_del_now(struct net_device *dev, 264 const struct switchdev_obj *obj) 265{ 266 return switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_DEL, 267 dev, obj, NULL); 268} 269 270static void switchdev_port_obj_del_deferred(struct net_device *dev, 271 const void *data) 272{ 273 const struct switchdev_obj *obj = data; 274 int err; 275 276 err = switchdev_port_obj_del_now(dev, obj); 277 if (err && err != -EOPNOTSUPP) 278 netdev_err(dev, "failed (err=%d) to del object (id=%d)\n", 279 err, obj->id); 280 if (obj->complete) 281 obj->complete(dev, err, obj->complete_priv); 282} 283 284static int switchdev_port_obj_del_defer(struct net_device *dev, 285 const struct switchdev_obj *obj) 286{ 287 return switchdev_deferred_enqueue(dev, obj, switchdev_obj_size(obj), 288 switchdev_port_obj_del_deferred); 289} 290 291/** 292 * switchdev_port_obj_del - Delete port object 293 * 294 * @dev: port device 295 * @obj: object to delete 296 * 297 * rtnl_lock must be held and must not be in atomic section, 298 * in case SWITCHDEV_F_DEFER flag is not set. 299 */ 300int switchdev_port_obj_del(struct net_device *dev, 301 const struct switchdev_obj *obj) 302{ 303 if (obj->flags & SWITCHDEV_F_DEFER) 304 return switchdev_port_obj_del_defer(dev, obj); 305 ASSERT_RTNL(); 306 return switchdev_port_obj_del_now(dev, obj); 307} 308EXPORT_SYMBOL_GPL(switchdev_port_obj_del); 309 310static ATOMIC_NOTIFIER_HEAD(switchdev_notif_chain); 311static BLOCKING_NOTIFIER_HEAD(switchdev_blocking_notif_chain); 312 313/** 314 * register_switchdev_notifier - Register notifier 315 * @nb: notifier_block 316 * 317 * Register switch device notifier. 318 */ 319int register_switchdev_notifier(struct notifier_block *nb) 320{ 321 return atomic_notifier_chain_register(&switchdev_notif_chain, nb); 322} 323EXPORT_SYMBOL_GPL(register_switchdev_notifier); 324 325/** 326 * unregister_switchdev_notifier - Unregister notifier 327 * @nb: notifier_block 328 * 329 * Unregister switch device notifier. 330 */ 331int unregister_switchdev_notifier(struct notifier_block *nb) 332{ 333 return atomic_notifier_chain_unregister(&switchdev_notif_chain, nb); 334} 335EXPORT_SYMBOL_GPL(unregister_switchdev_notifier); 336 337/** 338 * call_switchdev_notifiers - Call notifiers 339 * @val: value passed unmodified to notifier function 340 * @dev: port device 341 * @info: notifier information data 342 * @extack: netlink extended ack 343 * Call all network notifier blocks. 344 */ 345int call_switchdev_notifiers(unsigned long val, struct net_device *dev, 346 struct switchdev_notifier_info *info, 347 struct netlink_ext_ack *extack) 348{ 349 info->dev = dev; 350 info->extack = extack; 351 return atomic_notifier_call_chain(&switchdev_notif_chain, val, info); 352} 353EXPORT_SYMBOL_GPL(call_switchdev_notifiers); 354 355int register_switchdev_blocking_notifier(struct notifier_block *nb) 356{ 357 struct blocking_notifier_head *chain = &switchdev_blocking_notif_chain; 358 359 return blocking_notifier_chain_register(chain, nb); 360} 361EXPORT_SYMBOL_GPL(register_switchdev_blocking_notifier); 362 363int unregister_switchdev_blocking_notifier(struct notifier_block *nb) 364{ 365 struct blocking_notifier_head *chain = &switchdev_blocking_notif_chain; 366 367 return blocking_notifier_chain_unregister(chain, nb); 368} 369EXPORT_SYMBOL_GPL(unregister_switchdev_blocking_notifier); 370 371int call_switchdev_blocking_notifiers(unsigned long val, struct net_device *dev, 372 struct switchdev_notifier_info *info, 373 struct netlink_ext_ack *extack) 374{ 375 info->dev = dev; 376 info->extack = extack; 377 return blocking_notifier_call_chain(&switchdev_blocking_notif_chain, 378 val, info); 379} 380EXPORT_SYMBOL_GPL(call_switchdev_blocking_notifiers); 381 382struct switchdev_nested_priv { 383 bool (*check_cb)(const struct net_device *dev); 384 bool (*foreign_dev_check_cb)(const struct net_device *dev, 385 const struct net_device *foreign_dev); 386 const struct net_device *dev; 387 struct net_device *lower_dev; 388}; 389 390static int switchdev_lower_dev_walk(struct net_device *lower_dev, 391 struct netdev_nested_priv *priv) 392{ 393 struct switchdev_nested_priv *switchdev_priv = priv->data; 394 bool (*foreign_dev_check_cb)(const struct net_device *dev, 395 const struct net_device *foreign_dev); 396 bool (*check_cb)(const struct net_device *dev); 397 const struct net_device *dev; 398 399 check_cb = switchdev_priv->check_cb; 400 foreign_dev_check_cb = switchdev_priv->foreign_dev_check_cb; 401 dev = switchdev_priv->dev; 402 403 if (check_cb(lower_dev) && !foreign_dev_check_cb(lower_dev, dev)) { 404 switchdev_priv->lower_dev = lower_dev; 405 return 1; 406 } 407 408 return 0; 409} 410 411static struct net_device * 412switchdev_lower_dev_find_rcu(struct net_device *dev, 413 bool (*check_cb)(const struct net_device *dev), 414 bool (*foreign_dev_check_cb)(const struct net_device *dev, 415 const struct net_device *foreign_dev)) 416{ 417 struct switchdev_nested_priv switchdev_priv = { 418 .check_cb = check_cb, 419 .foreign_dev_check_cb = foreign_dev_check_cb, 420 .dev = dev, 421 .lower_dev = NULL, 422 }; 423 struct netdev_nested_priv priv = { 424 .data = &switchdev_priv, 425 }; 426 427 netdev_walk_all_lower_dev_rcu(dev, switchdev_lower_dev_walk, &priv); 428 429 return switchdev_priv.lower_dev; 430} 431 432static struct net_device * 433switchdev_lower_dev_find(struct net_device *dev, 434 bool (*check_cb)(const struct net_device *dev), 435 bool (*foreign_dev_check_cb)(const struct net_device *dev, 436 const struct net_device *foreign_dev)) 437{ 438 struct switchdev_nested_priv switchdev_priv = { 439 .check_cb = check_cb, 440 .foreign_dev_check_cb = foreign_dev_check_cb, 441 .dev = dev, 442 .lower_dev = NULL, 443 }; 444 struct netdev_nested_priv priv = { 445 .data = &switchdev_priv, 446 }; 447 448 netdev_walk_all_lower_dev(dev, switchdev_lower_dev_walk, &priv); 449 450 return switchdev_priv.lower_dev; 451} 452 453static int __switchdev_handle_fdb_event_to_device(struct net_device *dev, 454 struct net_device *orig_dev, unsigned long event, 455 const struct switchdev_notifier_fdb_info *fdb_info, 456 bool (*check_cb)(const struct net_device *dev), 457 bool (*foreign_dev_check_cb)(const struct net_device *dev, 458 const struct net_device *foreign_dev), 459 int (*mod_cb)(struct net_device *dev, struct net_device *orig_dev, 460 unsigned long event, const void *ctx, 461 const struct switchdev_notifier_fdb_info *fdb_info)) 462{ 463 const struct switchdev_notifier_info *info = &fdb_info->info; 464 struct net_device *br, *lower_dev, *switchdev; 465 struct list_head *iter; 466 int err = -EOPNOTSUPP; 467 468 if (check_cb(dev)) 469 return mod_cb(dev, orig_dev, event, info->ctx, fdb_info); 470 471 /* Recurse through lower interfaces in case the FDB entry is pointing 472 * towards a bridge or a LAG device. 473 */ 474 netdev_for_each_lower_dev(dev, lower_dev, iter) { 475 /* Do not propagate FDB entries across bridges */ 476 if (netif_is_bridge_master(lower_dev)) 477 continue; 478 479 /* Bridge ports might be either us, or LAG interfaces 480 * that we offload. 481 */ 482 if (!check_cb(lower_dev) && 483 !switchdev_lower_dev_find_rcu(lower_dev, check_cb, 484 foreign_dev_check_cb)) 485 continue; 486 487 err = __switchdev_handle_fdb_event_to_device(lower_dev, orig_dev, 488 event, fdb_info, check_cb, 489 foreign_dev_check_cb, 490 mod_cb); 491 if (err && err != -EOPNOTSUPP) 492 return err; 493 } 494 495 /* Event is neither on a bridge nor a LAG. Check whether it is on an 496 * interface that is in a bridge with us. 497 */ 498 br = netdev_master_upper_dev_get_rcu(dev); 499 if (!br || !netif_is_bridge_master(br)) 500 return 0; 501 502 switchdev = switchdev_lower_dev_find_rcu(br, check_cb, foreign_dev_check_cb); 503 if (!switchdev) 504 return 0; 505 506 if (!foreign_dev_check_cb(switchdev, dev)) 507 return err; 508 509 return __switchdev_handle_fdb_event_to_device(br, orig_dev, event, fdb_info, 510 check_cb, foreign_dev_check_cb, 511 mod_cb); 512} 513 514int switchdev_handle_fdb_event_to_device(struct net_device *dev, unsigned long event, 515 const struct switchdev_notifier_fdb_info *fdb_info, 516 bool (*check_cb)(const struct net_device *dev), 517 bool (*foreign_dev_check_cb)(const struct net_device *dev, 518 const struct net_device *foreign_dev), 519 int (*mod_cb)(struct net_device *dev, struct net_device *orig_dev, 520 unsigned long event, const void *ctx, 521 const struct switchdev_notifier_fdb_info *fdb_info)) 522{ 523 int err; 524 525 err = __switchdev_handle_fdb_event_to_device(dev, dev, event, fdb_info, 526 check_cb, foreign_dev_check_cb, 527 mod_cb); 528 if (err == -EOPNOTSUPP) 529 err = 0; 530 531 return err; 532} 533EXPORT_SYMBOL_GPL(switchdev_handle_fdb_event_to_device); 534 535static int __switchdev_handle_port_obj_add(struct net_device *dev, 536 struct switchdev_notifier_port_obj_info *port_obj_info, 537 bool (*check_cb)(const struct net_device *dev), 538 bool (*foreign_dev_check_cb)(const struct net_device *dev, 539 const struct net_device *foreign_dev), 540 int (*add_cb)(struct net_device *dev, const void *ctx, 541 const struct switchdev_obj *obj, 542 struct netlink_ext_ack *extack)) 543{ 544 struct switchdev_notifier_info *info = &port_obj_info->info; 545 struct net_device *br, *lower_dev, *switchdev; 546 struct netlink_ext_ack *extack; 547 struct list_head *iter; 548 int err = -EOPNOTSUPP; 549 550 extack = switchdev_notifier_info_to_extack(info); 551 552 if (check_cb(dev)) { 553 err = add_cb(dev, info->ctx, port_obj_info->obj, extack); 554 if (err != -EOPNOTSUPP) 555 port_obj_info->handled = true; 556 return err; 557 } 558 559 /* Switch ports might be stacked under e.g. a LAG. Ignore the 560 * unsupported devices, another driver might be able to handle them. But 561 * propagate to the callers any hard errors. 562 * 563 * If the driver does its own bookkeeping of stacked ports, it's not 564 * necessary to go through this helper. 565 */ 566 netdev_for_each_lower_dev(dev, lower_dev, iter) { 567 if (netif_is_bridge_master(lower_dev)) 568 continue; 569 570 /* When searching for switchdev interfaces that are neighbors 571 * of foreign ones, and @dev is a bridge, do not recurse on the 572 * foreign interface again, it was already visited. 573 */ 574 if (foreign_dev_check_cb && !check_cb(lower_dev) && 575 !switchdev_lower_dev_find(lower_dev, check_cb, foreign_dev_check_cb)) 576 continue; 577 578 err = __switchdev_handle_port_obj_add(lower_dev, port_obj_info, 579 check_cb, foreign_dev_check_cb, 580 add_cb); 581 if (err && err != -EOPNOTSUPP) 582 return err; 583 } 584 585 /* Event is neither on a bridge nor a LAG. Check whether it is on an 586 * interface that is in a bridge with us. 587 */ 588 if (!foreign_dev_check_cb) 589 return err; 590 591 br = netdev_master_upper_dev_get(dev); 592 if (!br || !netif_is_bridge_master(br)) 593 return err; 594 595 switchdev = switchdev_lower_dev_find(br, check_cb, foreign_dev_check_cb); 596 if (!switchdev) 597 return err; 598 599 if (!foreign_dev_check_cb(switchdev, dev)) 600 return err; 601 602 return __switchdev_handle_port_obj_add(br, port_obj_info, check_cb, 603 foreign_dev_check_cb, add_cb); 604} 605 606/* Pass through a port object addition, if @dev passes @check_cb, or replicate 607 * it towards all lower interfaces of @dev that pass @check_cb, if @dev is a 608 * bridge or a LAG. 609 */ 610int switchdev_handle_port_obj_add(struct net_device *dev, 611 struct switchdev_notifier_port_obj_info *port_obj_info, 612 bool (*check_cb)(const struct net_device *dev), 613 int (*add_cb)(struct net_device *dev, const void *ctx, 614 const struct switchdev_obj *obj, 615 struct netlink_ext_ack *extack)) 616{ 617 int err; 618 619 err = __switchdev_handle_port_obj_add(dev, port_obj_info, check_cb, 620 NULL, add_cb); 621 if (err == -EOPNOTSUPP) 622 err = 0; 623 return err; 624} 625EXPORT_SYMBOL_GPL(switchdev_handle_port_obj_add); 626 627/* Same as switchdev_handle_port_obj_add(), except if object is notified on a 628 * @dev that passes @foreign_dev_check_cb, it is replicated towards all devices 629 * that pass @check_cb and are in the same bridge as @dev. 630 */ 631int switchdev_handle_port_obj_add_foreign(struct net_device *dev, 632 struct switchdev_notifier_port_obj_info *port_obj_info, 633 bool (*check_cb)(const struct net_device *dev), 634 bool (*foreign_dev_check_cb)(const struct net_device *dev, 635 const struct net_device *foreign_dev), 636 int (*add_cb)(struct net_device *dev, const void *ctx, 637 const struct switchdev_obj *obj, 638 struct netlink_ext_ack *extack)) 639{ 640 int err; 641 642 err = __switchdev_handle_port_obj_add(dev, port_obj_info, check_cb, 643 foreign_dev_check_cb, add_cb); 644 if (err == -EOPNOTSUPP) 645 err = 0; 646 return err; 647} 648EXPORT_SYMBOL_GPL(switchdev_handle_port_obj_add_foreign); 649 650static int __switchdev_handle_port_obj_del(struct net_device *dev, 651 struct switchdev_notifier_port_obj_info *port_obj_info, 652 bool (*check_cb)(const struct net_device *dev), 653 bool (*foreign_dev_check_cb)(const struct net_device *dev, 654 const struct net_device *foreign_dev), 655 int (*del_cb)(struct net_device *dev, const void *ctx, 656 const struct switchdev_obj *obj)) 657{ 658 struct switchdev_notifier_info *info = &port_obj_info->info; 659 struct net_device *br, *lower_dev, *switchdev; 660 struct list_head *iter; 661 int err = -EOPNOTSUPP; 662 663 if (check_cb(dev)) { 664 err = del_cb(dev, info->ctx, port_obj_info->obj); 665 if (err != -EOPNOTSUPP) 666 port_obj_info->handled = true; 667 return err; 668 } 669 670 /* Switch ports might be stacked under e.g. a LAG. Ignore the 671 * unsupported devices, another driver might be able to handle them. But 672 * propagate to the callers any hard errors. 673 * 674 * If the driver does its own bookkeeping of stacked ports, it's not 675 * necessary to go through this helper. 676 */ 677 netdev_for_each_lower_dev(dev, lower_dev, iter) { 678 if (netif_is_bridge_master(lower_dev)) 679 continue; 680 681 /* When searching for switchdev interfaces that are neighbors 682 * of foreign ones, and @dev is a bridge, do not recurse on the 683 * foreign interface again, it was already visited. 684 */ 685 if (foreign_dev_check_cb && !check_cb(lower_dev) && 686 !switchdev_lower_dev_find(lower_dev, check_cb, foreign_dev_check_cb)) 687 continue; 688 689 err = __switchdev_handle_port_obj_del(lower_dev, port_obj_info, 690 check_cb, foreign_dev_check_cb, 691 del_cb); 692 if (err && err != -EOPNOTSUPP) 693 return err; 694 } 695 696 /* Event is neither on a bridge nor a LAG. Check whether it is on an 697 * interface that is in a bridge with us. 698 */ 699 if (!foreign_dev_check_cb) 700 return err; 701 702 br = netdev_master_upper_dev_get(dev); 703 if (!br || !netif_is_bridge_master(br)) 704 return err; 705 706 switchdev = switchdev_lower_dev_find(br, check_cb, foreign_dev_check_cb); 707 if (!switchdev) 708 return err; 709 710 if (!foreign_dev_check_cb(switchdev, dev)) 711 return err; 712 713 return __switchdev_handle_port_obj_del(br, port_obj_info, check_cb, 714 foreign_dev_check_cb, del_cb); 715} 716 717/* Pass through a port object deletion, if @dev passes @check_cb, or replicate 718 * it towards all lower interfaces of @dev that pass @check_cb, if @dev is a 719 * bridge or a LAG. 720 */ 721int switchdev_handle_port_obj_del(struct net_device *dev, 722 struct switchdev_notifier_port_obj_info *port_obj_info, 723 bool (*check_cb)(const struct net_device *dev), 724 int (*del_cb)(struct net_device *dev, const void *ctx, 725 const struct switchdev_obj *obj)) 726{ 727 int err; 728 729 err = __switchdev_handle_port_obj_del(dev, port_obj_info, check_cb, 730 NULL, del_cb); 731 if (err == -EOPNOTSUPP) 732 err = 0; 733 return err; 734} 735EXPORT_SYMBOL_GPL(switchdev_handle_port_obj_del); 736 737/* Same as switchdev_handle_port_obj_del(), except if object is notified on a 738 * @dev that passes @foreign_dev_check_cb, it is replicated towards all devices 739 * that pass @check_cb and are in the same bridge as @dev. 740 */ 741int switchdev_handle_port_obj_del_foreign(struct net_device *dev, 742 struct switchdev_notifier_port_obj_info *port_obj_info, 743 bool (*check_cb)(const struct net_device *dev), 744 bool (*foreign_dev_check_cb)(const struct net_device *dev, 745 const struct net_device *foreign_dev), 746 int (*del_cb)(struct net_device *dev, const void *ctx, 747 const struct switchdev_obj *obj)) 748{ 749 int err; 750 751 err = __switchdev_handle_port_obj_del(dev, port_obj_info, check_cb, 752 foreign_dev_check_cb, del_cb); 753 if (err == -EOPNOTSUPP) 754 err = 0; 755 return err; 756} 757EXPORT_SYMBOL_GPL(switchdev_handle_port_obj_del_foreign); 758 759static int __switchdev_handle_port_attr_set(struct net_device *dev, 760 struct switchdev_notifier_port_attr_info *port_attr_info, 761 bool (*check_cb)(const struct net_device *dev), 762 int (*set_cb)(struct net_device *dev, const void *ctx, 763 const struct switchdev_attr *attr, 764 struct netlink_ext_ack *extack)) 765{ 766 struct switchdev_notifier_info *info = &port_attr_info->info; 767 struct netlink_ext_ack *extack; 768 struct net_device *lower_dev; 769 struct list_head *iter; 770 int err = -EOPNOTSUPP; 771 772 extack = switchdev_notifier_info_to_extack(info); 773 774 if (check_cb(dev)) { 775 err = set_cb(dev, info->ctx, port_attr_info->attr, extack); 776 if (err != -EOPNOTSUPP) 777 port_attr_info->handled = true; 778 return err; 779 } 780 781 /* Switch ports might be stacked under e.g. a LAG. Ignore the 782 * unsupported devices, another driver might be able to handle them. But 783 * propagate to the callers any hard errors. 784 * 785 * If the driver does its own bookkeeping of stacked ports, it's not 786 * necessary to go through this helper. 787 */ 788 netdev_for_each_lower_dev(dev, lower_dev, iter) { 789 if (netif_is_bridge_master(lower_dev)) 790 continue; 791 792 err = __switchdev_handle_port_attr_set(lower_dev, port_attr_info, 793 check_cb, set_cb); 794 if (err && err != -EOPNOTSUPP) 795 return err; 796 } 797 798 return err; 799} 800 801int switchdev_handle_port_attr_set(struct net_device *dev, 802 struct switchdev_notifier_port_attr_info *port_attr_info, 803 bool (*check_cb)(const struct net_device *dev), 804 int (*set_cb)(struct net_device *dev, const void *ctx, 805 const struct switchdev_attr *attr, 806 struct netlink_ext_ack *extack)) 807{ 808 int err; 809 810 err = __switchdev_handle_port_attr_set(dev, port_attr_info, check_cb, 811 set_cb); 812 if (err == -EOPNOTSUPP) 813 err = 0; 814 return err; 815} 816EXPORT_SYMBOL_GPL(switchdev_handle_port_attr_set); 817 818int switchdev_bridge_port_offload(struct net_device *brport_dev, 819 struct net_device *dev, const void *ctx, 820 struct notifier_block *atomic_nb, 821 struct notifier_block *blocking_nb, 822 bool tx_fwd_offload, 823 struct netlink_ext_ack *extack) 824{ 825 struct switchdev_notifier_brport_info brport_info = { 826 .brport = { 827 .dev = dev, 828 .ctx = ctx, 829 .atomic_nb = atomic_nb, 830 .blocking_nb = blocking_nb, 831 .tx_fwd_offload = tx_fwd_offload, 832 }, 833 }; 834 int err; 835 836 ASSERT_RTNL(); 837 838 err = call_switchdev_blocking_notifiers(SWITCHDEV_BRPORT_OFFLOADED, 839 brport_dev, &brport_info.info, 840 extack); 841 return notifier_to_errno(err); 842} 843EXPORT_SYMBOL_GPL(switchdev_bridge_port_offload); 844 845void switchdev_bridge_port_unoffload(struct net_device *brport_dev, 846 const void *ctx, 847 struct notifier_block *atomic_nb, 848 struct notifier_block *blocking_nb) 849{ 850 struct switchdev_notifier_brport_info brport_info = { 851 .brport = { 852 .ctx = ctx, 853 .atomic_nb = atomic_nb, 854 .blocking_nb = blocking_nb, 855 }, 856 }; 857 858 ASSERT_RTNL(); 859 860 call_switchdev_blocking_notifiers(SWITCHDEV_BRPORT_UNOFFLOADED, 861 brport_dev, &brport_info.info, 862 NULL); 863} 864EXPORT_SYMBOL_GPL(switchdev_bridge_port_unoffload);