Lines Matching refs:br

50 int br_fdb_hash_init(struct net_bridge *br)  in br_fdb_hash_init()  argument
52 return rhashtable_init(&br->fdb_hash_tbl, &br_fdb_rht_params); in br_fdb_hash_init()
55 void br_fdb_hash_fini(struct net_bridge *br) in br_fdb_hash_fini() argument
57 rhashtable_destroy(&br->fdb_hash_tbl); in br_fdb_hash_fini()
63 static inline unsigned long hold_time(const struct net_bridge *br) in hold_time() argument
65 return br->topology_change ? br->forward_delay : br->ageing_time; in hold_time()
68 static inline int has_expired(const struct net_bridge *br, in has_expired() argument
73 time_before_eq(READ_ONCE(fdb->updated) + hold_time(br), jiffies); in has_expired()
76 static int fdb_to_nud(const struct net_bridge *br, in fdb_to_nud() argument
83 else if (has_expired(br, fdb)) in fdb_to_nud()
89 static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br, in fdb_fill_info() argument
110 ndm->ndm_ifindex = dst ? dst->dev->ifindex : br->dev->ifindex; in fdb_fill_info()
111 ndm->ndm_state = fdb_to_nud(br, fdb); in fdb_fill_info()
124 if (nla_put_u32(skb, NDA_MASTER, br->dev->ifindex)) in fdb_fill_info()
177 static void fdb_notify(struct net_bridge *br, in fdb_notify() argument
181 struct net *net = dev_net(br->dev); in fdb_notify()
186 br_switchdev_fdb_notify(br, fdb, type); in fdb_notify()
192 err = fdb_fill_info(skb, br, fdb, 0, 0, type, 0); in fdb_notify()
220 static struct net_bridge_fdb_entry *br_fdb_find(struct net_bridge *br, in br_fdb_find() argument
226 lockdep_assert_held_once(&br->hash_lock); in br_fdb_find()
229 fdb = fdb_find_rcu(&br->fdb_hash_tbl, addr, vid); in br_fdb_find()
241 struct net_bridge *br; in br_fdb_find_port() local
248 br = netdev_priv(br_dev); in br_fdb_find_port()
250 f = br_fdb_find_rcu(br, addr, vid); in br_fdb_find_port()
259 struct net_bridge_fdb_entry *br_fdb_find_rcu(struct net_bridge *br, in br_fdb_find_rcu() argument
263 return fdb_find_rcu(&br->fdb_hash_tbl, addr, vid); in br_fdb_find_rcu()
271 static void fdb_add_hw_addr(struct net_bridge *br, const unsigned char *addr) in fdb_add_hw_addr() argument
278 list_for_each_entry(p, &br->port_list, list) { in fdb_add_hw_addr()
288 list_for_each_entry_continue_reverse(p, &br->port_list, list) { in fdb_add_hw_addr()
299 static void fdb_del_hw_addr(struct net_bridge *br, const unsigned char *addr) in fdb_del_hw_addr() argument
305 list_for_each_entry(p, &br->port_list, list) { in fdb_del_hw_addr()
311 static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f, in fdb_delete() argument
314 trace_fdb_delete(br, f); in fdb_delete()
317 fdb_del_hw_addr(br, f->key.addr.addr); in fdb_delete()
320 rhashtable_remove_fast(&br->fdb_hash_tbl, &f->rhnode, in fdb_delete()
323 atomic_dec(&br->fdb_n_learned); in fdb_delete()
324 fdb_notify(br, f, RTM_DELNEIGH, swdev_notify); in fdb_delete()
334 static void fdb_delete_local(struct net_bridge *br, in fdb_delete_local() argument
345 list_for_each_entry(op, &br->port_list, list) { in fdb_delete_local()
355 vg = br_vlan_group(br); in fdb_delete_local()
358 if (p && ether_addr_equal(br->dev->dev_addr, addr) && in fdb_delete_local()
365 fdb_delete(br, f, true); in fdb_delete_local()
368 void br_fdb_find_delete_local(struct net_bridge *br, in br_fdb_find_delete_local() argument
374 spin_lock_bh(&br->hash_lock); in br_fdb_find_delete_local()
375 f = br_fdb_find(br, addr, vid); in br_fdb_find_delete_local()
378 fdb_delete_local(br, p, f); in br_fdb_find_delete_local()
379 spin_unlock_bh(&br->hash_lock); in br_fdb_find_delete_local()
382 static struct net_bridge_fdb_entry *fdb_create(struct net_bridge *br, in fdb_create() argument
390 u32 max_learned = READ_ONCE(br->fdb_max_learned); in fdb_create()
395 int n_learned = atomic_read(&br->fdb_n_learned); in fdb_create()
411 err = rhashtable_lookup_insert_fast(&br->fdb_hash_tbl, &fdb->rhnode, in fdb_create()
419 atomic_inc(&br->fdb_n_learned); in fdb_create()
421 hlist_add_head_rcu(&fdb->fdb_node, &br->fdb_list); in fdb_create()
426 static int fdb_add_local(struct net_bridge *br, struct net_bridge_port *source, in fdb_add_local() argument
434 fdb = br_fdb_find(br, addr, vid); in fdb_add_local()
441 br_warn(br, "adding interface %s with same address as a received packet (addr:%pM, vlan:%u)\n", in fdb_add_local()
442 source ? source->dev->name : br->dev->name, addr, vid); in fdb_add_local()
443 fdb_delete(br, fdb, true); in fdb_add_local()
446 fdb = fdb_create(br, source, addr, vid, in fdb_add_local()
451 fdb_add_hw_addr(br, addr); in fdb_add_local()
452 fdb_notify(br, fdb, RTM_NEWNEIGH, true); in fdb_add_local()
460 struct net_bridge *br = p->br; in br_fdb_changeaddr() local
464 local_vlan_0 = br_opt_get(br, BROPT_FDB_LOCAL_VLAN_0); in br_fdb_changeaddr()
466 spin_lock_bh(&br->hash_lock); in br_fdb_changeaddr()
468 hlist_for_each_entry(f, &br->fdb_list, fdb_node) { in br_fdb_changeaddr()
472 fdb_delete_local(br, p, f); in br_fdb_changeaddr()
485 fdb_add_local(br, p, newaddr, 0); in br_fdb_changeaddr()
495 fdb_add_local(br, p, newaddr, v->vid); in br_fdb_changeaddr()
498 spin_unlock_bh(&br->hash_lock); in br_fdb_changeaddr()
501 void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr) in br_fdb_change_mac_address() argument
508 local_vlan_0 = br_opt_get(br, BROPT_FDB_LOCAL_VLAN_0); in br_fdb_change_mac_address()
510 spin_lock_bh(&br->hash_lock); in br_fdb_change_mac_address()
513 f = br_fdb_find(br, br->dev->dev_addr, 0); in br_fdb_change_mac_address()
516 fdb_delete_local(br, NULL, f); in br_fdb_change_mac_address()
518 fdb_add_local(br, NULL, newaddr, 0); in br_fdb_change_mac_address()
519 vg = br_vlan_group(br); in br_fdb_change_mac_address()
529 f = br_fdb_find(br, br->dev->dev_addr, v->vid); in br_fdb_change_mac_address()
532 fdb_delete_local(br, NULL, f); in br_fdb_change_mac_address()
533 fdb_add_local(br, NULL, newaddr, v->vid); in br_fdb_change_mac_address()
536 spin_unlock_bh(&br->hash_lock); in br_fdb_change_mac_address()
541 struct net_bridge *br = container_of(work, struct net_bridge, in br_fdb_cleanup() local
544 unsigned long delay = hold_time(br); in br_fdb_cleanup()
553 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) { in br_fdb_cleanup()
564 fdb_notify(br, f, RTM_NEWNEIGH, false); in br_fdb_cleanup()
572 spin_lock_bh(&br->hash_lock); in br_fdb_cleanup()
574 fdb_delete(br, f, true); in br_fdb_cleanup()
575 spin_unlock_bh(&br->hash_lock); in br_fdb_cleanup()
582 mod_delayed_work(system_long_wq, &br->gc_work, work_delay); in br_fdb_cleanup()
585 static void br_fdb_delete_locals_per_vlan_port(struct net_bridge *br, in br_fdb_delete_locals_per_vlan_port() argument
596 vg = br_vlan_group(br); in br_fdb_delete_locals_per_vlan_port()
597 dev = br->dev; in br_fdb_delete_locals_per_vlan_port()
601 br_fdb_find_delete_local(br, p, dev->dev_addr, v->vid); in br_fdb_delete_locals_per_vlan_port()
604 static void br_fdb_delete_locals_per_vlan(struct net_bridge *br) in br_fdb_delete_locals_per_vlan() argument
610 list_for_each_entry(p, &br->port_list, list) in br_fdb_delete_locals_per_vlan()
611 br_fdb_delete_locals_per_vlan_port(br, p); in br_fdb_delete_locals_per_vlan()
613 br_fdb_delete_locals_per_vlan_port(br, NULL); in br_fdb_delete_locals_per_vlan()
616 static int br_fdb_insert_locals_per_vlan_port(struct net_bridge *br, in br_fdb_insert_locals_per_vlan_port() argument
629 vg = br_vlan_group(br); in br_fdb_insert_locals_per_vlan_port()
630 dev = br->dev; in br_fdb_insert_locals_per_vlan_port()
637 err = br_fdb_add_local(br, p, dev->dev_addr, v->vid); in br_fdb_insert_locals_per_vlan_port()
645 static int br_fdb_insert_locals_per_vlan(struct net_bridge *br, in br_fdb_insert_locals_per_vlan() argument
653 list_for_each_entry(p, &br->port_list, list) { in br_fdb_insert_locals_per_vlan()
654 err = br_fdb_insert_locals_per_vlan_port(br, p, extack); in br_fdb_insert_locals_per_vlan()
659 err = br_fdb_insert_locals_per_vlan_port(br, NULL, extack); in br_fdb_insert_locals_per_vlan()
667 br_fdb_delete_locals_per_vlan(br); in br_fdb_insert_locals_per_vlan()
671 int br_fdb_toggle_local_vlan_0(struct net_bridge *br, bool on, in br_fdb_toggle_local_vlan_0() argument
675 return br_fdb_insert_locals_per_vlan(br, extack); in br_fdb_toggle_local_vlan_0()
677 br_fdb_delete_locals_per_vlan(br); in br_fdb_toggle_local_vlan_0()
681 static bool __fdb_flush_matches(const struct net_bridge *br, in __fdb_flush_matches() argument
686 int port_ifidx = dst ? dst->dev->ifindex : br->dev->ifindex; in __fdb_flush_matches()
699 void br_fdb_flush(struct net_bridge *br, in br_fdb_flush() argument
705 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) { in br_fdb_flush()
706 if (!__fdb_flush_matches(br, f, desc)) in br_fdb_flush()
709 spin_lock_bh(&br->hash_lock); in br_fdb_flush()
711 fdb_delete(br, f, true); in br_fdb_flush()
712 spin_unlock_bh(&br->hash_lock); in br_fdb_flush()
745 static int __fdb_flush_validate_ifindex(const struct net_bridge *br, in __fdb_flush_validate_ifindex() argument
751 dev = __dev_get_by_index(dev_net(br->dev), ifindex); in __fdb_flush_validate_ifindex()
760 if (netif_is_bridge_master(dev) && dev != br->dev) { in __fdb_flush_validate_ifindex()
768 if (p->br != br) { in __fdb_flush_validate_ifindex()
791 struct net_bridge *br; in br_fdb_delete_bulk() local
803 br = netdev_priv(dev); in br_fdb_delete_bulk()
810 br = p->br; in br_fdb_delete_bulk()
840 err = __fdb_flush_validate_ifindex(br, ifidx, extack); in br_fdb_delete_bulk()
849 br_debug(br, "flushing port ifindex: %d vlan id: %u flags: 0x%lx flags mask: 0x%lx\n", in br_fdb_delete_bulk()
852 br_fdb_flush(br, &desc); in br_fdb_delete_bulk()
861 void br_fdb_delete_by_port(struct net_bridge *br, in br_fdb_delete_by_port() argument
869 spin_lock_bh(&br->hash_lock); in br_fdb_delete_by_port()
870 hlist_for_each_entry_safe(f, tmp, &br->fdb_list, fdb_node) { in br_fdb_delete_by_port()
882 fdb_delete_local(br, p, f); in br_fdb_delete_by_port()
884 fdb_delete(br, f, true); in br_fdb_delete_by_port()
886 spin_unlock_bh(&br->hash_lock); in br_fdb_delete_by_port()
905 fdb = br_fdb_find_rcu(port->br, addr, 0); in br_fdb_test_addr()
922 int br_fdb_fillbuf(struct net_bridge *br, void *buf, in br_fdb_fillbuf() argument
933 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) { in br_fdb_fillbuf()
937 if (has_expired(br, f)) in br_fdb_fillbuf()
971 int br_fdb_add_local(struct net_bridge *br, struct net_bridge_port *source, in br_fdb_add_local() argument
976 spin_lock_bh(&br->hash_lock); in br_fdb_add_local()
977 ret = fdb_add_local(br, source, addr, vid); in br_fdb_add_local()
978 spin_unlock_bh(&br->hash_lock); in br_fdb_add_local()
989 void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, in br_fdb_update() argument
995 if (hold_time(br) == 0) in br_fdb_update()
998 fdb = fdb_find_rcu(&br->fdb_hash_tbl, addr, vid); in br_fdb_update()
1003 br_warn(br, "received packet on %s with own address as source address (addr:%pM, vlan:%u)\n", in br_fdb_update()
1017 br_switchdev_fdb_notify(br, fdb, RTM_DELNEIGH); in br_fdb_update()
1036 atomic_dec(&br->fdb_n_learned); in br_fdb_update()
1039 trace_br_fdb_update(br, source, addr, vid, flags); in br_fdb_update()
1040 fdb_notify(br, fdb, RTM_NEWNEIGH, true); in br_fdb_update()
1044 spin_lock(&br->hash_lock); in br_fdb_update()
1045 fdb = fdb_create(br, source, addr, vid, flags); in br_fdb_update()
1047 trace_br_fdb_update(br, source, addr, vid, flags); in br_fdb_update()
1048 fdb_notify(br, fdb, RTM_NEWNEIGH, true); in br_fdb_update()
1053 spin_unlock(&br->hash_lock); in br_fdb_update()
1065 struct net_bridge *br = netdev_priv(dev); in br_fdb_dump() local
1079 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) { in br_fdb_dump()
1096 err = fdb_fill_info(skb, br, f, in br_fdb_dump()
1118 struct net_bridge *br = netdev_priv(dev); in br_fdb_get() local
1123 f = br_fdb_find_rcu(br, addr, vid); in br_fdb_get()
1130 err = fdb_fill_info(skb, br, f, portid, seq, in br_fdb_get()
1162 static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source, in fdb_add_entry() argument
1181 br->dev->name); in fdb_add_entry()
1195 fdb = br_fdb_find(br, addr, vid); in fdb_add_entry()
1200 fdb = fdb_create(br, source, addr, vid, in fdb_add_entry()
1217 atomic_dec(&br->fdb_n_learned); in fdb_add_entry()
1220 if (fdb_to_nud(br, fdb) != state) { in fdb_add_entry()
1224 fdb_add_hw_addr(br, addr); in fdb_add_entry()
1228 fdb_add_hw_addr(br, addr); in fdb_add_entry()
1232 fdb_del_hw_addr(br, addr); in fdb_add_entry()
1253 fdb_notify(br, fdb, RTM_NEWNEIGH, true); in fdb_add_entry()
1259 static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge *br, in __br_fdb_add() argument
1269 br->dev->name); in __br_fdb_add()
1277 br_fdb_update(br, p, addr, vid, BIT(BR_FDB_ADDED_BY_USER)); in __br_fdb_add()
1286 err = br_fdb_external_learn_add(br, p, addr, vid, false, true); in __br_fdb_add()
1288 spin_lock_bh(&br->hash_lock); in __br_fdb_add()
1289 err = fdb_add_entry(br, p, addr, ndm, nlh_flags, vid, nfea_tb); in __br_fdb_add()
1290 spin_unlock_bh(&br->hash_lock); in __br_fdb_add()
1313 struct net_bridge *br = NULL; in br_fdb_add() local
1330 br = netdev_priv(dev); in br_fdb_add()
1331 vg = br_vlan_group(br); in br_fdb_add()
1339 br = p->br; in br_fdb_add()
1369 err = __br_fdb_add(ndm, br, p, addr, nlh_flags, vid, nfea_tb, in br_fdb_add()
1372 err = __br_fdb_add(ndm, br, p, addr, nlh_flags, 0, nfea_tb, in br_fdb_add()
1384 err = __br_fdb_add(ndm, br, p, addr, nlh_flags, v->vid, in br_fdb_add()
1395 static int fdb_delete_by_addr_and_port(struct net_bridge *br, in fdb_delete_by_addr_and_port() argument
1401 fdb = br_fdb_find(br, addr, vlan); in fdb_delete_by_addr_and_port()
1405 fdb_delete(br, fdb, true); in fdb_delete_by_addr_and_port()
1411 static int __br_fdb_delete(struct net_bridge *br, in __br_fdb_delete() argument
1417 spin_lock_bh(&br->hash_lock); in __br_fdb_delete()
1418 err = fdb_delete_by_addr_and_port(br, p, addr, vid, notified); in __br_fdb_delete()
1419 spin_unlock_bh(&br->hash_lock); in __br_fdb_delete()
1432 struct net_bridge *br; in br_fdb_delete() local
1436 br = netdev_priv(dev); in br_fdb_delete()
1437 vg = br_vlan_group(br); in br_fdb_delete()
1446 br = p->br; in br_fdb_delete()
1450 err = __br_fdb_delete(br, p, addr, vid, notified); in br_fdb_delete()
1455 err &= __br_fdb_delete(br, p, addr, 0, notified); in br_fdb_delete()
1462 err &= __br_fdb_delete(br, p, addr, v->vid, notified); in br_fdb_delete()
1469 int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p) in br_fdb_sync_static() argument
1478 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) { in br_fdb_sync_static()
1492 hlist_for_each_entry_rcu(tmp, &br->fdb_list, fdb_node) { in br_fdb_sync_static()
1504 void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p) in br_fdb_unsync_static() argument
1511 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) { in br_fdb_unsync_static()
1521 int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, in br_fdb_external_learn_add() argument
1529 trace_br_fdb_external_learn_add(br, p, addr, vid); in br_fdb_external_learn_add()
1534 spin_lock_bh(&br->hash_lock); in br_fdb_external_learn_add()
1536 fdb = br_fdb_find(br, addr, vid); in br_fdb_external_learn_add()
1549 fdb = fdb_create(br, p, addr, vid, flags); in br_fdb_external_learn_add()
1554 fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify); in br_fdb_external_learn_add()
1590 atomic_dec(&br->fdb_n_learned); in br_fdb_external_learn_add()
1593 fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify); in br_fdb_external_learn_add()
1597 spin_unlock_bh(&br->hash_lock); in br_fdb_external_learn_add()
1602 int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p, in br_fdb_external_learn_del() argument
1609 spin_lock_bh(&br->hash_lock); in br_fdb_external_learn_del()
1611 fdb = br_fdb_find(br, addr, vid); in br_fdb_external_learn_del()
1613 fdb_delete(br, fdb, swdev_notify); in br_fdb_external_learn_del()
1617 spin_unlock_bh(&br->hash_lock); in br_fdb_external_learn_del()
1622 void br_fdb_offloaded_set(struct net_bridge *br, struct net_bridge_port *p, in br_fdb_offloaded_set() argument
1627 spin_lock_bh(&br->hash_lock); in br_fdb_offloaded_set()
1629 fdb = br_fdb_find(br, addr, vid); in br_fdb_offloaded_set()
1633 spin_unlock_bh(&br->hash_lock); in br_fdb_offloaded_set()
1647 spin_lock_bh(&p->br->hash_lock); in br_fdb_clear_offload()
1648 hlist_for_each_entry(f, &p->br->fdb_list, fdb_node) { in br_fdb_clear_offload()
1652 spin_unlock_bh(&p->br->hash_lock); in br_fdb_clear_offload()