linux/net/bridge/br_switchdev.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/kernel.h>
   3#include <linux/list.h>
   4#include <linux/netdevice.h>
   5#include <linux/rtnetlink.h>
   6#include <linux/skbuff.h>
   7#include <net/ip.h>
   8#include <net/switchdev.h>
   9
  10#include "br_private.h"
  11
  12static struct static_key_false br_switchdev_tx_fwd_offload;
  13
  14static bool nbp_switchdev_can_offload_tx_fwd(const struct net_bridge_port *p,
  15                                             const struct sk_buff *skb)
  16{
  17        if (!static_branch_unlikely(&br_switchdev_tx_fwd_offload))
  18                return false;
  19
  20        return (p->flags & BR_TX_FWD_OFFLOAD) &&
  21               (p->hwdom != BR_INPUT_SKB_CB(skb)->src_hwdom);
  22}
  23
  24bool br_switchdev_frame_uses_tx_fwd_offload(struct sk_buff *skb)
  25{
  26        if (!static_branch_unlikely(&br_switchdev_tx_fwd_offload))
  27                return false;
  28
  29        return BR_INPUT_SKB_CB(skb)->tx_fwd_offload;
  30}
  31
  32void br_switchdev_frame_set_offload_fwd_mark(struct sk_buff *skb)
  33{
  34        skb->offload_fwd_mark = br_switchdev_frame_uses_tx_fwd_offload(skb);
  35}
  36
  37/* Mark the frame for TX forwarding offload if this egress port supports it */
  38void nbp_switchdev_frame_mark_tx_fwd_offload(const struct net_bridge_port *p,
  39                                             struct sk_buff *skb)
  40{
  41        if (nbp_switchdev_can_offload_tx_fwd(p, skb))
  42                BR_INPUT_SKB_CB(skb)->tx_fwd_offload = true;
  43}
  44
  45/* Lazily adds the hwdom of the egress bridge port to the bit mask of hwdoms
  46 * that the skb has been already forwarded to, to avoid further cloning to
  47 * other ports in the same hwdom by making nbp_switchdev_allowed_egress()
  48 * return false.
  49 */
  50void nbp_switchdev_frame_mark_tx_fwd_to_hwdom(const struct net_bridge_port *p,
  51                                              struct sk_buff *skb)
  52{
  53        if (nbp_switchdev_can_offload_tx_fwd(p, skb))
  54                set_bit(p->hwdom, &BR_INPUT_SKB_CB(skb)->fwd_hwdoms);
  55}
  56
  57void nbp_switchdev_frame_mark(const struct net_bridge_port *p,
  58                              struct sk_buff *skb)
  59{
  60        if (p->hwdom)
  61                BR_INPUT_SKB_CB(skb)->src_hwdom = p->hwdom;
  62}
  63
  64bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p,
  65                                  const struct sk_buff *skb)
  66{
  67        struct br_input_skb_cb *cb = BR_INPUT_SKB_CB(skb);
  68
  69        return !test_bit(p->hwdom, &cb->fwd_hwdoms) &&
  70                (!skb->offload_fwd_mark || cb->src_hwdom != p->hwdom);
  71}
  72
  73/* Flags that can be offloaded to hardware */
  74#define BR_PORT_FLAGS_HW_OFFLOAD (BR_LEARNING | BR_FLOOD | \
  75                                  BR_MCAST_FLOOD | BR_BCAST_FLOOD | BR_PORT_LOCKED)
  76
  77int br_switchdev_set_port_flag(struct net_bridge_port *p,
  78                               unsigned long flags,
  79                               unsigned long mask,
  80                               struct netlink_ext_ack *extack)
  81{
  82        struct switchdev_attr attr = {
  83                .orig_dev = p->dev,
  84        };
  85        struct switchdev_notifier_port_attr_info info = {
  86                .attr = &attr,
  87        };
  88        int err;
  89
  90        mask &= BR_PORT_FLAGS_HW_OFFLOAD;
  91        if (!mask)
  92                return 0;
  93
  94        attr.id = SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS;
  95        attr.u.brport_flags.val = flags;
  96        attr.u.brport_flags.mask = mask;
  97
  98        /* We run from atomic context here */
  99        err = call_switchdev_notifiers(SWITCHDEV_PORT_ATTR_SET, p->dev,
 100                                       &info.info, extack);
 101        err = notifier_to_errno(err);
 102        if (err == -EOPNOTSUPP)
 103                return 0;
 104
 105        if (err) {
 106                if (extack && !extack->_msg)
 107                        NL_SET_ERR_MSG_MOD(extack,
 108                                           "bridge flag offload is not supported");
 109                return -EOPNOTSUPP;
 110        }
 111
 112        attr.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS;
 113        attr.flags = SWITCHDEV_F_DEFER;
 114
 115        err = switchdev_port_attr_set(p->dev, &attr, extack);
 116        if (err) {
 117                if (extack && !extack->_msg)
 118                        NL_SET_ERR_MSG_MOD(extack,
 119                                           "error setting offload flag on port");
 120                return err;
 121        }
 122
 123        return 0;
 124}
 125
 126static void br_switchdev_fdb_populate(struct net_bridge *br,
 127                                      struct switchdev_notifier_fdb_info *item,
 128                                      const struct net_bridge_fdb_entry *fdb,
 129                                      const void *ctx)
 130{
 131        const struct net_bridge_port *p = READ_ONCE(fdb->dst);
 132
 133        item->addr = fdb->key.addr.addr;
 134        item->vid = fdb->key.vlan_id;
 135        item->added_by_user = test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
 136        item->offloaded = test_bit(BR_FDB_OFFLOADED, &fdb->flags);
 137        item->is_local = test_bit(BR_FDB_LOCAL, &fdb->flags);
 138        item->info.dev = (!p || item->is_local) ? br->dev : p->dev;
 139        item->info.ctx = ctx;
 140}
 141
 142void
 143br_switchdev_fdb_notify(struct net_bridge *br,
 144                        const struct net_bridge_fdb_entry *fdb, int type)
 145{
 146        struct switchdev_notifier_fdb_info item;
 147
 148        br_switchdev_fdb_populate(br, &item, fdb, NULL);
 149
 150        switch (type) {
 151        case RTM_DELNEIGH:
 152                call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_DEVICE,
 153                                         item.info.dev, &item.info, NULL);
 154                break;
 155        case RTM_NEWNEIGH:
 156                call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_DEVICE,
 157                                         item.info.dev, &item.info, NULL);
 158                break;
 159        }
 160}
 161
 162int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
 163                               bool changed, struct netlink_ext_ack *extack)
 164{
 165        struct switchdev_obj_port_vlan v = {
 166                .obj.orig_dev = dev,
 167                .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
 168                .flags = flags,
 169                .vid = vid,
 170                .changed = changed,
 171        };
 172
 173        return switchdev_port_obj_add(dev, &v.obj, extack);
 174}
 175
 176int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid)
 177{
 178        struct switchdev_obj_port_vlan v = {
 179                .obj.orig_dev = dev,
 180                .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
 181                .vid = vid,
 182        };
 183
 184        return switchdev_port_obj_del(dev, &v.obj);
 185}
 186
 187static int nbp_switchdev_hwdom_set(struct net_bridge_port *joining)
 188{
 189        struct net_bridge *br = joining->br;
 190        struct net_bridge_port *p;
 191        int hwdom;
 192
 193        /* joining is yet to be added to the port list. */
 194        list_for_each_entry(p, &br->port_list, list) {
 195                if (netdev_phys_item_id_same(&joining->ppid, &p->ppid)) {
 196                        joining->hwdom = p->hwdom;
 197                        return 0;
 198                }
 199        }
 200
 201        hwdom = find_next_zero_bit(&br->busy_hwdoms, BR_HWDOM_MAX, 1);
 202        if (hwdom >= BR_HWDOM_MAX)
 203                return -EBUSY;
 204
 205        set_bit(hwdom, &br->busy_hwdoms);
 206        joining->hwdom = hwdom;
 207        return 0;
 208}
 209
 210static void nbp_switchdev_hwdom_put(struct net_bridge_port *leaving)
 211{
 212        struct net_bridge *br = leaving->br;
 213        struct net_bridge_port *p;
 214
 215        /* leaving is no longer in the port list. */
 216        list_for_each_entry(p, &br->port_list, list) {
 217                if (p->hwdom == leaving->hwdom)
 218                        return;
 219        }
 220
 221        clear_bit(leaving->hwdom, &br->busy_hwdoms);
 222}
 223
 224static int nbp_switchdev_add(struct net_bridge_port *p,
 225                             struct netdev_phys_item_id ppid,
 226                             bool tx_fwd_offload,
 227                             struct netlink_ext_ack *extack)
 228{
 229        int err;
 230
 231        if (p->offload_count) {
 232                /* Prevent unsupported configurations such as a bridge port
 233                 * which is a bonding interface, and the member ports are from
 234                 * different hardware switches.
 235                 */
 236                if (!netdev_phys_item_id_same(&p->ppid, &ppid)) {
 237                        NL_SET_ERR_MSG_MOD(extack,
 238                                           "Same bridge port cannot be offloaded by two physical switches");
 239                        return -EBUSY;
 240                }
 241
 242                /* Tolerate drivers that call switchdev_bridge_port_offload()
 243                 * more than once for the same bridge port, such as when the
 244                 * bridge port is an offloaded bonding/team interface.
 245                 */
 246                p->offload_count++;
 247
 248                return 0;
 249        }
 250
 251        p->ppid = ppid;
 252        p->offload_count = 1;
 253
 254        err = nbp_switchdev_hwdom_set(p);
 255        if (err)
 256                return err;
 257
 258        if (tx_fwd_offload) {
 259                p->flags |= BR_TX_FWD_OFFLOAD;
 260                static_branch_inc(&br_switchdev_tx_fwd_offload);
 261        }
 262
 263        return 0;
 264}
 265
 266static void nbp_switchdev_del(struct net_bridge_port *p)
 267{
 268        if (WARN_ON(!p->offload_count))
 269                return;
 270
 271        p->offload_count--;
 272
 273        if (p->offload_count)
 274                return;
 275
 276        if (p->hwdom)
 277                nbp_switchdev_hwdom_put(p);
 278
 279        if (p->flags & BR_TX_FWD_OFFLOAD) {
 280                p->flags &= ~BR_TX_FWD_OFFLOAD;
 281                static_branch_dec(&br_switchdev_tx_fwd_offload);
 282        }
 283}
 284
 285static int
 286br_switchdev_fdb_replay_one(struct net_bridge *br, struct notifier_block *nb,
 287                            const struct net_bridge_fdb_entry *fdb,
 288                            unsigned long action, const void *ctx)
 289{
 290        struct switchdev_notifier_fdb_info item;
 291        int err;
 292
 293        br_switchdev_fdb_populate(br, &item, fdb, ctx);
 294
 295        err = nb->notifier_call(nb, action, &item);
 296        return notifier_to_errno(err);
 297}
 298
 299static int
 300br_switchdev_fdb_replay(const struct net_device *br_dev, const void *ctx,
 301                        bool adding, struct notifier_block *nb)
 302{
 303        struct net_bridge_fdb_entry *fdb;
 304        struct net_bridge *br;
 305        unsigned long action;
 306        int err = 0;
 307
 308        if (!nb)
 309                return 0;
 310
 311        if (!netif_is_bridge_master(br_dev))
 312                return -EINVAL;
 313
 314        br = netdev_priv(br_dev);
 315
 316        if (adding)
 317                action = SWITCHDEV_FDB_ADD_TO_DEVICE;
 318        else
 319                action = SWITCHDEV_FDB_DEL_TO_DEVICE;
 320
 321        rcu_read_lock();
 322
 323        hlist_for_each_entry_rcu(fdb, &br->fdb_list, fdb_node) {
 324                err = br_switchdev_fdb_replay_one(br, nb, fdb, action, ctx);
 325                if (err)
 326                        break;
 327        }
 328
 329        rcu_read_unlock();
 330
 331        return err;
 332}
 333
 334static int br_switchdev_vlan_attr_replay(struct net_device *br_dev,
 335                                         const void *ctx,
 336                                         struct notifier_block *nb,
 337                                         struct netlink_ext_ack *extack)
 338{
 339        struct switchdev_notifier_port_attr_info attr_info = {
 340                .info = {
 341                        .dev = br_dev,
 342                        .extack = extack,
 343                        .ctx = ctx,
 344                },
 345        };
 346        struct net_bridge *br = netdev_priv(br_dev);
 347        struct net_bridge_vlan_group *vg;
 348        struct switchdev_attr attr;
 349        struct net_bridge_vlan *v;
 350        int err;
 351
 352        attr_info.attr = &attr;
 353        attr.orig_dev = br_dev;
 354
 355        vg = br_vlan_group(br);
 356        if (!vg)
 357                return 0;
 358
 359        list_for_each_entry(v, &vg->vlan_list, vlist) {
 360                if (v->msti) {
 361                        attr.id = SWITCHDEV_ATTR_ID_VLAN_MSTI;
 362                        attr.u.vlan_msti.vid = v->vid;
 363                        attr.u.vlan_msti.msti = v->msti;
 364
 365                        err = nb->notifier_call(nb, SWITCHDEV_PORT_ATTR_SET,
 366                                                &attr_info);
 367                        err = notifier_to_errno(err);
 368                        if (err)
 369                                return err;
 370                }
 371        }
 372
 373        return 0;
 374}
 375
 376static int
 377br_switchdev_vlan_replay_one(struct notifier_block *nb,
 378                             struct net_device *dev,
 379                             struct switchdev_obj_port_vlan *vlan,
 380                             const void *ctx, unsigned long action,
 381                             struct netlink_ext_ack *extack)
 382{
 383        struct switchdev_notifier_port_obj_info obj_info = {
 384                .info = {
 385                        .dev = dev,
 386                        .extack = extack,
 387                        .ctx = ctx,
 388                },
 389                .obj = &vlan->obj,
 390        };
 391        int err;
 392
 393        err = nb->notifier_call(nb, action, &obj_info);
 394        return notifier_to_errno(err);
 395}
 396
 397static int br_switchdev_vlan_replay_group(struct notifier_block *nb,
 398                                          struct net_device *dev,
 399                                          struct net_bridge_vlan_group *vg,
 400                                          const void *ctx, unsigned long action,
 401                                          struct netlink_ext_ack *extack)
 402{
 403        struct net_bridge_vlan *v;
 404        int err = 0;
 405        u16 pvid;
 406
 407        if (!vg)
 408                return 0;
 409
 410        pvid = br_get_pvid(vg);
 411
 412        list_for_each_entry(v, &vg->vlan_list, vlist) {
 413                struct switchdev_obj_port_vlan vlan = {
 414                        .obj.orig_dev = dev,
 415                        .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
 416                        .flags = br_vlan_flags(v, pvid),
 417                        .vid = v->vid,
 418                };
 419
 420                if (!br_vlan_should_use(v))
 421                        continue;
 422
 423                err = br_switchdev_vlan_replay_one(nb, dev, &vlan, ctx,
 424                                                   action, extack);
 425                if (err)
 426                        return err;
 427        }
 428
 429        return 0;
 430}
 431
 432static int br_switchdev_vlan_replay(struct net_device *br_dev,
 433                                    const void *ctx, bool adding,
 434                                    struct notifier_block *nb,
 435                                    struct netlink_ext_ack *extack)
 436{
 437        struct net_bridge *br = netdev_priv(br_dev);
 438        struct net_bridge_port *p;
 439        unsigned long action;
 440        int err;
 441
 442        ASSERT_RTNL();
 443
 444        if (!nb)
 445                return 0;
 446
 447        if (!netif_is_bridge_master(br_dev))
 448                return -EINVAL;
 449
 450        if (adding)
 451                action = SWITCHDEV_PORT_OBJ_ADD;
 452        else
 453                action = SWITCHDEV_PORT_OBJ_DEL;
 454
 455        err = br_switchdev_vlan_replay_group(nb, br_dev, br_vlan_group(br),
 456                                             ctx, action, extack);
 457        if (err)
 458                return err;
 459
 460        list_for_each_entry(p, &br->port_list, list) {
 461                struct net_device *dev = p->dev;
 462
 463                err = br_switchdev_vlan_replay_group(nb, dev,
 464                                                     nbp_vlan_group(p),
 465                                                     ctx, action, extack);
 466                if (err)
 467                        return err;
 468        }
 469
 470        if (adding) {
 471                err = br_switchdev_vlan_attr_replay(br_dev, ctx, nb, extack);
 472                if (err)
 473                        return err;
 474        }
 475
 476        return 0;
 477}
 478
 479#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
 480struct br_switchdev_mdb_complete_info {
 481        struct net_bridge_port *port;
 482        struct br_ip ip;
 483};
 484
 485static void br_switchdev_mdb_complete(struct net_device *dev, int err, void *priv)
 486{
 487        struct br_switchdev_mdb_complete_info *data = priv;
 488        struct net_bridge_port_group __rcu **pp;
 489        struct net_bridge_port_group *p;
 490        struct net_bridge_mdb_entry *mp;
 491        struct net_bridge_port *port = data->port;
 492        struct net_bridge *br = port->br;
 493
 494        if (err)
 495                goto err;
 496
 497        spin_lock_bh(&br->multicast_lock);
 498        mp = br_mdb_ip_get(br, &data->ip);
 499        if (!mp)
 500                goto out;
 501        for (pp = &mp->ports; (p = mlock_dereference(*pp, br)) != NULL;
 502             pp = &p->next) {
 503                if (p->key.port != port)
 504                        continue;
 505                p->flags |= MDB_PG_FLAGS_OFFLOAD;
 506        }
 507out:
 508        spin_unlock_bh(&br->multicast_lock);
 509err:
 510        kfree(priv);
 511}
 512
 513static void br_switchdev_mdb_populate(struct switchdev_obj_port_mdb *mdb,
 514                                      const struct net_bridge_mdb_entry *mp)
 515{
 516        if (mp->addr.proto == htons(ETH_P_IP))
 517                ip_eth_mc_map(mp->addr.dst.ip4, mdb->addr);
 518#if IS_ENABLED(CONFIG_IPV6)
 519        else if (mp->addr.proto == htons(ETH_P_IPV6))
 520                ipv6_eth_mc_map(&mp->addr.dst.ip6, mdb->addr);
 521#endif
 522        else
 523                ether_addr_copy(mdb->addr, mp->addr.dst.mac_addr);
 524
 525        mdb->vid = mp->addr.vid;
 526}
 527
 528static void br_switchdev_host_mdb_one(struct net_device *dev,
 529                                      struct net_device *lower_dev,
 530                                      struct net_bridge_mdb_entry *mp,
 531                                      int type)
 532{
 533        struct switchdev_obj_port_mdb mdb = {
 534                .obj = {
 535                        .id = SWITCHDEV_OBJ_ID_HOST_MDB,
 536                        .flags = SWITCHDEV_F_DEFER,
 537                        .orig_dev = dev,
 538                },
 539        };
 540
 541        br_switchdev_mdb_populate(&mdb, mp);
 542
 543        switch (type) {
 544        case RTM_NEWMDB:
 545                switchdev_port_obj_add(lower_dev, &mdb.obj, NULL);
 546                break;
 547        case RTM_DELMDB:
 548                switchdev_port_obj_del(lower_dev, &mdb.obj);
 549                break;
 550        }
 551}
 552
 553static void br_switchdev_host_mdb(struct net_device *dev,
 554                                  struct net_bridge_mdb_entry *mp, int type)
 555{
 556        struct net_device *lower_dev;
 557        struct list_head *iter;
 558
 559        netdev_for_each_lower_dev(dev, lower_dev, iter)
 560                br_switchdev_host_mdb_one(dev, lower_dev, mp, type);
 561}
 562
 563static int
 564br_switchdev_mdb_replay_one(struct notifier_block *nb, struct net_device *dev,
 565                            const struct switchdev_obj_port_mdb *mdb,
 566                            unsigned long action, const void *ctx,
 567                            struct netlink_ext_ack *extack)
 568{
 569        struct switchdev_notifier_port_obj_info obj_info = {
 570                .info = {
 571                        .dev = dev,
 572                        .extack = extack,
 573                        .ctx = ctx,
 574                },
 575                .obj = &mdb->obj,
 576        };
 577        int err;
 578
 579        err = nb->notifier_call(nb, action, &obj_info);
 580        return notifier_to_errno(err);
 581}
 582
 583static int br_switchdev_mdb_queue_one(struct list_head *mdb_list,
 584                                      enum switchdev_obj_id id,
 585                                      const struct net_bridge_mdb_entry *mp,
 586                                      struct net_device *orig_dev)
 587{
 588        struct switchdev_obj_port_mdb *mdb;
 589
 590        mdb = kzalloc(sizeof(*mdb), GFP_ATOMIC);
 591        if (!mdb)
 592                return -ENOMEM;
 593
 594        mdb->obj.id = id;
 595        mdb->obj.orig_dev = orig_dev;
 596        br_switchdev_mdb_populate(mdb, mp);
 597        list_add_tail(&mdb->obj.list, mdb_list);
 598
 599        return 0;
 600}
 601
 602void br_switchdev_mdb_notify(struct net_device *dev,
 603                             struct net_bridge_mdb_entry *mp,
 604                             struct net_bridge_port_group *pg,
 605                             int type)
 606{
 607        struct br_switchdev_mdb_complete_info *complete_info;
 608        struct switchdev_obj_port_mdb mdb = {
 609                .obj = {
 610                        .id = SWITCHDEV_OBJ_ID_PORT_MDB,
 611                        .flags = SWITCHDEV_F_DEFER,
 612                },
 613        };
 614
 615        if (!pg)
 616                return br_switchdev_host_mdb(dev, mp, type);
 617
 618        br_switchdev_mdb_populate(&mdb, mp);
 619
 620        mdb.obj.orig_dev = pg->key.port->dev;
 621        switch (type) {
 622        case RTM_NEWMDB:
 623                complete_info = kmalloc(sizeof(*complete_info), GFP_ATOMIC);
 624                if (!complete_info)
 625                        break;
 626                complete_info->port = pg->key.port;
 627                complete_info->ip = mp->addr;
 628                mdb.obj.complete_priv = complete_info;
 629                mdb.obj.complete = br_switchdev_mdb_complete;
 630                if (switchdev_port_obj_add(pg->key.port->dev, &mdb.obj, NULL))
 631                        kfree(complete_info);
 632                break;
 633        case RTM_DELMDB:
 634                switchdev_port_obj_del(pg->key.port->dev, &mdb.obj);
 635                break;
 636        }
 637}
 638#endif
 639
 640static int
 641br_switchdev_mdb_replay(struct net_device *br_dev, struct net_device *dev,
 642                        const void *ctx, bool adding, struct notifier_block *nb,
 643                        struct netlink_ext_ack *extack)
 644{
 645#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
 646        const struct net_bridge_mdb_entry *mp;
 647        struct switchdev_obj *obj, *tmp;
 648        struct net_bridge *br;
 649        unsigned long action;
 650        LIST_HEAD(mdb_list);
 651        int err = 0;
 652
 653        ASSERT_RTNL();
 654
 655        if (!nb)
 656                return 0;
 657
 658        if (!netif_is_bridge_master(br_dev) || !netif_is_bridge_port(dev))
 659                return -EINVAL;
 660
 661        br = netdev_priv(br_dev);
 662
 663        if (!br_opt_get(br, BROPT_MULTICAST_ENABLED))
 664                return 0;
 665
 666        /* We cannot walk over br->mdb_list protected just by the rtnl_mutex,
 667         * because the write-side protection is br->multicast_lock. But we
 668         * need to emulate the [ blocking ] calling context of a regular
 669         * switchdev event, so since both br->multicast_lock and RCU read side
 670         * critical sections are atomic, we have no choice but to pick the RCU
 671         * read side lock, queue up all our events, leave the critical section
 672         * and notify switchdev from blocking context.
 673         */
 674        rcu_read_lock();
 675
 676        hlist_for_each_entry_rcu(mp, &br->mdb_list, mdb_node) {
 677                struct net_bridge_port_group __rcu * const *pp;
 678                const struct net_bridge_port_group *p;
 679
 680                if (mp->host_joined) {
 681                        err = br_switchdev_mdb_queue_one(&mdb_list,
 682                                                         SWITCHDEV_OBJ_ID_HOST_MDB,
 683                                                         mp, br_dev);
 684                        if (err) {
 685                                rcu_read_unlock();
 686                                goto out_free_mdb;
 687                        }
 688                }
 689
 690                for (pp = &mp->ports; (p = rcu_dereference(*pp)) != NULL;
 691                     pp = &p->next) {
 692                        if (p->key.port->dev != dev)
 693                                continue;
 694
 695                        err = br_switchdev_mdb_queue_one(&mdb_list,
 696                                                         SWITCHDEV_OBJ_ID_PORT_MDB,
 697                                                         mp, dev);
 698                        if (err) {
 699                                rcu_read_unlock();
 700                                goto out_free_mdb;
 701                        }
 702                }
 703        }
 704
 705        rcu_read_unlock();
 706
 707        if (adding)
 708                action = SWITCHDEV_PORT_OBJ_ADD;
 709        else
 710                action = SWITCHDEV_PORT_OBJ_DEL;
 711
 712        list_for_each_entry(obj, &mdb_list, list) {
 713                err = br_switchdev_mdb_replay_one(nb, dev,
 714                                                  SWITCHDEV_OBJ_PORT_MDB(obj),
 715                                                  action, ctx, extack);
 716                if (err)
 717                        goto out_free_mdb;
 718        }
 719
 720out_free_mdb:
 721        list_for_each_entry_safe(obj, tmp, &mdb_list, list) {
 722                list_del(&obj->list);
 723                kfree(SWITCHDEV_OBJ_PORT_MDB(obj));
 724        }
 725
 726        if (err)
 727                return err;
 728#endif
 729
 730        return 0;
 731}
 732
 733static int nbp_switchdev_sync_objs(struct net_bridge_port *p, const void *ctx,
 734                                   struct notifier_block *atomic_nb,
 735                                   struct notifier_block *blocking_nb,
 736                                   struct netlink_ext_ack *extack)
 737{
 738        struct net_device *br_dev = p->br->dev;
 739        struct net_device *dev = p->dev;
 740        int err;
 741
 742        err = br_switchdev_vlan_replay(br_dev, ctx, true, blocking_nb, extack);
 743        if (err && err != -EOPNOTSUPP)
 744                return err;
 745
 746        err = br_switchdev_mdb_replay(br_dev, dev, ctx, true, blocking_nb,
 747                                      extack);
 748        if (err && err != -EOPNOTSUPP)
 749                return err;
 750
 751        err = br_switchdev_fdb_replay(br_dev, ctx, true, atomic_nb);
 752        if (err && err != -EOPNOTSUPP)
 753                return err;
 754
 755        return 0;
 756}
 757
 758static void nbp_switchdev_unsync_objs(struct net_bridge_port *p,
 759                                      const void *ctx,
 760                                      struct notifier_block *atomic_nb,
 761                                      struct notifier_block *blocking_nb)
 762{
 763        struct net_device *br_dev = p->br->dev;
 764        struct net_device *dev = p->dev;
 765
 766        br_switchdev_fdb_replay(br_dev, ctx, false, atomic_nb);
 767
 768        br_switchdev_mdb_replay(br_dev, dev, ctx, false, blocking_nb, NULL);
 769
 770        br_switchdev_vlan_replay(br_dev, ctx, false, blocking_nb, NULL);
 771}
 772
 773/* Let the bridge know that this port is offloaded, so that it can assign a
 774 * switchdev hardware domain to it.
 775 */
 776int br_switchdev_port_offload(struct net_bridge_port *p,
 777                              struct net_device *dev, const void *ctx,
 778                              struct notifier_block *atomic_nb,
 779                              struct notifier_block *blocking_nb,
 780                              bool tx_fwd_offload,
 781                              struct netlink_ext_ack *extack)
 782{
 783        struct netdev_phys_item_id ppid;
 784        int err;
 785
 786        err = dev_get_port_parent_id(dev, &ppid, false);
 787        if (err)
 788                return err;
 789
 790        err = nbp_switchdev_add(p, ppid, tx_fwd_offload, extack);
 791        if (err)
 792                return err;
 793
 794        err = nbp_switchdev_sync_objs(p, ctx, atomic_nb, blocking_nb, extack);
 795        if (err)
 796                goto out_switchdev_del;
 797
 798        return 0;
 799
 800out_switchdev_del:
 801        nbp_switchdev_del(p);
 802
 803        return err;
 804}
 805
 806void br_switchdev_port_unoffload(struct net_bridge_port *p, const void *ctx,
 807                                 struct notifier_block *atomic_nb,
 808                                 struct notifier_block *blocking_nb)
 809{
 810        nbp_switchdev_unsync_objs(p, ctx, atomic_nb, blocking_nb);
 811
 812        nbp_switchdev_del(p);
 813}
 814