Loading net/bridge/br_fdb.c +12 −13 Original line number Diff line number Diff line Loading @@ -225,7 +225,7 @@ static void fdb_delete_local(struct net_bridge *br, if (op != p && ether_addr_equal(op->dev->dev_addr, addr) && (!vid || br_vlan_find(vg, vid))) { f->dst = op; f->added_by_user = 0; clear_bit(BR_FDB_ADDED_BY_USER, &f->flags); return; } } Loading @@ -236,7 +236,7 @@ static void fdb_delete_local(struct net_bridge *br, if (p && ether_addr_equal(br->dev->dev_addr, addr) && (!vid || (v && br_vlan_should_use(v)))) { f->dst = NULL; f->added_by_user = 0; clear_bit(BR_FDB_ADDED_BY_USER, &f->flags); return; } Loading @@ -252,7 +252,7 @@ void br_fdb_find_delete_local(struct net_bridge *br, spin_lock_bh(&br->hash_lock); f = br_fdb_find(br, addr, vid); if (f && test_bit(BR_FDB_LOCAL, &f->flags) && !f->added_by_user && f->dst == p) !test_bit(BR_FDB_ADDED_BY_USER, &f->flags) && f->dst == p) fdb_delete_local(br, p, f); spin_unlock_bh(&br->hash_lock); } Loading @@ -268,7 +268,7 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) vg = nbp_vlan_group(p); hlist_for_each_entry(f, &br->fdb_list, fdb_node) { if (f->dst == p && test_bit(BR_FDB_LOCAL, &f->flags) && !f->added_by_user) { !test_bit(BR_FDB_ADDED_BY_USER, &f->flags)) { /* delete old one */ fdb_delete_local(br, p, f); Loading Loading @@ -310,7 +310,7 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr) /* If old entry was unassociated with any port, then delete it. */ f = br_fdb_find(br, br->dev->dev_addr, 0); if (f && test_bit(BR_FDB_LOCAL, &f->flags) && !f->dst && !f->added_by_user) !f->dst && !test_bit(BR_FDB_ADDED_BY_USER, &f->flags)) fdb_delete_local(br, NULL, f); fdb_insert(br, NULL, newaddr, 0); Loading @@ -326,7 +326,7 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr) continue; f = br_fdb_find(br, br->dev->dev_addr, v->vid); if (f && test_bit(BR_FDB_LOCAL, &f->flags) && !f->dst && !f->added_by_user) !f->dst && !test_bit(BR_FDB_ADDED_BY_USER, &f->flags)) fdb_delete_local(br, NULL, f); fdb_insert(br, NULL, newaddr, v->vid); } Loading Loading @@ -506,7 +506,6 @@ static struct net_bridge_fdb_entry *fdb_create(struct net_bridge *br, set_bit(BR_FDB_LOCAL, &fdb->flags); if (is_static) set_bit(BR_FDB_STATIC, &fdb->flags); fdb->added_by_user = 0; fdb->added_by_external_learn = 0; fdb->offloaded = 0; fdb->updated = fdb->used = jiffies; Loading Loading @@ -600,7 +599,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, if (now != fdb->updated) fdb->updated = now; if (unlikely(added_by_user)) fdb->added_by_user = 1; set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); if (unlikely(fdb_modified)) { trace_br_fdb_update(br, source, addr, vid, added_by_user); fdb_notify(br, fdb, RTM_NEWNEIGH, true); Loading @@ -611,7 +610,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, fdb = fdb_create(br, source, addr, vid, 0, 0); if (fdb) { if (unlikely(added_by_user)) fdb->added_by_user = 1; set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); trace_br_fdb_update(br, source, addr, vid, added_by_user); fdb_notify(br, fdb, RTM_NEWNEIGH, true); Loading Loading @@ -871,7 +870,7 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source, modified = true; } fdb->added_by_user = 1; set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); fdb->used = jiffies; if (modified) { Loading Loading @@ -1129,7 +1128,7 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, goto err_unlock; } if (swdev_notify) fdb->added_by_user = 1; set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); fdb->added_by_external_learn = 1; fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify); } else { Loading @@ -1143,14 +1142,14 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, if (fdb->added_by_external_learn) { /* Refresh entry */ fdb->used = jiffies; } else if (!fdb->added_by_user) { } else if (!test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags)) { /* Take over SW learned entry */ fdb->added_by_external_learn = 1; modified = true; } if (swdev_notify) fdb->added_by_user = 1; set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); if (modified) fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify); Loading net/bridge/br_private.h +2 −2 Original line number Diff line number Diff line Loading @@ -177,6 +177,7 @@ enum { BR_FDB_LOCAL, BR_FDB_STATIC, BR_FDB_STICKY, BR_FDB_ADDED_BY_USER, }; struct net_bridge_fdb_key { Loading @@ -191,8 +192,7 @@ struct net_bridge_fdb_entry { struct net_bridge_fdb_key key; struct hlist_node fdb_node; unsigned long flags; unsigned char added_by_user:1, added_by_external_learn:1, unsigned char added_by_external_learn:1, offloaded:1; /* write-heavy members should not affect lookups */ Loading net/bridge/br_switchdev.c +4 −2 Original line number Diff line number Diff line Loading @@ -129,14 +129,16 @@ br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type) br_switchdev_fdb_call_notifiers(false, fdb->key.addr.addr, fdb->key.vlan_id, fdb->dst->dev, fdb->added_by_user, test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags), fdb->offloaded); break; case RTM_NEWNEIGH: br_switchdev_fdb_call_notifiers(true, fdb->key.addr.addr, fdb->key.vlan_id, fdb->dst->dev, fdb->added_by_user, test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags), fdb->offloaded); break; } Loading Loading
net/bridge/br_fdb.c +12 −13 Original line number Diff line number Diff line Loading @@ -225,7 +225,7 @@ static void fdb_delete_local(struct net_bridge *br, if (op != p && ether_addr_equal(op->dev->dev_addr, addr) && (!vid || br_vlan_find(vg, vid))) { f->dst = op; f->added_by_user = 0; clear_bit(BR_FDB_ADDED_BY_USER, &f->flags); return; } } Loading @@ -236,7 +236,7 @@ static void fdb_delete_local(struct net_bridge *br, if (p && ether_addr_equal(br->dev->dev_addr, addr) && (!vid || (v && br_vlan_should_use(v)))) { f->dst = NULL; f->added_by_user = 0; clear_bit(BR_FDB_ADDED_BY_USER, &f->flags); return; } Loading @@ -252,7 +252,7 @@ void br_fdb_find_delete_local(struct net_bridge *br, spin_lock_bh(&br->hash_lock); f = br_fdb_find(br, addr, vid); if (f && test_bit(BR_FDB_LOCAL, &f->flags) && !f->added_by_user && f->dst == p) !test_bit(BR_FDB_ADDED_BY_USER, &f->flags) && f->dst == p) fdb_delete_local(br, p, f); spin_unlock_bh(&br->hash_lock); } Loading @@ -268,7 +268,7 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) vg = nbp_vlan_group(p); hlist_for_each_entry(f, &br->fdb_list, fdb_node) { if (f->dst == p && test_bit(BR_FDB_LOCAL, &f->flags) && !f->added_by_user) { !test_bit(BR_FDB_ADDED_BY_USER, &f->flags)) { /* delete old one */ fdb_delete_local(br, p, f); Loading Loading @@ -310,7 +310,7 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr) /* If old entry was unassociated with any port, then delete it. */ f = br_fdb_find(br, br->dev->dev_addr, 0); if (f && test_bit(BR_FDB_LOCAL, &f->flags) && !f->dst && !f->added_by_user) !f->dst && !test_bit(BR_FDB_ADDED_BY_USER, &f->flags)) fdb_delete_local(br, NULL, f); fdb_insert(br, NULL, newaddr, 0); Loading @@ -326,7 +326,7 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr) continue; f = br_fdb_find(br, br->dev->dev_addr, v->vid); if (f && test_bit(BR_FDB_LOCAL, &f->flags) && !f->dst && !f->added_by_user) !f->dst && !test_bit(BR_FDB_ADDED_BY_USER, &f->flags)) fdb_delete_local(br, NULL, f); fdb_insert(br, NULL, newaddr, v->vid); } Loading Loading @@ -506,7 +506,6 @@ static struct net_bridge_fdb_entry *fdb_create(struct net_bridge *br, set_bit(BR_FDB_LOCAL, &fdb->flags); if (is_static) set_bit(BR_FDB_STATIC, &fdb->flags); fdb->added_by_user = 0; fdb->added_by_external_learn = 0; fdb->offloaded = 0; fdb->updated = fdb->used = jiffies; Loading Loading @@ -600,7 +599,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, if (now != fdb->updated) fdb->updated = now; if (unlikely(added_by_user)) fdb->added_by_user = 1; set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); if (unlikely(fdb_modified)) { trace_br_fdb_update(br, source, addr, vid, added_by_user); fdb_notify(br, fdb, RTM_NEWNEIGH, true); Loading @@ -611,7 +610,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, fdb = fdb_create(br, source, addr, vid, 0, 0); if (fdb) { if (unlikely(added_by_user)) fdb->added_by_user = 1; set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); trace_br_fdb_update(br, source, addr, vid, added_by_user); fdb_notify(br, fdb, RTM_NEWNEIGH, true); Loading Loading @@ -871,7 +870,7 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source, modified = true; } fdb->added_by_user = 1; set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); fdb->used = jiffies; if (modified) { Loading Loading @@ -1129,7 +1128,7 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, goto err_unlock; } if (swdev_notify) fdb->added_by_user = 1; set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); fdb->added_by_external_learn = 1; fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify); } else { Loading @@ -1143,14 +1142,14 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, if (fdb->added_by_external_learn) { /* Refresh entry */ fdb->used = jiffies; } else if (!fdb->added_by_user) { } else if (!test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags)) { /* Take over SW learned entry */ fdb->added_by_external_learn = 1; modified = true; } if (swdev_notify) fdb->added_by_user = 1; set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); if (modified) fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify); Loading
net/bridge/br_private.h +2 −2 Original line number Diff line number Diff line Loading @@ -177,6 +177,7 @@ enum { BR_FDB_LOCAL, BR_FDB_STATIC, BR_FDB_STICKY, BR_FDB_ADDED_BY_USER, }; struct net_bridge_fdb_key { Loading @@ -191,8 +192,7 @@ struct net_bridge_fdb_entry { struct net_bridge_fdb_key key; struct hlist_node fdb_node; unsigned long flags; unsigned char added_by_user:1, added_by_external_learn:1, unsigned char added_by_external_learn:1, offloaded:1; /* write-heavy members should not affect lookups */ Loading
net/bridge/br_switchdev.c +4 −2 Original line number Diff line number Diff line Loading @@ -129,14 +129,16 @@ br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type) br_switchdev_fdb_call_notifiers(false, fdb->key.addr.addr, fdb->key.vlan_id, fdb->dst->dev, fdb->added_by_user, test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags), fdb->offloaded); break; case RTM_NEWNEIGH: br_switchdev_fdb_call_notifiers(true, fdb->key.addr.addr, fdb->key.vlan_id, fdb->dst->dev, fdb->added_by_user, test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags), fdb->offloaded); break; } Loading