blob: 65a6054873690b473387fb920cf2c239516dab09 [file] [log] [blame]
xf.li3dd53742024-09-27 00:06:23 -07001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Forwarding database
4 * Linux ethernet bridge
5 *
6 * Authors:
7 * Lennert Buytenhek <buytenh@gnu.org>
8 */
9
10#include <linux/kernel.h>
11#include <linux/init.h>
12#include <linux/rculist.h>
13#include <linux/spinlock.h>
14#include <linux/times.h>
15#include <linux/netdevice.h>
16#include <linux/etherdevice.h>
17#include <linux/jhash.h>
18#include <linux/random.h>
19#include <linux/slab.h>
20#include <linux/atomic.h>
21#include <asm/unaligned.h>
22#include <linux/if_vlan.h>
23#include <net/switchdev.h>
24#include <trace/events/bridge.h>
25#include "br_private.h"
26#ifdef CONFIG_FASTNAT_MODULE
27#include <net/SI/fast_common.h>
28#include <net/SI/net_track.h>
29#include <net/SI/netioc_proc.h>
30#endif
31
32static const struct rhashtable_params br_fdb_rht_params = {
33 .head_offset = offsetof(struct net_bridge_fdb_entry, rhnode),
34 .key_offset = offsetof(struct net_bridge_fdb_entry, key),
35 .key_len = sizeof(struct net_bridge_fdb_key),
36 .automatic_shrinking = true,
37};
38
39static struct kmem_cache *br_fdb_cache __read_mostly;
40static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
41 const unsigned char *addr, u16 vid);
42static void fdb_notify(struct net_bridge *br,
43 const struct net_bridge_fdb_entry *, int, bool);
44
45int __init br_fdb_init(void)
46{
47 br_fdb_cache = kmem_cache_create("bridge_fdb_cache",
48 sizeof(struct net_bridge_fdb_entry),
49 0,
50 SLAB_HWCACHE_ALIGN, NULL);
51 if (!br_fdb_cache)
52 return -ENOMEM;
53
54 return 0;
55}
56
57void br_fdb_fini(void)
58{
59 kmem_cache_destroy(br_fdb_cache);
60}
61
62int br_fdb_hash_init(struct net_bridge *br)
63{
64 return rhashtable_init(&br->fdb_hash_tbl, &br_fdb_rht_params);
65}
66
67void br_fdb_hash_fini(struct net_bridge *br)
68{
69 rhashtable_destroy(&br->fdb_hash_tbl);
70}
71
72/* if topology_changing then use forward_delay (default 15 sec)
73 * otherwise keep longer (default 5 minutes)
74 */
75static inline unsigned long hold_time(const struct net_bridge *br)
76{
77 return br->topology_change ? br->forward_delay : br->ageing_time;
78}
79
80static inline int has_expired(const struct net_bridge *br,
81 const struct net_bridge_fdb_entry *fdb)
82{
83 return !test_bit(BR_FDB_STATIC, &fdb->flags) &&
84 !test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags) &&
85 time_before_eq(fdb->updated + hold_time(br), jiffies);
86}
87
88static void fdb_rcu_free(struct rcu_head *head)
89{
90 struct net_bridge_fdb_entry *ent
91 = container_of(head, struct net_bridge_fdb_entry, rcu);
92 kmem_cache_free(br_fdb_cache, ent);
93}
94
95static struct net_bridge_fdb_entry *fdb_find_rcu(struct rhashtable *tbl,
96 const unsigned char *addr,
97 __u16 vid)
98{
99 struct net_bridge_fdb_key key;
100
101 WARN_ON_ONCE(!rcu_read_lock_held());
102
103 key.vlan_id = vid;
104 memcpy(key.addr.addr, addr, sizeof(key.addr.addr));
105
106 return rhashtable_lookup(tbl, &key, br_fdb_rht_params);
107}
108
109/* requires bridge hash_lock */
110static struct net_bridge_fdb_entry *br_fdb_find(struct net_bridge *br,
111 const unsigned char *addr,
112 __u16 vid)
113{
114 struct net_bridge_fdb_entry *fdb;
115
116 lockdep_assert_held_once(&br->hash_lock);
117
118 rcu_read_lock();
119 fdb = fdb_find_rcu(&br->fdb_hash_tbl, addr, vid);
120 rcu_read_unlock();
121
122 return fdb;
123}
124
125struct net_device *br_fdb_find_port(const struct net_device *br_dev,
126 const unsigned char *addr,
127 __u16 vid)
128{
129 struct net_bridge_fdb_entry *f;
130 struct net_device *dev = NULL;
131 struct net_bridge *br;
132
133 ASSERT_RTNL();
134
135 if (!netif_is_bridge_master(br_dev))
136 return NULL;
137
138 br = netdev_priv(br_dev);
139 rcu_read_lock();
140 f = br_fdb_find_rcu(br, addr, vid);
141 if (f && f->dst)
142 dev = f->dst->dev;
143 rcu_read_unlock();
144
145 return dev;
146}
147EXPORT_SYMBOL_GPL(br_fdb_find_port);
148
149struct net_bridge_fdb_entry *br_fdb_find_rcu(struct net_bridge *br,
150 const unsigned char *addr,
151 __u16 vid)
152{
153 return fdb_find_rcu(&br->fdb_hash_tbl, addr, vid);
154}
155
156/* When a static FDB entry is added, the mac address from the entry is
157 * added to the bridge private HW address list and all required ports
158 * are then updated with the new information.
159 * Called under RTNL.
160 */
161static void fdb_add_hw_addr(struct net_bridge *br, const unsigned char *addr)
162{
163 int err;
164 struct net_bridge_port *p;
165
166 ASSERT_RTNL();
167
168 list_for_each_entry(p, &br->port_list, list) {
169 if (!br_promisc_port(p)) {
170 err = dev_uc_add(p->dev, addr);
171 if (err)
172 goto undo;
173 }
174 }
175
176 return;
177undo:
178 list_for_each_entry_continue_reverse(p, &br->port_list, list) {
179 if (!br_promisc_port(p))
180 dev_uc_del(p->dev, addr);
181 }
182}
183
184/* When a static FDB entry is deleted, the HW address from that entry is
185 * also removed from the bridge private HW address list and updates all
186 * the ports with needed information.
187 * Called under RTNL.
188 */
189static void fdb_del_hw_addr(struct net_bridge *br, const unsigned char *addr)
190{
191 struct net_bridge_port *p;
192
193 ASSERT_RTNL();
194
195 list_for_each_entry(p, &br->port_list, list) {
196 if (!br_promisc_port(p))
197 dev_uc_del(p->dev, addr);
198 }
199}
200
201static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f,
202 bool swdev_notify)
203{
204 trace_fdb_delete(br, f);
205
206 if (test_bit(BR_FDB_STATIC, &f->flags))
207 fdb_del_hw_addr(br, f->key.addr.addr);
208
209 hlist_del_init_rcu(&f->fdb_node);
210 rhashtable_remove_fast(&br->fdb_hash_tbl, &f->rhnode,
211 br_fdb_rht_params);
212 fdb_notify(br, f, RTM_DELNEIGH, swdev_notify);
213 call_rcu(&f->rcu, fdb_rcu_free);
214}
215
216/* Delete a local entry if no other port had the same address. */
217static void fdb_delete_local(struct net_bridge *br,
218 const struct net_bridge_port *p,
219 struct net_bridge_fdb_entry *f)
220{
221 const unsigned char *addr = f->key.addr.addr;
222 struct net_bridge_vlan_group *vg;
223 const struct net_bridge_vlan *v;
224 struct net_bridge_port *op;
225 u16 vid = f->key.vlan_id;
226
227 /* Maybe another port has same hw addr? */
228 list_for_each_entry(op, &br->port_list, list) {
229 vg = nbp_vlan_group(op);
230 if (op != p && ether_addr_equal(op->dev->dev_addr, addr) &&
231 (!vid || br_vlan_find(vg, vid))) {
232 f->dst = op;
233 clear_bit(BR_FDB_ADDED_BY_USER, &f->flags);
234 return;
235 }
236 }
237
238 vg = br_vlan_group(br);
239 v = br_vlan_find(vg, vid);
240 /* Maybe bridge device has same hw addr? */
241 if (p && ether_addr_equal(br->dev->dev_addr, addr) &&
242 (!vid || (v && br_vlan_should_use(v)))) {
243 f->dst = NULL;
244 clear_bit(BR_FDB_ADDED_BY_USER, &f->flags);
245 return;
246 }
247
248 fdb_delete(br, f, true);
249}
250
251void br_fdb_find_delete_local(struct net_bridge *br,
252 const struct net_bridge_port *p,
253 const unsigned char *addr, u16 vid)
254{
255 struct net_bridge_fdb_entry *f;
256
257 spin_lock_bh(&br->hash_lock);
258 f = br_fdb_find(br, addr, vid);
259 if (f && test_bit(BR_FDB_LOCAL, &f->flags) &&
260 !test_bit(BR_FDB_ADDED_BY_USER, &f->flags) && f->dst == p)
261 fdb_delete_local(br, p, f);
262 spin_unlock_bh(&br->hash_lock);
263}
264
265void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr)
266{
267 struct net_bridge_vlan_group *vg;
268 struct net_bridge_fdb_entry *f;
269 struct net_bridge *br = p->br;
270 struct net_bridge_vlan *v;
271
272 spin_lock_bh(&br->hash_lock);
273 vg = nbp_vlan_group(p);
274 hlist_for_each_entry(f, &br->fdb_list, fdb_node) {
275 if (f->dst == p && test_bit(BR_FDB_LOCAL, &f->flags) &&
276 !test_bit(BR_FDB_ADDED_BY_USER, &f->flags)) {
277 /* delete old one */
278 fdb_delete_local(br, p, f);
279
280 /* if this port has no vlan information
281 * configured, we can safely be done at
282 * this point.
283 */
284 if (!vg || !vg->num_vlans)
285 goto insert;
286 }
287 }
288
289insert:
290 /* insert new address, may fail if invalid address or dup. */
291 fdb_insert(br, p, newaddr, 0);
292
293 if (!vg || !vg->num_vlans)
294 goto done;
295
296 /* Now add entries for every VLAN configured on the port.
297 * This function runs under RTNL so the bitmap will not change
298 * from under us.
299 */
300 list_for_each_entry(v, &vg->vlan_list, vlist)
301 fdb_insert(br, p, newaddr, v->vid);
302
303done:
304 spin_unlock_bh(&br->hash_lock);
305}
306
307void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
308{
309 struct net_bridge_vlan_group *vg;
310 struct net_bridge_fdb_entry *f;
311 struct net_bridge_vlan *v;
312
313 spin_lock_bh(&br->hash_lock);
314
315 /* If old entry was unassociated with any port, then delete it. */
316 f = br_fdb_find(br, br->dev->dev_addr, 0);
317 if (f && test_bit(BR_FDB_LOCAL, &f->flags) &&
318 !f->dst && !test_bit(BR_FDB_ADDED_BY_USER, &f->flags))
319 fdb_delete_local(br, NULL, f);
320
321 fdb_insert(br, NULL, newaddr, 0);
322 vg = br_vlan_group(br);
323 if (!vg || !vg->num_vlans)
324 goto out;
325 /* Now remove and add entries for every VLAN configured on the
326 * bridge. This function runs under RTNL so the bitmap will not
327 * change from under us.
328 */
329 list_for_each_entry(v, &vg->vlan_list, vlist) {
330 if (!br_vlan_should_use(v))
331 continue;
332 f = br_fdb_find(br, br->dev->dev_addr, v->vid);
333 if (f && test_bit(BR_FDB_LOCAL, &f->flags) &&
334 !f->dst && !test_bit(BR_FDB_ADDED_BY_USER, &f->flags))
335 fdb_delete_local(br, NULL, f);
336 fdb_insert(br, NULL, newaddr, v->vid);
337 }
338out:
339 spin_unlock_bh(&br->hash_lock);
340}
341
342void br_fdb_cleanup(struct work_struct *work)
343{
344 struct net_bridge *br = container_of(work, struct net_bridge,
345 gc_work.work);
346 struct net_bridge_fdb_entry *f = NULL;
347 unsigned long delay = hold_time(br);
348 unsigned long work_delay = delay;
349 unsigned long now = jiffies;
350
351 /* this part is tricky, in order to avoid blocking learning and
352 * consequently forwarding, we rely on rcu to delete objects with
353 * delayed freeing allowing us to continue traversing
354 */
355 rcu_read_lock();
356 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
357 unsigned long this_timer = f->updated + delay;
358
359 if (test_bit(BR_FDB_STATIC, &f->flags) ||
360 test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &f->flags)) {
361 if (test_bit(BR_FDB_NOTIFY, &f->flags)) {
362 if (time_after(this_timer, now))
363 work_delay = min(work_delay,
364 this_timer - now);
365 else if (!test_and_set_bit(BR_FDB_NOTIFY_INACTIVE,
366 &f->flags))
367 fdb_notify(br, f, RTM_NEWNEIGH, false);
368 }
369 continue;
370 }
371
372 if (time_after(this_timer, now)) {
373 work_delay = min(work_delay, this_timer - now);
374 } else {
375 spin_lock_bh(&br->hash_lock);
376 if (!hlist_unhashed(&f->fdb_node))
377 fdb_delete(br, f, true);
378 spin_unlock_bh(&br->hash_lock);
379 }
380 }
381 rcu_read_unlock();
382
383 /* Cleanup minimum 10 milliseconds apart */
384 work_delay = max_t(unsigned long, work_delay, msecs_to_jiffies(10));
385 mod_delayed_work(system_long_wq, &br->gc_work, work_delay);
386}
387
388/* Completely flush all dynamic entries in forwarding database.*/
389void br_fdb_flush(struct net_bridge *br)
390{
391 struct net_bridge_fdb_entry *f;
392 struct hlist_node *tmp;
393
394 spin_lock_bh(&br->hash_lock);
395 hlist_for_each_entry_safe(f, tmp, &br->fdb_list, fdb_node) {
396 if (!test_bit(BR_FDB_STATIC, &f->flags))
397 fdb_delete(br, f, true);
398 }
399 spin_unlock_bh(&br->hash_lock);
400}
401
402/* Flush all entries referring to a specific port.
403 * if do_all is set also flush static entries
404 * if vid is set delete all entries that match the vlan_id
405 */
406void br_fdb_delete_by_port(struct net_bridge *br,
407 const struct net_bridge_port *p,
408 u16 vid,
409 int do_all)
410{
411 struct net_bridge_fdb_entry *f;
412 struct hlist_node *tmp;
413
414 spin_lock_bh(&br->hash_lock);
415 hlist_for_each_entry_safe(f, tmp, &br->fdb_list, fdb_node) {
416 if (f->dst != p)
417 continue;
418
419 if (!do_all)
420 if (test_bit(BR_FDB_STATIC, &f->flags) ||
421 (test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &f->flags) &&
422 !test_bit(BR_FDB_OFFLOADED, &f->flags)) ||
423 (vid && f->key.vlan_id != vid))
424 continue;
425
426 if (test_bit(BR_FDB_LOCAL, &f->flags))
427 fdb_delete_local(br, p, f);
428 else
429 fdb_delete(br, f, true);
430 }
431 spin_unlock_bh(&br->hash_lock);
432}
433
434#if IS_ENABLED(CONFIG_ATM_LANE)
435/* Interface used by ATM LANE hook to test
436 * if an addr is on some other bridge port */
437int br_fdb_test_addr(struct net_device *dev, unsigned char *addr)
438{
439 struct net_bridge_fdb_entry *fdb;
440 struct net_bridge_port *port;
441 int ret;
442
443 rcu_read_lock();
444 port = br_port_get_rcu(dev);
445 if (!port)
446 ret = 0;
447 else {
448 fdb = br_fdb_find_rcu(port->br, addr, 0);
449 ret = fdb && fdb->dst && fdb->dst->dev != dev &&
450 fdb->dst->state == BR_STATE_FORWARDING;
451 }
452 rcu_read_unlock();
453
454 return ret;
455}
456#endif /* CONFIG_ATM_LANE */
457
458/*
459 * Fill buffer with forwarding table records in
460 * the API format.
461 */
462int br_fdb_fillbuf(struct net_bridge *br, void *buf,
463 unsigned long maxnum, unsigned long skip)
464{
465 struct net_bridge_fdb_entry *f;
466 struct __fdb_entry *fe = buf;
467 int num = 0;
468
469 memset(buf, 0, maxnum*sizeof(struct __fdb_entry));
470
471 rcu_read_lock();
472 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
473 if (num >= maxnum)
474 break;
475
476 if (has_expired(br, f))
477 continue;
478
479 /* ignore pseudo entry for local MAC address */
480 if (!f->dst)
481 continue;
482
483 if (skip) {
484 --skip;
485 continue;
486 }
487
488 /* convert from internal format to API */
489 memcpy(fe->mac_addr, f->key.addr.addr, ETH_ALEN);
490
491 /* due to ABI compat need to split into hi/lo */
492 fe->port_no = f->dst->port_no;
493 fe->port_hi = f->dst->port_no >> 8;
494
495 fe->is_local = test_bit(BR_FDB_LOCAL, &f->flags);
496 if (!test_bit(BR_FDB_STATIC, &f->flags))
497 fe->ageing_timer_value = jiffies_delta_to_clock_t(jiffies - f->updated);
498 ++fe;
499 ++num;
500 }
501 rcu_read_unlock();
502
503 return num;
504}
505
506static struct net_bridge_fdb_entry *fdb_create(struct net_bridge *br,
507 struct net_bridge_port *source,
508 const unsigned char *addr,
509 __u16 vid,
510 unsigned long flags)
511{
512 struct net_bridge_fdb_entry *fdb;
513
514 fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC);
515 if (fdb) {
516 memcpy(fdb->key.addr.addr, addr, ETH_ALEN);
517 fdb->dst = source;
518 fdb->key.vlan_id = vid;
519 fdb->flags = flags;
520 fdb->updated = fdb->used = jiffies;
521 if (rhashtable_lookup_insert_fast(&br->fdb_hash_tbl,
522 &fdb->rhnode,
523 br_fdb_rht_params)) {
524 kmem_cache_free(br_fdb_cache, fdb);
525 fdb = NULL;
526 } else {
527 hlist_add_head_rcu(&fdb->fdb_node, &br->fdb_list);
528 }
529 }
530 return fdb;
531}
532
533static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
534 const unsigned char *addr, u16 vid)
535{
536 struct net_bridge_fdb_entry *fdb;
537
538 if (!is_valid_ether_addr(addr))
539 return -EINVAL;
540
541 fdb = br_fdb_find(br, addr, vid);
542 if (fdb) {
543 /* it is okay to have multiple ports with same
544 * address, just use the first one.
545 */
546 if (test_bit(BR_FDB_LOCAL, &fdb->flags))
547 return 0;
548 br_warn(br, "adding interface %s with same address as a received packet (addr:%pM, vlan:%u)\n",
549 source ? source->dev->name : br->dev->name, addr, vid);
550 fdb_delete(br, fdb, true);
551 }
552
553 fdb = fdb_create(br, source, addr, vid,
554 BIT(BR_FDB_LOCAL) | BIT(BR_FDB_STATIC));
555 if (!fdb)
556 return -ENOMEM;
557
558 fdb_add_hw_addr(br, addr);
559 fdb_notify(br, fdb, RTM_NEWNEIGH, true);
560 return 0;
561}
562
563/* Add entry for local address of interface */
564int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
565 const unsigned char *addr, u16 vid)
566{
567 int ret;
568
569 spin_lock_bh(&br->hash_lock);
570 ret = fdb_insert(br, source, addr, vid);
571 spin_unlock_bh(&br->hash_lock);
572 return ret;
573}
574
575/* returns true if the fdb was modified */
576static bool __fdb_mark_active(struct net_bridge_fdb_entry *fdb)
577{
578 return !!(test_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags) &&
579 test_and_clear_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags));
580}
581
582void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
583 const unsigned char *addr, u16 vid, unsigned long flags)
584{
585 struct net_bridge_fdb_entry *fdb;
586
587 /* some users want to always flood. */
588 if (hold_time(br) == 0)
589 return;
590
591 fdb = fdb_find_rcu(&br->fdb_hash_tbl, addr, vid);
592 if (likely(fdb)) {
593 /* attempt to update an entry for a local interface */
594 if (unlikely(test_bit(BR_FDB_LOCAL, &fdb->flags))) {
595 if (net_ratelimit())
596 br_warn(br, "received packet on %s with own address as source address (addr:%pM, vlan:%u)\n",
597 source->dev->name, addr, vid);
598 } else {
599 unsigned long now = jiffies;
600 bool fdb_modified = false;
601
602 if (now != fdb->updated) {
603 fdb->updated = now;
604 fdb_modified = __fdb_mark_active(fdb);
605 }
606
607 /* fastpath: update of existing entry */
608 if (unlikely(source != fdb->dst &&
609 !test_bit(BR_FDB_STICKY, &fdb->flags))) {
610 fdb->dst = source;
611 fdb_modified = true;
612 /* Take over HW learned entry */
613 if (unlikely(test_bit(BR_FDB_ADDED_BY_EXT_LEARN,
614 &fdb->flags)))
615 clear_bit(BR_FDB_ADDED_BY_EXT_LEARN,
616 &fdb->flags);
617 }
618
619 if (unlikely(test_bit(BR_FDB_ADDED_BY_USER, &flags)))
620 set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
621 if (unlikely(fdb_modified)) {
622 trace_br_fdb_update(br, source, addr, vid, flags);
623 fdb_notify(br, fdb, RTM_NEWNEIGH, true);
624 }
625 }
626 } else {
627 spin_lock(&br->hash_lock);
628 fdb = fdb_create(br, source, addr, vid, flags);
629 if (fdb) {
630 trace_br_fdb_update(br, source, addr, vid, flags);
631 fdb_notify(br, fdb, RTM_NEWNEIGH, true);
632 }
633 /* else we lose race and someone else inserts
634 * it first, don't bother updating
635 */
636 spin_unlock(&br->hash_lock);
637 }
638}
639
640static int fdb_to_nud(const struct net_bridge *br,
641 const struct net_bridge_fdb_entry *fdb)
642{
643 if (test_bit(BR_FDB_LOCAL, &fdb->flags))
644 return NUD_PERMANENT;
645 else if (test_bit(BR_FDB_STATIC, &fdb->flags))
646 return NUD_NOARP;
647 else if (has_expired(br, fdb))
648 return NUD_STALE;
649 else
650 return NUD_REACHABLE;
651}
652
653static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br,
654 const struct net_bridge_fdb_entry *fdb,
655 u32 portid, u32 seq, int type, unsigned int flags)
656{
657 unsigned long now = jiffies;
658 struct nda_cacheinfo ci;
659 struct nlmsghdr *nlh;
660 struct ndmsg *ndm;
661
662 nlh = nlmsg_put(skb, portid, seq, type, sizeof(*ndm), flags);
663 if (nlh == NULL)
664 return -EMSGSIZE;
665
666 ndm = nlmsg_data(nlh);
667 ndm->ndm_family = AF_BRIDGE;
668 ndm->ndm_pad1 = 0;
669 ndm->ndm_pad2 = 0;
670 ndm->ndm_flags = 0;
671 ndm->ndm_type = 0;
672 ndm->ndm_ifindex = fdb->dst ? fdb->dst->dev->ifindex : br->dev->ifindex;
673 ndm->ndm_state = fdb_to_nud(br, fdb);
674
675 if (test_bit(BR_FDB_OFFLOADED, &fdb->flags))
676 ndm->ndm_flags |= NTF_OFFLOADED;
677 if (test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags))
678 ndm->ndm_flags |= NTF_EXT_LEARNED;
679 if (test_bit(BR_FDB_STICKY, &fdb->flags))
680 ndm->ndm_flags |= NTF_STICKY;
681
682 if (nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->key.addr))
683 goto nla_put_failure;
684 if (nla_put_u32(skb, NDA_MASTER, br->dev->ifindex))
685 goto nla_put_failure;
686 ci.ndm_used = jiffies_to_clock_t(now - fdb->used);
687 ci.ndm_confirmed = 0;
688 ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated);
689 ci.ndm_refcnt = 0;
690 if (nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci))
691 goto nla_put_failure;
692
693 if (fdb->key.vlan_id && nla_put(skb, NDA_VLAN, sizeof(u16),
694 &fdb->key.vlan_id))
695 goto nla_put_failure;
696
697 if (test_bit(BR_FDB_NOTIFY, &fdb->flags)) {
698 struct nlattr *nest = nla_nest_start(skb, NDA_FDB_EXT_ATTRS);
699 u8 notify_bits = FDB_NOTIFY_BIT;
700
701 if (!nest)
702 goto nla_put_failure;
703 if (test_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags))
704 notify_bits |= FDB_NOTIFY_INACTIVE_BIT;
705
706 if (nla_put_u8(skb, NFEA_ACTIVITY_NOTIFY, notify_bits)) {
707 nla_nest_cancel(skb, nest);
708 goto nla_put_failure;
709 }
710
711 nla_nest_end(skb, nest);
712 }
713
714 nlmsg_end(skb, nlh);
715 return 0;
716
717nla_put_failure:
718 nlmsg_cancel(skb, nlh);
719 return -EMSGSIZE;
720}
721
722static inline size_t fdb_nlmsg_size(void)
723{
724 return NLMSG_ALIGN(sizeof(struct ndmsg))
725 + nla_total_size(ETH_ALEN) /* NDA_LLADDR */
726 + nla_total_size(sizeof(u32)) /* NDA_MASTER */
727 + nla_total_size(sizeof(u16)) /* NDA_VLAN */
728 + nla_total_size(sizeof(struct nda_cacheinfo))
729 + nla_total_size(0) /* NDA_FDB_EXT_ATTRS */
730 + nla_total_size(sizeof(u8)); /* NFEA_ACTIVITY_NOTIFY */
731}
732
733static void fdb_notify(struct net_bridge *br,
734 const struct net_bridge_fdb_entry *fdb, int type,
735 bool swdev_notify)
736{
737 struct net *net = dev_net(br->dev);
738 struct sk_buff *skb;
739 int err = -ENOBUFS;
740
741 if (swdev_notify)
742 br_switchdev_fdb_notify(fdb, type);
743
744 skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC);
745 if (skb == NULL)
746 goto errout;
747
748 err = fdb_fill_info(skb, br, fdb, 0, 0, type, 0);
749 if (err < 0) {
750 /* -EMSGSIZE implies BUG in fdb_nlmsg_size() */
751 WARN_ON(err == -EMSGSIZE);
752 kfree_skb(skb);
753 goto errout;
754 }
755 rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
756 return;
757errout:
758 rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
759}
760
761/* Dump information about entries, in response to GETNEIGH */
762int br_fdb_dump(struct sk_buff *skb,
763 struct netlink_callback *cb,
764 struct net_device *dev,
765 struct net_device *filter_dev,
766 int *idx)
767{
768 struct net_bridge *br = netdev_priv(dev);
769 struct net_bridge_fdb_entry *f;
770 int err = 0;
771
772 if (!(dev->priv_flags & IFF_EBRIDGE))
773 return err;
774
775 if (!filter_dev) {
776 err = ndo_dflt_fdb_dump(skb, cb, dev, NULL, idx);
777 if (err < 0)
778 return err;
779 }
780
781 rcu_read_lock();
782 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
783 if (*idx < cb->args[2])
784 goto skip;
785 if (filter_dev && (!f->dst || f->dst->dev != filter_dev)) {
786 if (filter_dev != dev)
787 goto skip;
788 /* !f->dst is a special case for bridge
789 * It means the MAC belongs to the bridge
790 * Therefore need a little more filtering
791 * we only want to dump the !f->dst case
792 */
793 if (f->dst)
794 goto skip;
795 }
796 if (!filter_dev && f->dst)
797 goto skip;
798
799 err = fdb_fill_info(skb, br, f,
800 NETLINK_CB(cb->skb).portid,
801 cb->nlh->nlmsg_seq,
802 RTM_NEWNEIGH,
803 NLM_F_MULTI);
804 if (err < 0)
805 break;
806skip:
807 *idx += 1;
808 }
809 rcu_read_unlock();
810
811 return err;
812}
813
814int br_fdb_get(struct sk_buff *skb,
815 struct nlattr *tb[],
816 struct net_device *dev,
817 const unsigned char *addr,
818 u16 vid, u32 portid, u32 seq,
819 struct netlink_ext_ack *extack)
820{
821 struct net_bridge *br = netdev_priv(dev);
822 struct net_bridge_fdb_entry *f;
823 int err = 0;
824
825 rcu_read_lock();
826 f = br_fdb_find_rcu(br, addr, vid);
827 if (!f) {
828 NL_SET_ERR_MSG(extack, "Fdb entry not found");
829 err = -ENOENT;
830 goto errout;
831 }
832
833 err = fdb_fill_info(skb, br, f, portid, seq,
834 RTM_NEWNEIGH, 0);
835errout:
836 rcu_read_unlock();
837 return err;
838}
839
840/* returns true if the fdb is modified */
841static bool fdb_handle_notify(struct net_bridge_fdb_entry *fdb, u8 notify)
842{
843 bool modified = false;
844
845 /* allow to mark an entry as inactive, usually done on creation */
846 if ((notify & FDB_NOTIFY_INACTIVE_BIT) &&
847 !test_and_set_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags))
848 modified = true;
849
850 if ((notify & FDB_NOTIFY_BIT) &&
851 !test_and_set_bit(BR_FDB_NOTIFY, &fdb->flags)) {
852 /* enabled activity tracking */
853 modified = true;
854 } else if (!(notify & FDB_NOTIFY_BIT) &&
855 test_and_clear_bit(BR_FDB_NOTIFY, &fdb->flags)) {
856 /* disabled activity tracking, clear notify state */
857 clear_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags);
858 modified = true;
859 }
860
861 return modified;
862}
863
864/* Update (create or replace) forwarding database entry */
865static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
866 const u8 *addr, struct ndmsg *ndm, u16 flags, u16 vid,
867 struct nlattr *nfea_tb[])
868{
869 bool is_sticky = !!(ndm->ndm_flags & NTF_STICKY);
870 bool refresh = !nfea_tb[NFEA_DONT_REFRESH];
871 struct net_bridge_fdb_entry *fdb;
872 u16 state = ndm->ndm_state;
873 bool modified = false;
874 u8 notify = 0;
875
876 /* If the port cannot learn allow only local and static entries */
877 if (source && !(state & NUD_PERMANENT) && !(state & NUD_NOARP) &&
878 !(source->state == BR_STATE_LEARNING ||
879 source->state == BR_STATE_FORWARDING))
880 return -EPERM;
881
882 if (!source && !(state & NUD_PERMANENT)) {
883 pr_info("bridge: RTM_NEWNEIGH %s without NUD_PERMANENT\n",
884 br->dev->name);
885 return -EINVAL;
886 }
887
888 if (is_sticky && (state & NUD_PERMANENT))
889 return -EINVAL;
890
891 if (nfea_tb[NFEA_ACTIVITY_NOTIFY]) {
892 notify = nla_get_u8(nfea_tb[NFEA_ACTIVITY_NOTIFY]);
893 if ((notify & ~BR_FDB_NOTIFY_SETTABLE_BITS) ||
894 (notify & BR_FDB_NOTIFY_SETTABLE_BITS) == FDB_NOTIFY_INACTIVE_BIT)
895 return -EINVAL;
896 }
897
898 fdb = br_fdb_find(br, addr, vid);
899 if (fdb == NULL) {
900 if (!(flags & NLM_F_CREATE))
901 return -ENOENT;
902
903 fdb = fdb_create(br, source, addr, vid, 0);
904 if (!fdb)
905 return -ENOMEM;
906
907 modified = true;
908 } else {
909 if (flags & NLM_F_EXCL)
910 return -EEXIST;
911
912 if (fdb->dst != source) {
913 fdb->dst = source;
914 modified = true;
915 }
916 }
917
918 if (fdb_to_nud(br, fdb) != state) {
919 if (state & NUD_PERMANENT) {
920 set_bit(BR_FDB_LOCAL, &fdb->flags);
921 if (!test_and_set_bit(BR_FDB_STATIC, &fdb->flags))
922 fdb_add_hw_addr(br, addr);
923 } else if (state & NUD_NOARP) {
924 clear_bit(BR_FDB_LOCAL, &fdb->flags);
925 if (!test_and_set_bit(BR_FDB_STATIC, &fdb->flags))
926 fdb_add_hw_addr(br, addr);
927 } else {
928 clear_bit(BR_FDB_LOCAL, &fdb->flags);
929 if (test_and_clear_bit(BR_FDB_STATIC, &fdb->flags))
930 fdb_del_hw_addr(br, addr);
931 }
932
933 modified = true;
934 }
935
936 if (is_sticky != test_bit(BR_FDB_STICKY, &fdb->flags)) {
937 change_bit(BR_FDB_STICKY, &fdb->flags);
938 modified = true;
939 }
940
941 if (fdb_handle_notify(fdb, notify))
942 modified = true;
943
944 set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
945
946 fdb->used = jiffies;
947 if (modified) {
948 if (refresh)
949 fdb->updated = jiffies;
950 fdb_notify(br, fdb, RTM_NEWNEIGH, true);
951 }
952
953 return 0;
954}
955
956static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge *br,
957 struct net_bridge_port *p, const unsigned char *addr,
958 u16 nlh_flags, u16 vid, struct nlattr *nfea_tb[],
959 struct netlink_ext_ack *extack)
960{
961 int err = 0;
962
963 if (ndm->ndm_flags & NTF_USE) {
964 if (!p) {
965 pr_info("bridge: RTM_NEWNEIGH %s with NTF_USE is not supported\n",
966 br->dev->name);
967 return -EINVAL;
968 }
969 if (!nbp_state_should_learn(p))
970 return 0;
971
972 local_bh_disable();
973 rcu_read_lock();
974 br_fdb_update(br, p, addr, vid, BIT(BR_FDB_ADDED_BY_USER));
975 rcu_read_unlock();
976 local_bh_enable();
977 } else if (ndm->ndm_flags & NTF_EXT_LEARNED) {
978 if (!p && !(ndm->ndm_state & NUD_PERMANENT)) {
979 NL_SET_ERR_MSG_MOD(extack,
980 "FDB entry towards bridge must be permanent");
981 return -EINVAL;
982 }
983 err = br_fdb_external_learn_add(br, p, addr, vid, true);
984 } else {
985 spin_lock_bh(&br->hash_lock);
986 err = fdb_add_entry(br, p, addr, ndm, nlh_flags, vid, nfea_tb);
987 spin_unlock_bh(&br->hash_lock);
988 }
989
990 return err;
991}
992
993static const struct nla_policy br_nda_fdb_pol[NFEA_MAX + 1] = {
994 [NFEA_ACTIVITY_NOTIFY] = { .type = NLA_U8 },
995 [NFEA_DONT_REFRESH] = { .type = NLA_FLAG },
996};
997
998/* Add new permanent fdb entry with RTM_NEWNEIGH */
999int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
1000 struct net_device *dev,
1001 const unsigned char *addr, u16 vid, u16 nlh_flags,
1002 struct netlink_ext_ack *extack)
1003{
1004 struct nlattr *nfea_tb[NFEA_MAX + 1], *attr;
1005 struct net_bridge_vlan_group *vg;
1006 struct net_bridge_port *p = NULL;
1007 struct net_bridge_vlan *v;
1008 struct net_bridge *br = NULL;
1009 int err = 0;
1010
1011 trace_br_fdb_add(ndm, dev, addr, vid, nlh_flags);
1012
1013 if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE))) {
1014 pr_info("bridge: RTM_NEWNEIGH with invalid state %#x\n", ndm->ndm_state);
1015 return -EINVAL;
1016 }
1017
1018 if (is_zero_ether_addr(addr)) {
1019 pr_info("bridge: RTM_NEWNEIGH with invalid ether address\n");
1020 return -EINVAL;
1021 }
1022
1023 if (dev->priv_flags & IFF_EBRIDGE) {
1024 br = netdev_priv(dev);
1025 vg = br_vlan_group(br);
1026 } else {
1027 p = br_port_get_rtnl(dev);
1028 if (!p) {
1029 pr_info("bridge: RTM_NEWNEIGH %s not a bridge port\n",
1030 dev->name);
1031 return -EINVAL;
1032 }
1033 br = p->br;
1034 vg = nbp_vlan_group(p);
1035 }
1036
1037 if (tb[NDA_FDB_EXT_ATTRS]) {
1038 attr = tb[NDA_FDB_EXT_ATTRS];
1039 err = nla_parse_nested(nfea_tb, NFEA_MAX, attr,
1040 br_nda_fdb_pol, extack);
1041 if (err)
1042 return err;
1043 } else {
1044 memset(nfea_tb, 0, sizeof(struct nlattr *) * (NFEA_MAX + 1));
1045 }
1046
1047 if (vid) {
1048 v = br_vlan_find(vg, vid);
1049 if (!v || !br_vlan_should_use(v)) {
1050 pr_info("bridge: RTM_NEWNEIGH with unconfigured vlan %d on %s\n", vid, dev->name);
1051 return -EINVAL;
1052 }
1053
1054 /* VID was specified, so use it. */
1055 err = __br_fdb_add(ndm, br, p, addr, nlh_flags, vid, nfea_tb,
1056 extack);
1057 } else {
1058 err = __br_fdb_add(ndm, br, p, addr, nlh_flags, 0, nfea_tb,
1059 extack);
1060 if (err || !vg || !vg->num_vlans)
1061 goto out;
1062
1063 /* We have vlans configured on this port and user didn't
1064 * specify a VLAN. To be nice, add/update entry for every
1065 * vlan on this port.
1066 */
1067 list_for_each_entry(v, &vg->vlan_list, vlist) {
1068 if (!br_vlan_should_use(v))
1069 continue;
1070 err = __br_fdb_add(ndm, br, p, addr, nlh_flags, v->vid,
1071 nfea_tb, extack);
1072 if (err)
1073 goto out;
1074 }
1075 }
1076
1077out:
1078 return err;
1079}
1080
1081static int fdb_delete_by_addr_and_port(struct net_bridge *br,
1082 const struct net_bridge_port *p,
1083 const u8 *addr, u16 vlan)
1084{
1085 struct net_bridge_fdb_entry *fdb;
1086
1087 fdb = br_fdb_find(br, addr, vlan);
1088 if (!fdb || fdb->dst != p)
1089 return -ENOENT;
1090
1091 fdb_delete(br, fdb, true);
1092
1093 return 0;
1094}
1095
1096static int __br_fdb_delete(struct net_bridge *br,
1097 const struct net_bridge_port *p,
1098 const unsigned char *addr, u16 vid)
1099{
1100 int err;
1101
1102 spin_lock_bh(&br->hash_lock);
1103 err = fdb_delete_by_addr_and_port(br, p, addr, vid);
1104 spin_unlock_bh(&br->hash_lock);
1105
1106 return err;
1107}
1108
1109/* Remove neighbor entry with RTM_DELNEIGH */
1110int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
1111 struct net_device *dev,
1112 const unsigned char *addr, u16 vid)
1113{
1114 struct net_bridge_vlan_group *vg;
1115 struct net_bridge_port *p = NULL;
1116 struct net_bridge_vlan *v;
1117 struct net_bridge *br;
1118 int err;
1119
1120 if (dev->priv_flags & IFF_EBRIDGE) {
1121 br = netdev_priv(dev);
1122 vg = br_vlan_group(br);
1123 } else {
1124 p = br_port_get_rtnl(dev);
1125 if (!p) {
1126 pr_info("bridge: RTM_DELNEIGH %s not a bridge port\n",
1127 dev->name);
1128 return -EINVAL;
1129 }
1130 vg = nbp_vlan_group(p);
1131 br = p->br;
1132 }
1133
1134 if (vid) {
1135 v = br_vlan_find(vg, vid);
1136 if (!v) {
1137 pr_info("bridge: RTM_DELNEIGH with unconfigured vlan %d on %s\n", vid, dev->name);
1138 return -EINVAL;
1139 }
1140
1141 err = __br_fdb_delete(br, p, addr, vid);
1142 } else {
1143 err = -ENOENT;
1144 err &= __br_fdb_delete(br, p, addr, 0);
1145 if (!vg || !vg->num_vlans)
1146 return err;
1147
1148 list_for_each_entry(v, &vg->vlan_list, vlist) {
1149 if (!br_vlan_should_use(v))
1150 continue;
1151 err &= __br_fdb_delete(br, p, addr, v->vid);
1152 }
1153 }
1154
1155 return err;
1156}
1157
1158int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p)
1159{
1160 struct net_bridge_fdb_entry *f, *tmp;
1161 int err = 0;
1162
1163 ASSERT_RTNL();
1164
1165 /* the key here is that static entries change only under rtnl */
1166 rcu_read_lock();
1167 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
1168 /* We only care for static entries */
1169 if (!test_bit(BR_FDB_STATIC, &f->flags))
1170 continue;
1171 err = dev_uc_add(p->dev, f->key.addr.addr);
1172 if (err)
1173 goto rollback;
1174 }
1175done:
1176 rcu_read_unlock();
1177
1178 return err;
1179
1180rollback:
1181 hlist_for_each_entry_rcu(tmp, &br->fdb_list, fdb_node) {
1182 /* We only care for static entries */
1183 if (!test_bit(BR_FDB_STATIC, &tmp->flags))
1184 continue;
1185 if (tmp == f)
1186 break;
1187 dev_uc_del(p->dev, tmp->key.addr.addr);
1188 }
1189
1190 goto done;
1191}
1192
1193void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p)
1194{
1195 struct net_bridge_fdb_entry *f;
1196
1197 ASSERT_RTNL();
1198
1199 rcu_read_lock();
1200 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
1201 /* We only care for static entries */
1202 if (!test_bit(BR_FDB_STATIC, &f->flags))
1203 continue;
1204
1205 dev_uc_del(p->dev, f->key.addr.addr);
1206 }
1207 rcu_read_unlock();
1208}
1209
1210int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
1211 const unsigned char *addr, u16 vid,
1212 bool swdev_notify)
1213{
1214 struct net_bridge_fdb_entry *fdb;
1215 bool modified = false;
1216 int err = 0;
1217
1218 trace_br_fdb_external_learn_add(br, p, addr, vid);
1219
1220 spin_lock_bh(&br->hash_lock);
1221
1222 fdb = br_fdb_find(br, addr, vid);
1223 if (!fdb) {
1224 unsigned long flags = BIT(BR_FDB_ADDED_BY_EXT_LEARN);
1225
1226 if (swdev_notify)
1227 flags |= BIT(BR_FDB_ADDED_BY_USER);
1228
1229 if (!p)
1230 flags |= BIT(BR_FDB_LOCAL);
1231
1232 fdb = fdb_create(br, p, addr, vid, flags);
1233 if (!fdb) {
1234 err = -ENOMEM;
1235 goto err_unlock;
1236 }
1237 fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify);
1238 } else {
1239 fdb->updated = jiffies;
1240
1241 if (fdb->dst != p) {
1242 fdb->dst = p;
1243 modified = true;
1244 }
1245
1246 if (test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags)) {
1247 /* Refresh entry */
1248 fdb->used = jiffies;
1249 } else if (!test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags)) {
1250 /* Take over SW learned entry */
1251 set_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags);
1252 modified = true;
1253 }
1254
1255 if (swdev_notify)
1256 set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
1257
1258 if (!p)
1259 set_bit(BR_FDB_LOCAL, &fdb->flags);
1260
1261 if (modified)
1262 fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify);
1263 }
1264
1265err_unlock:
1266 spin_unlock_bh(&br->hash_lock);
1267
1268 return err;
1269}
1270
1271int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
1272 const unsigned char *addr, u16 vid,
1273 bool swdev_notify)
1274{
1275 struct net_bridge_fdb_entry *fdb;
1276 int err = 0;
1277
1278 spin_lock_bh(&br->hash_lock);
1279
1280 fdb = br_fdb_find(br, addr, vid);
1281 if (fdb && test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags))
1282 fdb_delete(br, fdb, swdev_notify);
1283 else
1284 err = -ENOENT;
1285
1286 spin_unlock_bh(&br->hash_lock);
1287
1288 return err;
1289}
1290
1291void br_fdb_offloaded_set(struct net_bridge *br, struct net_bridge_port *p,
1292 const unsigned char *addr, u16 vid, bool offloaded)
1293{
1294 struct net_bridge_fdb_entry *fdb;
1295
1296 spin_lock_bh(&br->hash_lock);
1297
1298 fdb = br_fdb_find(br, addr, vid);
1299 if (fdb && offloaded != test_bit(BR_FDB_OFFLOADED, &fdb->flags))
1300 change_bit(BR_FDB_OFFLOADED, &fdb->flags);
1301
1302 spin_unlock_bh(&br->hash_lock);
1303}
1304#ifdef CONFIG_FASTNAT_MODULE
1305int fast_br(struct sk_buff *skb)
1306{
1307 //lium_fastnat_del
1308 const unsigned char *dest = NULL;
1309 struct hlist_head *head;
1310 struct net_bridge_fdb_entry *fdb;
1311 struct net_bridge_port *p;
1312 struct net_bridge *br;
1313 u16 vid = 0;
1314 int ntl_port_id = 0xff;
1315
xf.lia06dd222024-10-14 09:07:20 +00001316 if(!skb->dev)
xf.li3dd53742024-09-27 00:06:23 -07001317 {
1318 //print_sun(SUN_DBG, "fast_br skb->dev err skb->dev = %x\n", skb->dev);
1319 return 0;
1320 }
1321
1322 /*if(skb->mac_header == 0 || skb->mac_header == ~0U)
1323 panic("driver not set macheader !!!\n");*/
1324
1325 dest = eth_hdr(skb)->h_dest;
1326
1327
1328 p = br_port_get_rtnl(skb->dev);
1329 if (p == NULL || p->br == NULL)
1330 {
1331 //print_sun(SUN_DBG, "fast_br br_port_get_rtnl err p = %x\n", p);
1332 return 0;
1333 }
1334
1335 br = p->br;
1336 br_should_learn(p, skb, &vid);
1337
1338 //head = &br->hash[br_mac_hash(dest, vid)];
1339
1340 //if((fdb = fdb_find_rcu(head, dest,vid)) != NULL)
1341 if((fdb = fdb_find_rcu(&(br->fdb_hash_tbl), dest,vid)) != NULL)
1342 {
1343
1344 if((!(test_bit(BR_FDB_LOCAL, &fdb->flags))) && fdb->dst && fdb->dst->dev &&
1345 (((fdb->dst->flags & BR_HAIRPIN_MODE) || skb->dev != fdb->dst->dev) &&fdb->dst->state == BR_STATE_FORWARDING))
1346 {
1347 fast_tcpdump(skb);
1348 if(fastnat_level == FAST_NET_DEVICE){
1349 skb->dev->stats.rx_packets++;
1350 skb->dev->stats.rx_bytes += skb->len;
1351 }
1352 skb->dev = fdb->dst->dev;
1353 skb->isFastbr = 1;
1354 fdb->updated = jiffies;
1355 skb->now_location |= FASTBR_SUCC;
1356 skb_rest_data_byproto(skb);
1357
1358 br_dev_queue_push_xmit(NULL, NULL, skb);
1359 return 1;
1360 }
1361
1362
1363 if((!(test_bit(BR_FDB_LOCAL, &fdb->flags))) && fdb->dst && fdb->dst->dev &&
1364 (skb->dev == fdb->dst->dev) && fdb->dst->state == BR_STATE_FORWARDING)
1365 {
1366 skbinfo_add(NULL,SKB_LOOP);
1367 skb->dev->stats.rx_dropped++;
1368 //print_sun(SUN_ERR,"fast_br loop data discarded, dev:%s \n", skb->dev->name);
1369 kfree_skb(skb);
1370 return 1;
1371 }
1372 }
1373 //print_sun(SUN_DBG, "fast_br fdb_find_rcu err fdb = %x \n",fdb);
1374
1375 return 0;
1376}
1377EXPORT_SYMBOL(fast_br);
1378
1379
1380
1381struct net_device *getbrport_bydst(struct net_device *dev,unsigned char *dest)
1382{
1383 //lium_fastnat_del
1384 //struct hlist_head *head;
1385 struct net_bridge_fdb_entry *fdb;
1386 struct net_bridge_port *p;
1387 struct net_bridge *br;
1388 struct net_bridge_vlan_group *vg;
1389 __u16 vid;
1390#if FASTNAT_DEBUG
1391 printk("getbrport_bydst() begine");
1392#endif
1393
1394 if (dev == NULL || !(dev->priv_flags & IFF_EBRIDGE))
1395 return dev;
1396#if FASTNAT_DEBUG
1397 printk("getbrport_bydst() 1");
1398#endif
1399 br = netdev_priv(dev);
1400 vg = br_vlan_group_rcu(br);
1401 vid = br_get_pvid(vg);
1402#if FASTNAT_DEBUG
1403 printk("getbrport_bydst() 2");
1404#endif
1405
1406 //head = &br->hash[br_mac_hash(dest,vid)];
1407#if FASTNAT_DEBUG
1408 printk("getbrport_bydst() 3");
1409#endif
1410 //if((fdb = fdb_find_rcu(head, dest,vid)) != NULL)
1411 if((fdb = fdb_find_rcu(&(br->fdb_hash_tbl), dest,vid)) != NULL)
1412 {
1413
1414 if((!(test_bit(BR_FDB_LOCAL, &fdb->flags))) && fdb->dst && fdb->dst->dev &&
1415 (fdb->dst->state == BR_STATE_FORWARDING)) //(fdb->dst->flags & BR_HAIRPIN_MODE)
1416 {
1417 return fdb->dst->dev;
1418 }
1419 }
1420 return dev;
1421}
1422
1423extern void fast_tcpdump(struct sk_buff *skb);
1424extern struct neigh_table arp_tbl;
1425extern char default_route_name[IFNAMSIZ];
1426char default_br_name[IFNAMSIZ] = {0};
1427int fast_fwd_ip4addr_conflict(struct sk_buff *skb)
1428{
1429 struct iphdr *iph = ip_hdr(skb);
1430 __be32 saddr,daddr,wan_ip,br_ip=0,br_bcast=0;
1431 struct net_device* in_dev = NULL;
1432 struct net_device* out_dev = NULL;
1433 struct ethhdr *eth;
1434 struct net_bridge_port *p;
1435 struct net_bridge *br = NULL;
1436 struct net_device *default_route_dev;
1437 struct net_device *default_br_dev;
1438 struct in_device *ip_ptr;
1439
1440 if(iph->version != 4 || skb->indev == NULL)
1441 {
1442 return 0;
1443 }
1444 default_route_dev = dev_get_by_name(&init_net, default_route_name);
1445 if(default_route_dev == NULL)
1446 {
1447 return 0;
1448 }
1449 ip_ptr = __in_dev_get_rtnl(default_route_dev);
1450 if(ip_ptr && ip_ptr->ifa_list)
1451 {
1452 wan_ip = ip_ptr->ifa_list->ifa_local;
1453 }
1454 else
1455 {
1456 default_br_name[0] = 0;
1457 dev_put(default_route_dev);
1458 return 0;
1459 }
1460 in_dev = skb->indev;
1461 saddr = iph->saddr;
1462 daddr = iph->daddr;
1463 p = br_port_get_rtnl(in_dev);
1464 if (p != NULL)
1465 {
1466 br = p->br;
1467 if (br && br->dev && strncmp(br->dev->name, default_br_name, IFNAMSIZ-1))
1468 {
1469 strncpy(default_br_name, br->dev->name, IFNAMSIZ-1);
1470 }
1471 }
1472 default_br_dev = dev_get_by_name(&init_net, default_br_name);
1473 if(default_br_dev)
1474 {
1475 ip_ptr = __in_dev_get_rtnl(default_br_dev);
1476 if(ip_ptr && ip_ptr->ifa_list)
1477 {
1478 br_ip = ip_ptr->ifa_list->ifa_local;
1479 br_bcast = ip_ptr->ifa_list->ifa_broadcast;
1480 }
1481 }
1482 else
1483 {
1484 dev_put(default_route_dev);
1485 return 0;
1486 }
1487 if(br && ((daddr == br_ip) || (daddr == br_bcast) || (daddr == wan_ip)))
1488 {
1489 //printk("@!@1saddr=%08x,daddr=%08x,br_ip=%08x,br_bcast=%08x,wan_ip=%08x\n",saddr, daddr, br_ip, br_bcast, wan_ip);
1490 if (IPPROTO_UDP == iph->protocol)
1491 {
1492 struct udphdr *udph = (struct udphdr *)(skb->data + iph->ihl * 4);
1493 if(udph->source == 0x4300 || udph->source == 0x4400
1494 || udph->dest == 0x4300 || udph->dest == 0x4400)
1495 {
1496 //printk("@!@dhcp packet\n");
1497 dev_put(default_route_dev);
1498 dev_put(default_br_dev);
1499 return 0;
1500 }
1501 }
1502 out_dev = default_route_dev;
1503 skb_push(skb, ETH_HLEN);
1504 eth = (struct ethhdr*)(skb->data);
1505 memcpy(eth->h_source, in_dev->dev_addr, ETH_ALEN);
1506 memcpy(eth->h_dest, out_dev->dev_addr, ETH_ALEN);
1507 fast_tcpdump(skb);
1508 skb->dev = out_dev;
1509 }
1510 else if(in_dev == default_route_dev && ((saddr == br_ip) || (saddr == br_bcast) || (saddr == wan_ip)))
1511 {
1512 struct neighbour *neigh = neigh_lookup(&arp_tbl, &daddr, default_br_dev);
1513 //printk("@!@2saddr=%08x,daddr=%08x,neigh=%08x,wan_ip=%08x\n",saddr, daddr, neigh, wan_ip);
1514 if(neigh)
1515 {
1516 //printk("@!@neigh=%s\n",neigh->dev->name);
1517 out_dev = getbrport_bydst(default_br_dev,neigh->ha);
1518 if(out_dev)
1519 {
1520 //printk("@!@out_dev=%s\n",out_dev->name);
1521 skb_push(skb, ETH_HLEN);
1522 eth = (struct ethhdr*)(skb->data);
1523 memcpy(eth->h_source, out_dev->dev_addr, ETH_ALEN);
1524 memcpy(eth->h_dest, neigh->ha, ETH_ALEN);
1525 //printk("@!@mac=%02x %02x %02x %02x %02x %02x\n",eth->h_dest[0],eth->h_dest[1],eth->h_dest[2],eth->h_dest[3],eth->h_dest[4],eth->h_dest[5]);
1526 }
1527 neigh_release(neigh);
1528 }
1529 if(out_dev == NULL)
1530 {
1531 printk("@!@dev: br port not found\n");
1532 dev_put(default_route_dev);
1533 dev_put(default_br_dev);
1534 return 0;
1535 }
1536 fast_tcpdump(skb);
1537 skb->dev = out_dev;
1538 }
1539 else
1540 {
1541 dev_put(default_route_dev);
1542 dev_put(default_br_dev);
1543 return 0;
1544 }
1545
1546 eth->h_proto = htons(ETH_P_IP);
1547 skb->now_location |= FASTNAT_SUCC;
1548 dev_queue_xmit(skb);
1549
1550 dev_put(default_route_dev);
1551 dev_put(default_br_dev);
1552 return 1;
1553}
1554
1555int fast_for_multicast(struct sk_buff *skb)
1556{
1557 if (skb->indev && !strncmp(skb->indev->name, default_route_name, IFNAMSIZ-1))
1558 {
1559 struct net_device* dev = NULL;
1560 struct net_bridge *br;
1561 struct net_bridge_port *p;
1562
1563 dev = dev_get_by_name(&init_net, default_br_name);
1564 if (dev == NULL || !(dev->priv_flags & IFF_EBRIDGE))
1565 {
1566 printk("@!@dev: br not found\n");
1567 return 0;
1568 }
1569 br = (struct net_bridge *)netdev_priv(dev);
1570 p = br_get_port(br, 1);
1571 if(p && p->dev)
1572 {
1573 struct ethhdr *eth;
1574 struct iphdr *iph = ip_hdr(skb);
1575
1576 skb_push(skb, ETH_HLEN);
1577 eth = (struct ethhdr *)skb->data;
1578 memcpy(eth->h_source, p->dev->dev_addr, ETH_ALEN);
1579 ip_eth_mc_map(iph->daddr, eth->h_dest);
1580 eth->h_proto = htons(ETH_P_IP);
1581 skb->dev = p->dev;
1582 skb->now_location |= FASTNAT_SUCC;
1583 dev_queue_xmit(skb);
1584 dev_put(dev);
1585 return 1;
1586 }
1587 dev_put(dev);
1588 }
1589 return 0;
1590}
1591#endif
1592
1593void br_fdb_clear_offload(const struct net_device *dev, u16 vid)
1594{
1595 struct net_bridge_fdb_entry *f;
1596 struct net_bridge_port *p;
1597
1598 ASSERT_RTNL();
1599
1600 p = br_port_get_rtnl(dev);
1601 if (!p)
1602 return;
1603
1604 spin_lock_bh(&p->br->hash_lock);
1605 hlist_for_each_entry(f, &p->br->fdb_list, fdb_node) {
1606 if (f->dst == p && f->key.vlan_id == vid)
1607 clear_bit(BR_FDB_OFFLOADED, &f->flags);
1608 }
1609 spin_unlock_bh(&p->br->hash_lock);
1610}
1611EXPORT_SYMBOL_GPL(br_fdb_clear_offload);