Lines Matching +full:1 +full:br +full:- +full:10
1 // SPDX-License-Identifier: GPL-2.0-or-later
40 return -ENOMEM; in br_fdb_init()
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
71 return !test_bit(BR_FDB_STATIC, &fdb->flags) && in has_expired()
72 !test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags) && in has_expired()
73 time_before_eq(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
79 if (test_bit(BR_FDB_LOCAL, &fdb->flags)) in fdb_to_nud()
81 else if (test_bit(BR_FDB_STATIC, &fdb->flags)) in fdb_to_nud()
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
93 const struct net_bridge_port *dst = READ_ONCE(fdb->dst); in fdb_fill_info()
102 return -EMSGSIZE; in fdb_fill_info()
105 ndm->ndm_family = AF_BRIDGE; in fdb_fill_info()
106 ndm->ndm_pad1 = 0; in fdb_fill_info()
107 ndm->ndm_pad2 = 0; in fdb_fill_info()
108 ndm->ndm_flags = 0; in fdb_fill_info()
109 ndm->ndm_type = 0; in fdb_fill_info()
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()
113 if (test_bit(BR_FDB_OFFLOADED, &fdb->flags)) in fdb_fill_info()
114 ndm->ndm_flags |= NTF_OFFLOADED; in fdb_fill_info()
115 if (test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags)) in fdb_fill_info()
116 ndm->ndm_flags |= NTF_EXT_LEARNED; in fdb_fill_info()
117 if (test_bit(BR_FDB_STICKY, &fdb->flags)) in fdb_fill_info()
118 ndm->ndm_flags |= NTF_STICKY; in fdb_fill_info()
119 if (test_bit(BR_FDB_LOCKED, &fdb->flags)) in fdb_fill_info()
122 if (nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->key.addr)) in fdb_fill_info()
124 if (nla_put_u32(skb, NDA_MASTER, br->dev->ifindex)) in fdb_fill_info()
129 ci.ndm_used = jiffies_to_clock_t(now - fdb->used); in fdb_fill_info()
131 ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated); in fdb_fill_info()
136 if (fdb->key.vlan_id && nla_put(skb, NDA_VLAN, sizeof(u16), in fdb_fill_info()
137 &fdb->key.vlan_id)) in fdb_fill_info()
140 if (test_bit(BR_FDB_NOTIFY, &fdb->flags)) { in fdb_fill_info()
146 if (test_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags)) in fdb_fill_info()
162 return -EMSGSIZE; 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()
183 int err = -ENOBUFS; 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()
194 /* -EMSGSIZE implies BUG in fdb_nlmsg_size() */ in fdb_notify()
195 WARN_ON(err == -EMSGSIZE); 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()
251 if (f && f->dst) in br_fdb_find_port()
252 dev = f->dst->dev; 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()
280 err = dev_uc_add(p->dev, addr); in fdb_add_hw_addr()
288 list_for_each_entry_continue_reverse(p, &br->port_list, list) { in fdb_add_hw_addr()
290 dev_uc_del(p->dev, addr); 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()
307 dev_uc_del(p->dev, addr); 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()
316 if (test_bit(BR_FDB_STATIC, &f->flags)) in fdb_delete()
317 fdb_del_hw_addr(br, f->key.addr.addr); in fdb_delete()
319 hlist_del_init_rcu(&f->fdb_node); in fdb_delete()
320 rhashtable_remove_fast(&br->fdb_hash_tbl, &f->rhnode, in fdb_delete()
322 if (test_and_clear_bit(BR_FDB_DYNAMIC_LEARNED, &f->flags)) 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
338 const unsigned char *addr = f->key.addr.addr; in fdb_delete_local()
342 u16 vid = f->key.vlan_id; in fdb_delete_local()
345 list_for_each_entry(op, &br->port_list, list) { in fdb_delete_local()
347 if (op != p && ether_addr_equal(op->dev->dev_addr, addr) && in fdb_delete_local()
349 f->dst = op; in fdb_delete_local()
350 clear_bit(BR_FDB_ADDED_BY_USER, &f->flags); 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()
360 f->dst = NULL; in fdb_delete_local()
361 clear_bit(BR_FDB_ADDED_BY_USER, &f->flags); 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()
376 if (f && test_bit(BR_FDB_LOCAL, &f->flags) && in br_fdb_find_delete_local()
377 !test_bit(BR_FDB_ADDED_BY_USER, &f->flags) && f->dst == p) 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()
406 memcpy(fdb->key.addr.addr, addr, ETH_ALEN); in fdb_create()
407 WRITE_ONCE(fdb->dst, source); in fdb_create()
408 fdb->key.vlan_id = vid; in fdb_create()
409 fdb->flags = flags; in fdb_create()
410 fdb->updated = fdb->used = jiffies; 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
432 return -EINVAL; in fdb_add_local()
434 fdb = br_fdb_find(br, addr, vid); in fdb_add_local()
439 if (test_bit(BR_FDB_LOCAL, &fdb->flags)) 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()
449 return -ENOMEM; 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
463 spin_lock_bh(&br->hash_lock); in br_fdb_changeaddr()
465 hlist_for_each_entry(f, &br->fdb_list, fdb_node) { in br_fdb_changeaddr()
466 if (f->dst == p && test_bit(BR_FDB_LOCAL, &f->flags) && in br_fdb_changeaddr()
467 !test_bit(BR_FDB_ADDED_BY_USER, &f->flags)) { in br_fdb_changeaddr()
469 fdb_delete_local(br, p, f); in br_fdb_changeaddr()
475 if (!vg || !vg->num_vlans) in br_fdb_changeaddr()
482 fdb_add_local(br, p, newaddr, 0); in br_fdb_changeaddr()
484 if (!vg || !vg->num_vlans) in br_fdb_changeaddr()
491 list_for_each_entry(v, &vg->vlan_list, vlist) in br_fdb_changeaddr()
492 fdb_add_local(br, p, newaddr, v->vid); in br_fdb_changeaddr()
495 spin_unlock_bh(&br->hash_lock); in br_fdb_changeaddr()
498 void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr) in br_fdb_change_mac_address() argument
504 spin_lock_bh(&br->hash_lock); in br_fdb_change_mac_address()
507 f = br_fdb_find(br, br->dev->dev_addr, 0); in br_fdb_change_mac_address()
508 if (f && test_bit(BR_FDB_LOCAL, &f->flags) && in br_fdb_change_mac_address()
509 !f->dst && !test_bit(BR_FDB_ADDED_BY_USER, &f->flags)) in br_fdb_change_mac_address()
510 fdb_delete_local(br, NULL, f); in br_fdb_change_mac_address()
512 fdb_add_local(br, NULL, newaddr, 0); in br_fdb_change_mac_address()
513 vg = br_vlan_group(br); in br_fdb_change_mac_address()
514 if (!vg || !vg->num_vlans) in br_fdb_change_mac_address()
520 list_for_each_entry(v, &vg->vlan_list, vlist) { in br_fdb_change_mac_address()
523 f = br_fdb_find(br, br->dev->dev_addr, v->vid); in br_fdb_change_mac_address()
524 if (f && test_bit(BR_FDB_LOCAL, &f->flags) && in br_fdb_change_mac_address()
525 !f->dst && !test_bit(BR_FDB_ADDED_BY_USER, &f->flags)) in br_fdb_change_mac_address()
526 fdb_delete_local(br, NULL, f); in br_fdb_change_mac_address()
527 fdb_add_local(br, NULL, newaddr, v->vid); in br_fdb_change_mac_address()
530 spin_unlock_bh(&br->hash_lock); in br_fdb_change_mac_address()
535 struct net_bridge *br = container_of(work, struct net_bridge, in br_fdb_cleanup() local
538 unsigned long delay = hold_time(br); in br_fdb_cleanup()
547 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) { in br_fdb_cleanup()
548 unsigned long this_timer = f->updated + delay; in br_fdb_cleanup()
550 if (test_bit(BR_FDB_STATIC, &f->flags) || in br_fdb_cleanup()
551 test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &f->flags)) { in br_fdb_cleanup()
552 if (test_bit(BR_FDB_NOTIFY, &f->flags)) { in br_fdb_cleanup()
555 this_timer - now); in br_fdb_cleanup()
557 &f->flags)) in br_fdb_cleanup()
558 fdb_notify(br, f, RTM_NEWNEIGH, false); in br_fdb_cleanup()
564 work_delay = min(work_delay, this_timer - now); in br_fdb_cleanup()
566 spin_lock_bh(&br->hash_lock); in br_fdb_cleanup()
567 if (!hlist_unhashed(&f->fdb_node)) in br_fdb_cleanup()
568 fdb_delete(br, f, true); in br_fdb_cleanup()
569 spin_unlock_bh(&br->hash_lock); in br_fdb_cleanup()
574 /* Cleanup minimum 10 milliseconds apart */ in br_fdb_cleanup()
575 work_delay = max_t(unsigned long, work_delay, msecs_to_jiffies(10)); in br_fdb_cleanup()
576 mod_delayed_work(system_long_wq, &br->gc_work, work_delay); in br_fdb_cleanup()
579 static bool __fdb_flush_matches(const struct net_bridge *br, in __fdb_flush_matches() argument
583 const struct net_bridge_port *dst = READ_ONCE(f->dst); in __fdb_flush_matches()
584 int port_ifidx = dst ? dst->dev->ifindex : br->dev->ifindex; in __fdb_flush_matches()
586 if (desc->vlan_id && desc->vlan_id != f->key.vlan_id) in __fdb_flush_matches()
588 if (desc->port_ifindex && desc->port_ifindex != port_ifidx) in __fdb_flush_matches()
590 if (desc->flags_mask && (f->flags & desc->flags_mask) != desc->flags) in __fdb_flush_matches()
597 void br_fdb_flush(struct net_bridge *br, in br_fdb_flush() argument
603 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) { in br_fdb_flush()
604 if (!__fdb_flush_matches(br, f, desc)) in br_fdb_flush()
607 spin_lock_bh(&br->hash_lock); in br_fdb_flush()
608 if (!hlist_unhashed(&f->fdb_node)) in br_fdb_flush()
609 fdb_delete(br, f, true); in br_fdb_flush()
610 spin_unlock_bh(&br->hash_lock); in br_fdb_flush()
643 static int __fdb_flush_validate_ifindex(const struct net_bridge *br, in __fdb_flush_validate_ifindex() argument
649 dev = __dev_get_by_index(dev_net(br->dev), ifindex); in __fdb_flush_validate_ifindex()
652 return -ENODEV; in __fdb_flush_validate_ifindex()
656 return -EINVAL; in __fdb_flush_validate_ifindex()
658 if (netif_is_bridge_master(dev) && dev != br->dev) { in __fdb_flush_validate_ifindex()
661 return -EINVAL; in __fdb_flush_validate_ifindex()
666 if (p->br != br) { in __fdb_flush_validate_ifindex()
668 return -EINVAL; in __fdb_flush_validate_ifindex()
675 static const struct nla_policy br_fdb_del_bulk_policy[NDA_MAX + 1] = {
676 [NDA_VLAN] = NLA_POLICY_RANGE(NLA_U16, 1, VLAN_N_VID - 2),
677 [NDA_IFINDEX] = NLA_POLICY_MIN(NLA_S32, 1),
688 struct nlattr *tb[NDA_MAX + 1]; in br_fdb_delete_bulk()
689 struct net_bridge *br; in br_fdb_delete_bulk() local
693 ndm_flags = ndm->ndm_flags & ~FDB_FLUSH_IGNORED_NDM_FLAGS; in br_fdb_delete_bulk()
701 br = netdev_priv(dev); in br_fdb_delete_bulk()
706 return -EINVAL; in br_fdb_delete_bulk()
708 br = p->br; in br_fdb_delete_bulk()
716 return -EINVAL; in br_fdb_delete_bulk()
718 if (ndm->ndm_state & ~FDB_FLUSH_ALLOWED_NDM_STATES) { in br_fdb_delete_bulk()
720 return -EINVAL; in br_fdb_delete_bulk()
723 desc.flags |= __ndm_state_to_fdb_flags(ndm->ndm_state); in br_fdb_delete_bulk()
738 err = __fdb_flush_validate_ifindex(br, ifidx, extack); in br_fdb_delete_bulk()
744 desc.port_ifindex = p->dev->ifindex; in br_fdb_delete_bulk()
747 br_debug(br, "flushing port ifindex: %d vlan id: %u flags: 0x%lx flags mask: 0x%lx\n", in br_fdb_delete_bulk()
750 br_fdb_flush(br, &desc); in br_fdb_delete_bulk()
759 void br_fdb_delete_by_port(struct net_bridge *br, in br_fdb_delete_by_port() argument
767 spin_lock_bh(&br->hash_lock); in br_fdb_delete_by_port()
768 hlist_for_each_entry_safe(f, tmp, &br->fdb_list, fdb_node) { in br_fdb_delete_by_port()
769 if (f->dst != p) in br_fdb_delete_by_port()
773 if (test_bit(BR_FDB_STATIC, &f->flags) || in br_fdb_delete_by_port()
774 (test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &f->flags) && in br_fdb_delete_by_port()
775 !test_bit(BR_FDB_OFFLOADED, &f->flags)) || in br_fdb_delete_by_port()
776 (vid && f->key.vlan_id != vid)) in br_fdb_delete_by_port()
779 if (test_bit(BR_FDB_LOCAL, &f->flags)) in br_fdb_delete_by_port()
780 fdb_delete_local(br, p, f); in br_fdb_delete_by_port()
782 fdb_delete(br, f, true); in br_fdb_delete_by_port()
784 spin_unlock_bh(&br->hash_lock); in br_fdb_delete_by_port()
803 fdb = br_fdb_find_rcu(port->br, addr, 0); in br_fdb_test_addr()
805 dst = READ_ONCE(fdb->dst); in br_fdb_test_addr()
807 ret = dst && dst->dev != dev && in br_fdb_test_addr()
808 dst->state == BR_STATE_FORWARDING; in br_fdb_test_addr()
820 int br_fdb_fillbuf(struct net_bridge *br, void *buf, in br_fdb_fillbuf() argument
830 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) { in br_fdb_fillbuf()
834 if (has_expired(br, f)) in br_fdb_fillbuf()
838 if (!f->dst) in br_fdb_fillbuf()
842 --skip; in br_fdb_fillbuf()
847 memcpy(fe->mac_addr, f->key.addr.addr, ETH_ALEN); in br_fdb_fillbuf()
850 fe->port_no = f->dst->port_no; in br_fdb_fillbuf()
851 fe->port_hi = f->dst->port_no >> 8; in br_fdb_fillbuf()
853 fe->is_local = test_bit(BR_FDB_LOCAL, &f->flags); in br_fdb_fillbuf()
854 if (!test_bit(BR_FDB_STATIC, &f->flags)) in br_fdb_fillbuf()
855 fe->ageing_timer_value = jiffies_delta_to_clock_t(jiffies - f->updated); in br_fdb_fillbuf()
865 int br_fdb_add_local(struct net_bridge *br, struct net_bridge_port *source, in br_fdb_add_local() argument
870 spin_lock_bh(&br->hash_lock); in br_fdb_add_local()
871 ret = fdb_add_local(br, source, addr, vid); in br_fdb_add_local()
872 spin_unlock_bh(&br->hash_lock); in br_fdb_add_local()
879 return !!(test_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags) && in __fdb_mark_active()
880 test_and_clear_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags)); in __fdb_mark_active()
883 void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, in br_fdb_update() argument
889 if (hold_time(br) == 0) in br_fdb_update()
892 fdb = fdb_find_rcu(&br->fdb_hash_tbl, addr, vid); in br_fdb_update()
895 if (unlikely(test_bit(BR_FDB_LOCAL, &fdb->flags))) { in br_fdb_update()
897 br_warn(br, "received packet on %s with own address as source address (addr:%pM, vlan:%u)\n", in br_fdb_update()
898 source->dev->name, addr, vid); in br_fdb_update()
903 if (now != fdb->updated) { in br_fdb_update()
904 fdb->updated = now; in br_fdb_update()
909 if (unlikely(source != READ_ONCE(fdb->dst) && in br_fdb_update()
910 !test_bit(BR_FDB_STICKY, &fdb->flags))) { in br_fdb_update()
911 br_switchdev_fdb_notify(br, fdb, RTM_DELNEIGH); in br_fdb_update()
912 WRITE_ONCE(fdb->dst, source); in br_fdb_update()
916 &fdb->flags))) in br_fdb_update()
918 &fdb->flags); in br_fdb_update()
922 if (unlikely(test_bit(BR_FDB_LOCKED, &fdb->flags))) in br_fdb_update()
923 clear_bit(BR_FDB_LOCKED, &fdb->flags); in br_fdb_update()
927 set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); in br_fdb_update()
929 &fdb->flags)) in br_fdb_update()
930 atomic_dec(&br->fdb_n_learned); in br_fdb_update()
933 trace_br_fdb_update(br, source, addr, vid, flags); in br_fdb_update()
934 fdb_notify(br, fdb, RTM_NEWNEIGH, true); in br_fdb_update()
938 spin_lock(&br->hash_lock); in br_fdb_update()
939 fdb = fdb_create(br, source, addr, vid, flags); in br_fdb_update()
941 trace_br_fdb_update(br, source, addr, vid, flags); in br_fdb_update()
942 fdb_notify(br, fdb, RTM_NEWNEIGH, true); in br_fdb_update()
947 spin_unlock(&br->hash_lock); in br_fdb_update()
958 struct ndo_fdb_dump_context *ctx = (void *)cb->ctx; in br_fdb_dump()
959 struct net_bridge *br = netdev_priv(dev); in br_fdb_dump() local
973 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) { in br_fdb_dump()
974 if (*idx < ctx->fdb_idx) in br_fdb_dump()
976 if (filter_dev && (!f->dst || f->dst->dev != filter_dev)) { in br_fdb_dump()
979 /* !f->dst is a special case for bridge in br_fdb_dump()
982 * we only want to dump the !f->dst case in br_fdb_dump()
984 if (f->dst) in br_fdb_dump()
987 if (!filter_dev && f->dst) in br_fdb_dump()
990 err = fdb_fill_info(skb, br, f, in br_fdb_dump()
991 NETLINK_CB(cb->skb).portid, in br_fdb_dump()
992 cb->nlh->nlmsg_seq, in br_fdb_dump()
998 *idx += 1; in br_fdb_dump()
1012 struct net_bridge *br = netdev_priv(dev); in br_fdb_get() local
1017 f = br_fdb_find_rcu(br, addr, vid); in br_fdb_get()
1020 err = -ENOENT; in br_fdb_get()
1024 err = fdb_fill_info(skb, br, f, portid, seq, in br_fdb_get()
1038 !test_and_set_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags)) in fdb_handle_notify()
1042 !test_and_set_bit(BR_FDB_NOTIFY, &fdb->flags)) { in fdb_handle_notify()
1046 test_and_clear_bit(BR_FDB_NOTIFY, &fdb->flags)) { in fdb_handle_notify()
1048 clear_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags); in fdb_handle_notify()
1056 static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source, in fdb_add_entry() argument
1060 bool is_sticky = !!(ndm->ndm_flags & NTF_STICKY); in fdb_add_entry()
1063 u16 state = ndm->ndm_state; in fdb_add_entry()
1069 !(source->state == BR_STATE_LEARNING || in fdb_add_entry()
1070 source->state == BR_STATE_FORWARDING)) in fdb_add_entry()
1071 return -EPERM; in fdb_add_entry()
1075 br->dev->name); in fdb_add_entry()
1076 return -EINVAL; in fdb_add_entry()
1080 return -EINVAL; in fdb_add_entry()
1086 return -EINVAL; in fdb_add_entry()
1089 fdb = br_fdb_find(br, addr, vid); in fdb_add_entry()
1092 return -ENOENT; in fdb_add_entry()
1094 fdb = fdb_create(br, source, addr, vid, in fdb_add_entry()
1097 return -ENOMEM; in fdb_add_entry()
1102 return -EEXIST; in fdb_add_entry()
1104 if (READ_ONCE(fdb->dst) != source) { in fdb_add_entry()
1105 WRITE_ONCE(fdb->dst, source); in fdb_add_entry()
1109 set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); in fdb_add_entry()
1110 if (test_and_clear_bit(BR_FDB_DYNAMIC_LEARNED, &fdb->flags)) in fdb_add_entry()
1111 atomic_dec(&br->fdb_n_learned); in fdb_add_entry()
1114 if (fdb_to_nud(br, fdb) != state) { in fdb_add_entry()
1116 set_bit(BR_FDB_LOCAL, &fdb->flags); in fdb_add_entry()
1117 if (!test_and_set_bit(BR_FDB_STATIC, &fdb->flags)) in fdb_add_entry()
1118 fdb_add_hw_addr(br, addr); in fdb_add_entry()
1120 clear_bit(BR_FDB_LOCAL, &fdb->flags); in fdb_add_entry()
1121 if (!test_and_set_bit(BR_FDB_STATIC, &fdb->flags)) in fdb_add_entry()
1122 fdb_add_hw_addr(br, addr); in fdb_add_entry()
1124 clear_bit(BR_FDB_LOCAL, &fdb->flags); in fdb_add_entry()
1125 if (test_and_clear_bit(BR_FDB_STATIC, &fdb->flags)) in fdb_add_entry()
1126 fdb_del_hw_addr(br, addr); in fdb_add_entry()
1132 if (is_sticky != test_bit(BR_FDB_STICKY, &fdb->flags)) { in fdb_add_entry()
1133 change_bit(BR_FDB_STICKY, &fdb->flags); in fdb_add_entry()
1137 if (test_and_clear_bit(BR_FDB_LOCKED, &fdb->flags)) in fdb_add_entry()
1143 fdb->used = jiffies; in fdb_add_entry()
1146 fdb->updated = jiffies; in fdb_add_entry()
1147 fdb_notify(br, fdb, RTM_NEWNEIGH, true); in fdb_add_entry()
1153 static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge *br, in __br_fdb_add() argument
1160 if (ndm->ndm_flags & NTF_USE) { in __br_fdb_add()
1163 br->dev->name); in __br_fdb_add()
1164 return -EINVAL; in __br_fdb_add()
1171 br_fdb_update(br, p, addr, vid, BIT(BR_FDB_ADDED_BY_USER)); in __br_fdb_add()
1174 } else if (ndm->ndm_flags & NTF_EXT_LEARNED) { in __br_fdb_add()
1175 if (!p && !(ndm->ndm_state & NUD_PERMANENT)) { in __br_fdb_add()
1178 return -EINVAL; in __br_fdb_add()
1180 err = br_fdb_external_learn_add(br, p, addr, vid, false, true); in __br_fdb_add()
1182 spin_lock_bh(&br->hash_lock); in __br_fdb_add()
1183 err = fdb_add_entry(br, p, addr, ndm, nlh_flags, vid, nfea_tb); in __br_fdb_add()
1184 spin_unlock_bh(&br->hash_lock); in __br_fdb_add()
1192 static const struct nla_policy br_nda_fdb_pol[NFEA_MAX + 1] = {
1203 struct nlattr *nfea_tb[NFEA_MAX + 1], *attr; in br_fdb_add()
1207 struct net_bridge *br = NULL; in br_fdb_add() local
1213 if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE))) { in br_fdb_add()
1214 pr_info("bridge: RTM_NEWNEIGH with invalid state %#x\n", ndm->ndm_state); in br_fdb_add()
1215 return -EINVAL; in br_fdb_add()
1220 return -EINVAL; in br_fdb_add()
1224 br = netdev_priv(dev); in br_fdb_add()
1225 vg = br_vlan_group(br); in br_fdb_add()
1230 dev->name); in br_fdb_add()
1231 return -EINVAL; in br_fdb_add()
1233 br = p->br; in br_fdb_add()
1242 return -EINVAL; in br_fdb_add()
1252 memset(nfea_tb, 0, sizeof(struct nlattr *) * (NFEA_MAX + 1)); in br_fdb_add()
1258 pr_info("bridge: RTM_NEWNEIGH with unconfigured vlan %d on %s\n", vid, dev->name); in br_fdb_add()
1259 return -EINVAL; in br_fdb_add()
1263 err = __br_fdb_add(ndm, br, p, addr, nlh_flags, vid, nfea_tb, in br_fdb_add()
1266 err = __br_fdb_add(ndm, br, p, addr, nlh_flags, 0, nfea_tb, in br_fdb_add()
1268 if (err || !vg || !vg->num_vlans) in br_fdb_add()
1275 list_for_each_entry(v, &vg->vlan_list, vlist) { in br_fdb_add()
1278 err = __br_fdb_add(ndm, br, p, addr, nlh_flags, v->vid, in br_fdb_add()
1289 static int fdb_delete_by_addr_and_port(struct net_bridge *br, in fdb_delete_by_addr_and_port() argument
1295 fdb = br_fdb_find(br, addr, vlan); in fdb_delete_by_addr_and_port()
1296 if (!fdb || READ_ONCE(fdb->dst) != p) in fdb_delete_by_addr_and_port()
1297 return -ENOENT; in fdb_delete_by_addr_and_port()
1299 fdb_delete(br, fdb, true); in fdb_delete_by_addr_and_port()
1305 static int __br_fdb_delete(struct net_bridge *br, in __br_fdb_delete() argument
1311 spin_lock_bh(&br->hash_lock); in __br_fdb_delete()
1312 err = fdb_delete_by_addr_and_port(br, p, addr, vid, notified); in __br_fdb_delete()
1313 spin_unlock_bh(&br->hash_lock); in __br_fdb_delete()
1326 struct net_bridge *br; in br_fdb_delete() local
1330 br = netdev_priv(dev); in br_fdb_delete()
1331 vg = br_vlan_group(br); in br_fdb_delete()
1336 dev->name); in br_fdb_delete()
1337 return -EINVAL; in br_fdb_delete()
1340 br = p->br; in br_fdb_delete()
1344 err = __br_fdb_delete(br, p, addr, vid, notified); in br_fdb_delete()
1348 err = -ENOENT; in br_fdb_delete()
1349 err &= __br_fdb_delete(br, p, addr, 0, notified); in br_fdb_delete()
1350 if (!vg || !vg->num_vlans) in br_fdb_delete()
1353 list_for_each_entry(v, &vg->vlan_list, vlist) { in br_fdb_delete()
1356 err &= __br_fdb_delete(br, p, addr, v->vid, notified); in br_fdb_delete()
1363 int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p) in br_fdb_sync_static() argument
1372 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) { in br_fdb_sync_static()
1374 if (!test_bit(BR_FDB_STATIC, &f->flags)) in br_fdb_sync_static()
1376 err = dev_uc_add(p->dev, f->key.addr.addr); in br_fdb_sync_static()
1386 hlist_for_each_entry_rcu(tmp, &br->fdb_list, fdb_node) { in br_fdb_sync_static()
1388 if (!test_bit(BR_FDB_STATIC, &tmp->flags)) in br_fdb_sync_static()
1392 dev_uc_del(p->dev, tmp->key.addr.addr); in br_fdb_sync_static()
1398 void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p) in br_fdb_unsync_static() argument
1405 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) { in br_fdb_unsync_static()
1407 if (!test_bit(BR_FDB_STATIC, &f->flags)) in br_fdb_unsync_static()
1410 dev_uc_del(p->dev, f->key.addr.addr); in br_fdb_unsync_static()
1415 int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, in br_fdb_external_learn_add() argument
1423 trace_br_fdb_external_learn_add(br, p, addr, vid); in br_fdb_external_learn_add()
1425 if (locked && (!p || !(p->flags & BR_PORT_MAB))) in br_fdb_external_learn_add()
1426 return -EINVAL; in br_fdb_external_learn_add()
1428 spin_lock_bh(&br->hash_lock); in br_fdb_external_learn_add()
1430 fdb = br_fdb_find(br, addr, vid); in br_fdb_external_learn_add()
1443 fdb = fdb_create(br, p, addr, vid, flags); in br_fdb_external_learn_add()
1445 err = -ENOMEM; in br_fdb_external_learn_add()
1448 fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify); in br_fdb_external_learn_add()
1451 (!test_bit(BR_FDB_LOCKED, &fdb->flags) || in br_fdb_external_learn_add()
1452 READ_ONCE(fdb->dst) != p)) { in br_fdb_external_learn_add()
1453 err = -EINVAL; in br_fdb_external_learn_add()
1457 fdb->updated = jiffies; in br_fdb_external_learn_add()
1459 if (READ_ONCE(fdb->dst) != p) { in br_fdb_external_learn_add()
1460 WRITE_ONCE(fdb->dst, p); in br_fdb_external_learn_add()
1464 if (test_and_set_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags)) { in br_fdb_external_learn_add()
1466 fdb->used = jiffies; in br_fdb_external_learn_add()
1471 if (locked != test_bit(BR_FDB_LOCKED, &fdb->flags)) { in br_fdb_external_learn_add()
1472 change_bit(BR_FDB_LOCKED, &fdb->flags); in br_fdb_external_learn_add()
1477 set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); in br_fdb_external_learn_add()
1480 set_bit(BR_FDB_LOCAL, &fdb->flags); in br_fdb_external_learn_add()
1483 test_and_clear_bit(BR_FDB_DYNAMIC_LEARNED, &fdb->flags)) in br_fdb_external_learn_add()
1484 atomic_dec(&br->fdb_n_learned); in br_fdb_external_learn_add()
1487 fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify); in br_fdb_external_learn_add()
1491 spin_unlock_bh(&br->hash_lock); in br_fdb_external_learn_add()
1496 int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p, in br_fdb_external_learn_del() argument
1503 spin_lock_bh(&br->hash_lock); in br_fdb_external_learn_del()
1505 fdb = br_fdb_find(br, addr, vid); in br_fdb_external_learn_del()
1506 if (fdb && test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags)) in br_fdb_external_learn_del()
1507 fdb_delete(br, fdb, swdev_notify); in br_fdb_external_learn_del()
1509 err = -ENOENT; in br_fdb_external_learn_del()
1511 spin_unlock_bh(&br->hash_lock); in br_fdb_external_learn_del()
1516 void br_fdb_offloaded_set(struct net_bridge *br, struct net_bridge_port *p, in br_fdb_offloaded_set() argument
1521 spin_lock_bh(&br->hash_lock); in br_fdb_offloaded_set()
1523 fdb = br_fdb_find(br, addr, vid); in br_fdb_offloaded_set()
1524 if (fdb && offloaded != test_bit(BR_FDB_OFFLOADED, &fdb->flags)) in br_fdb_offloaded_set()
1525 change_bit(BR_FDB_OFFLOADED, &fdb->flags); in br_fdb_offloaded_set()
1527 spin_unlock_bh(&br->hash_lock); in br_fdb_offloaded_set()
1541 spin_lock_bh(&p->br->hash_lock); in br_fdb_clear_offload()
1542 hlist_for_each_entry(f, &p->br->fdb_list, fdb_node) { in br_fdb_clear_offload()
1543 if (f->dst == p && f->key.vlan_id == vid) in br_fdb_clear_offload()
1544 clear_bit(BR_FDB_OFFLOADED, &f->flags); in br_fdb_clear_offload()
1546 spin_unlock_bh(&p->br->hash_lock); in br_fdb_clear_offload()