blob: 0c22ff308dc54039c1a764ecd3293955a5ac0a43 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*
2 * Forwarding database
3 * Linux ethernet bridge
4 *
5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/rculist.h>
17#include <linux/spinlock.h>
18#include <linux/times.h>
19#include <linux/netdevice.h>
20#include <linux/etherdevice.h>
21#include <linux/jhash.h>
22#include <linux/random.h>
23#include <linux/slab.h>
24#include <linux/atomic.h>
25#include <linux/export.h>
26#include <asm/unaligned.h>
27#include <net/SI/fast_common.h>
28#include "br_private.h"
29
30static struct kmem_cache *br_fdb_cache __read_mostly;
31static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
32 const unsigned char *addr);
33static void fdb_notify(struct net_bridge *br,
34 const struct net_bridge_fdb_entry *, int);
35
36static u32 fdb_salt __read_mostly;
37
38
39int __init br_fdb_init(void)
40{
41 br_fdb_cache = kmem_cache_create("bridge_fdb_cache",
42 sizeof(struct net_bridge_fdb_entry),
43 0,
44 SLAB_HWCACHE_ALIGN, NULL);
45 if (!br_fdb_cache)
46 return -ENOMEM;
47
48 get_random_bytes(&fdb_salt, sizeof(fdb_salt));
49 return 0;
50}
51
52void br_fdb_fini(void)
53{
54 kmem_cache_destroy(br_fdb_cache);
55}
56
57
58/* if topology_changing then use forward_delay (default 15 sec)
59 * otherwise keep longer (default 5 minutes)
60 */
61static inline unsigned long hold_time(const struct net_bridge *br)
62{
63 return br->topology_change ? br->forward_delay : br->ageing_time;
64}
65
66static inline int has_expired(const struct net_bridge *br,
67 const struct net_bridge_fdb_entry *fdb)
68{
69 return !fdb->is_static &&
70 time_before_eq(fdb->updated + hold_time(br), jiffies);
71}
72
73static inline int br_mac_hash(const unsigned char *mac)
74{
75 /* use 1 byte of OUI cnd 3 bytes of NIC */
76 u32 key = get_unaligned((u32 *)(mac + 2));
77 return jhash_1word(key, fdb_salt) & (BR_HASH_SIZE - 1);
78}
79int netdog_mac_hash(const unsigned char *mac)
80{
81 return br_mac_hash(mac);
82}
83static void fdb_rcu_free(struct rcu_head *head)
84{
85 struct net_bridge_fdb_entry *ent
86 = container_of(head, struct net_bridge_fdb_entry, rcu);
87 netslab_dec(BRFDB_SLAB);
88 kmem_cache_free(br_fdb_cache, ent);
89}
90
91static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f)
92{
93 hlist_del_rcu(&f->hlist);
94 fdb_notify(br, f, RTM_DELNEIGH);
95 call_rcu(&f->rcu, fdb_rcu_free);
96}
97
98void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr)
99{
100 struct net_bridge *br = p->br;
101 int i;
102
103 spin_lock_bh(&br->hash_lock);
104
105 /* Search all chains since old address/hash is unknown */
106 for (i = 0; i < BR_HASH_SIZE; i++) {
107 struct hlist_node *h;
108 hlist_for_each(h, &br->hash[i]) {
109 struct net_bridge_fdb_entry *f;
110
111 f = hlist_entry(h, struct net_bridge_fdb_entry, hlist);
112 if (f->dst == p && f->is_local) {
113 /* maybe another port has same hw addr? */
114 struct net_bridge_port *op;
115 list_for_each_entry(op, &br->port_list, list) {
116 if (op != p &&
117 !compare_ether_addr(op->dev->dev_addr,
118 f->addr.addr)) {
119 f->dst = op;
120 goto insert;
121 }
122 }
123
124 /* delete old one */
125 fdb_delete(br, f);
126 goto insert;
127 }
128 }
129 }
130 insert:
131 /* insert new address, may fail if invalid address or dup. */
132 fdb_insert(br, p, newaddr);
133
134 spin_unlock_bh(&br->hash_lock);
135}
136
137void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
138{
139 struct net_bridge_fdb_entry *f;
140
141 /* If old entry was unassociated with any port, then delete it. */
142 f = __br_fdb_get(br, br->dev->dev_addr);
143 if (f && f->is_local && !f->dst)
144 fdb_delete(br, f);
145
146 fdb_insert(br, NULL, newaddr);
147}
148
149void br_fdb_cleanup(unsigned long _data)
150{
151 struct net_bridge *br = (struct net_bridge *)_data;
152 unsigned long delay = hold_time(br);
153 unsigned long next_timer = jiffies + br->ageing_time;
154 int i;
155
156 spin_lock(&br->hash_lock);
157 for (i = 0; i < BR_HASH_SIZE; i++) {
158 struct net_bridge_fdb_entry *f;
159 struct hlist_node *h, *n;
160
161 hlist_for_each_entry_safe(f, h, n, &br->hash[i], hlist) {
162 unsigned long this_timer;
163 if (f->is_static)
164 continue;
165 this_timer = f->updated + delay;
166 if (time_before_eq(this_timer, jiffies))
167 fdb_delete(br, f);
168 else if (time_before(this_timer, next_timer))
169 next_timer = this_timer;
170 }
171 }
172 spin_unlock(&br->hash_lock);
173
174 mod_timer(&br->gc_timer, round_jiffies_up(next_timer));
175}
176
177/* Completely flush all dynamic entries in forwarding database.*/
178void br_fdb_flush(struct net_bridge *br)
179{
180 int i;
181
182 spin_lock_bh(&br->hash_lock);
183 for (i = 0; i < BR_HASH_SIZE; i++) {
184 struct net_bridge_fdb_entry *f;
185 struct hlist_node *h, *n;
186 hlist_for_each_entry_safe(f, h, n, &br->hash[i], hlist) {
187 if (!f->is_static)
188 fdb_delete(br, f);
189 }
190 }
191 spin_unlock_bh(&br->hash_lock);
192}
193
194/* Flush all entries referring to a specific port.
195 * if do_all is set also flush static entries
196 */
197void br_fdb_delete_by_port(struct net_bridge *br,
198 const struct net_bridge_port *p,
199 int do_all)
200{
201 int i;
202
203 spin_lock_bh(&br->hash_lock);
204 for (i = 0; i < BR_HASH_SIZE; i++) {
205 struct hlist_node *h, *g;
206
207 hlist_for_each_safe(h, g, &br->hash[i]) {
208 struct net_bridge_fdb_entry *f
209 = hlist_entry(h, struct net_bridge_fdb_entry, hlist);
210 if (f->dst != p)
211 continue;
212
213 if (f->is_static && !do_all)
214 continue;
215 /*
216 * if multiple ports all have the same device address
217 * then when one port is deleted, assign
218 * the local entry to other port
219 */
220 if (f->is_local) {
221 struct net_bridge_port *op;
222 list_for_each_entry(op, &br->port_list, list) {
223 if (op != p &&
224 !compare_ether_addr(op->dev->dev_addr,
225 f->addr.addr)) {
226 f->dst = op;
227 goto skip_delete;
228 }
229 }
230 }
231
232 fdb_delete(br, f);
233 skip_delete: ;
234 }
235 }
236 spin_unlock_bh(&br->hash_lock);
237}
238
239/* No locking or refcounting, assumes caller has rcu_read_lock */
240struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
241 const unsigned char *addr)
242{
243 struct hlist_node *h;
244 struct net_bridge_fdb_entry *fdb;
245
246 hlist_for_each_entry_rcu(fdb, h, &br->hash[br_mac_hash(addr)], hlist) {
247 if (!compare_ether_addr(fdb->addr.addr, addr)) {
248 if (unlikely(has_expired(br, fdb)))
249 break;
250 return fdb;
251 }
252 }
253
254 return NULL;
255}
256
257#if IS_ENABLED(CONFIG_ATM_LANE)
258/* Interface used by ATM LANE hook to test
259 * if an addr is on some other bridge port */
260int br_fdb_test_addr(struct net_device *dev, unsigned char *addr)
261{
262 struct net_bridge_fdb_entry *fdb;
263 struct net_bridge_port *port;
264 int ret;
265
266 rcu_read_lock();
267 port = br_port_get_rcu(dev);
268 if (!port)
269 ret = 0;
270 else {
271 fdb = __br_fdb_get(port->br, addr);
272 ret = fdb && fdb->dst && fdb->dst->dev != dev &&
273 fdb->dst->state == BR_STATE_FORWARDING;
274 }
275 rcu_read_unlock();
276
277 return ret;
278}
279#endif /* CONFIG_ATM_LANE */
280
281/*
282 * Fill buffer with forwarding table records in
283 * the API format.
284 */
285int br_fdb_fillbuf(struct net_bridge *br, void *buf,
286 unsigned long maxnum, unsigned long skip)
287{
288 struct __fdb_entry *fe = buf;
289 int i, num = 0;
290 struct hlist_node *h;
291 struct net_bridge_fdb_entry *f;
292
293 memset(buf, 0, maxnum*sizeof(struct __fdb_entry));
294
295 rcu_read_lock();
296 for (i = 0; i < BR_HASH_SIZE; i++) {
297 hlist_for_each_entry_rcu(f, h, &br->hash[i], hlist) {
298 if (num >= maxnum)
299 goto out;
300
301 if (has_expired(br, f))
302 continue;
303
304 /* ignore pseudo entry for local MAC address */
305 if (!f->dst)
306 continue;
307
308 if (skip) {
309 --skip;
310 continue;
311 }
312
313 /* convert from internal format to API */
314 memcpy(fe->mac_addr, f->addr.addr, ETH_ALEN);
315
316 /* due to ABI compat need to split into hi/lo */
317 fe->port_no = f->dst->port_no;
318 fe->port_hi = f->dst->port_no >> 8;
319
320 fe->is_local = f->is_local;
321 if (!f->is_static)
322 fe->ageing_timer_value = jiffies_to_clock_t(jiffies - f->updated);
323 ++fe;
324 ++num;
325 }
326 }
327
328 out:
329 rcu_read_unlock();
330
331 return num;
332}
333
334static struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head,
335 const unsigned char *addr)
336{
337 struct hlist_node *h;
338 struct net_bridge_fdb_entry *fdb;
339
340 hlist_for_each_entry(fdb, h, head, hlist) {
341 if (!compare_ether_addr(fdb->addr.addr, addr))
342 return fdb;
343 }
344 return NULL;
345}
346
347static struct net_bridge_fdb_entry *fdb_find_rcu(struct hlist_head *head,
348 const unsigned char *addr)
349{
350 struct hlist_node *h;
351 struct net_bridge_fdb_entry *fdb;
352
353 hlist_for_each_entry_rcu(fdb, h, head, hlist) {
354 if (!compare_ether_addr(fdb->addr.addr, addr))
355 return fdb;
356 }
357 return NULL;
358}
359
360static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head,
361 struct net_bridge_port *source,
362 const unsigned char *addr)
363{
364 struct net_bridge_fdb_entry *fdb;
365 fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC);
366 if (fdb) {
367 netslab_inc(BRFDB_SLAB);
368 netruninfo_add(NULL, BRFDB_ALLOC);
369 memcpy(fdb->addr.addr, addr, ETH_ALEN);
370 fdb->dst = source;
371 fdb->is_local = 0;
372 fdb->is_static = 0;
373 fdb->updated = fdb->used = jiffies;
374 hlist_add_head_rcu(&fdb->hlist, head);
375 net_run_track(PRT_BR,"create");
376 }
377 return fdb;
378}
379
380static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
381 const unsigned char *addr)
382{
383 struct hlist_head *head = &br->hash[br_mac_hash(addr)];
384 struct net_bridge_fdb_entry *fdb;
385
386 if (!is_valid_ether_addr(addr))
387 return -EINVAL;
388
389 fdb = fdb_find(head, addr);
390 if (fdb) {
391 /* it is okay to have multiple ports with same
392 * address, just use the first one.
393 */
394 if (fdb->is_local)
395 return 0;
396 br_warn(br, "adding interface %s with same address "
397 "as a received packet\n",
398 source->dev->name);
399 fdb_delete(br, fdb);
400 }
401
402 fdb = fdb_create(head, source, addr);
403 if (!fdb)
404 return -ENOMEM;
405
406 fdb->is_local = fdb->is_static = 1;
407 fdb_notify(br, fdb, RTM_NEWNEIGH);
408 return 0;
409}
410
411/* Add entry for local address of interface */
412int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
413 const unsigned char *addr)
414{
415 int ret;
416
417 spin_lock_bh(&br->hash_lock);
418 ret = fdb_insert(br, source, addr);
419 spin_unlock_bh(&br->hash_lock);
420 return ret;
421}
422
423
424//add by zhudeming Ìí¼ÓÒì³£ÁÚ¾ÓÁбí¸üУ¬µ±´æÔÚÁ½¸öÒì³£macµØÖ·Ê±£¬
425//Ìṩ¶ÔÆäÖÐÒ»¸öµØÖ·µÄ¼æÈÝÅжÏ
426int brmoniter_flag = 0;
427int usbhaved = 0;
428unsigned char ignoremac[ETH_ALEN] = {0};
429unsigned char usbmac[ETH_ALEN] = {0};
430
431void br_fdb_moniter(struct net_bridge_port *source, const unsigned char *addr)
432{
433 if(brmoniter_flag)
434 {
435 if(usbhaved == 0)
436 {
437 usbhaved == 1;
438 memcpy(usbmac, addr, ETH_ALEN);
439 }
440 else if(source->dev&& strncmp(source->dev->name,"usb",3)==0)
441 {
442 if ( (strncmp(addr, usbmac, ETH_ALEN) != 0) && (strncmp(addr, ignoremac, ETH_ALEN) != 0) )
443 {
444 panic("set wrong neigh table for usb!!!");
445 }
446 }
447 }
448}
449
450
451void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
452 const unsigned char *addr)
453{
454 struct hlist_head *head = &br->hash[br_mac_hash(addr)];
455 struct net_bridge_fdb_entry *fdb;
456
457 /* some users want to always flood. */
458 if (hold_time(br) == 0)
459 return;
460
461 /* ignore packets unless we are using this port */
462 if (!(source->state == BR_STATE_LEARNING ||
463 source->state == BR_STATE_FORWARDING))
464 return;
465
466 fdb = fdb_find_rcu(head, addr);
467 if (likely(fdb)) {
468 /* attempt to update an entry for a local interface */
469 if(fdb->dst && fdb->dst->dev && source->dev && fdb->dst->dev->ifindex != source->dev->ifindex){
470 netruninfo_add(NULL,SSMAC_CHANGE_INDEV);
471 }
472 if (unlikely(fdb->is_local)) {
473 if (net_ratelimit())
474 br_warn(br, "received packet on %s with "
475 "own address as source address\n",
476 source->dev->name);
477 } else {
478 /* fastpath: update of existing entry */
479 /*add by jiangjing*/
480 if(fdb->dst!=NULL && fdb->dst != source)
481 {
482 netruninfo_add(NULL, BR_NEIGH_VARY);
483 //panic("br_fdb_update err: %s received data ,source mac addr is %s addr,should is %s mac addr!\n",
484 //source->dev->name,fdb->dst->dev->name,source->dev->name);
485 }
486 fdb->dst = source;
487 fdb->updated = jiffies;
488 }
489 } else {
490 spin_lock_bh(&br->hash_lock);
491 if (likely(!fdb_find(head, addr))) {
492
493 //add by zhudeming
494 br_fdb_moniter(source, addr);
495
496 fdb = fdb_create(head, source, addr);
497 if (fdb)
498 fdb_notify(br, fdb, RTM_NEWNEIGH);
499 }
500 /* else we lose race and someone else inserts
501 * it first, don't bother updating
502 */
503 spin_unlock_bh(&br->hash_lock);
504 }
505}
506
507static int fdb_to_nud(const struct net_bridge_fdb_entry *fdb)
508{
509 if (fdb->is_local)
510 return NUD_PERMANENT;
511 else if (fdb->is_static)
512 return NUD_NOARP;
513 else if (has_expired(fdb->dst->br, fdb))
514 return NUD_STALE;
515 else
516 return NUD_REACHABLE;
517}
518
519static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br,
520 const struct net_bridge_fdb_entry *fdb,
521 u32 pid, u32 seq, int type, unsigned int flags)
522{
523 unsigned long now = jiffies;
524 struct nda_cacheinfo ci;
525 struct nlmsghdr *nlh;
526 struct ndmsg *ndm;
527
528 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags);
529 if (nlh == NULL)
530 return -EMSGSIZE;
531
532 ndm = nlmsg_data(nlh);
533 ndm->ndm_family = AF_BRIDGE;
534 ndm->ndm_pad1 = 0;
535 ndm->ndm_pad2 = 0;
536 ndm->ndm_flags = 0;
537 ndm->ndm_type = 0;
538 ndm->ndm_ifindex = fdb->dst ? fdb->dst->dev->ifindex : br->dev->ifindex;
539 ndm->ndm_state = fdb_to_nud(fdb);
540
541 NLA_PUT(skb, NDA_LLADDR, ETH_ALEN, &fdb->addr);
542
543 ci.ndm_used = jiffies_to_clock_t(now - fdb->used);
544 ci.ndm_confirmed = 0;
545 ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated);
546 ci.ndm_refcnt = 0;
547 NLA_PUT(skb, NDA_CACHEINFO, sizeof(ci), &ci);
548
549 return nlmsg_end(skb, nlh);
550
551nla_put_failure:
552 nlmsg_cancel(skb, nlh);
553 return -EMSGSIZE;
554}
555
556static inline size_t fdb_nlmsg_size(void)
557{
558 return NLMSG_ALIGN(sizeof(struct ndmsg))
559 + nla_total_size(ETH_ALEN) /* NDA_LLADDR */
560 + nla_total_size(sizeof(struct nda_cacheinfo));
561}
562
563static void fdb_notify(struct net_bridge *br,
564 const struct net_bridge_fdb_entry *fdb, int type)
565{
566 struct net *net = dev_net(br->dev);
567 struct sk_buff *skb;
568 int err = -ENOBUFS;
569
570 skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC);
571 if (skb == NULL)
572 goto errout;
573
574 err = fdb_fill_info(skb, br, fdb, 0, 0, type, 0);
575 if (err < 0) {
576 /* -EMSGSIZE implies BUG in fdb_nlmsg_size() */
577 WARN_ON(err == -EMSGSIZE);
578 kfree_skb(skb);
579 goto errout;
580 }
581 //print_sun(SUN_LEARN,"dev:%s,fdb_notify::rtnl_notify;type=%d,for example RTM_NEWNEIGH",br->dev->name,type);
582 rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
583 return;
584errout:
585 if (err < 0)
586 rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
587}
588
589/* Dump information about entries, in response to GETNEIGH */
590int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
591{
592 struct net *net = sock_net(skb->sk);
593 struct net_device *dev;
594 int idx = 0;
595
596 rcu_read_lock();
597 for_each_netdev_rcu(net, dev) {
598 struct net_bridge *br = netdev_priv(dev);
599 int i;
600
601 if (!(dev->priv_flags & IFF_EBRIDGE))
602 continue;
603
604 for (i = 0; i < BR_HASH_SIZE; i++) {
605 struct hlist_node *h;
606 struct net_bridge_fdb_entry *f;
607
608 hlist_for_each_entry_rcu(f, h, &br->hash[i], hlist) {
609 if (idx < cb->args[0])
610 goto skip;
611
612 if (fdb_fill_info(skb, br, f,
613 NETLINK_CB(cb->skb).pid,
614 cb->nlh->nlmsg_seq,
615 RTM_NEWNEIGH,
616 NLM_F_MULTI) < 0)
617 break;
618skip:
619 ++idx;
620 }
621 }
622 }
623 rcu_read_unlock();
624
625 cb->args[0] = idx;
626
627 return skb->len;
628}
629
630/* Update (create or replace) forwarding database entry */
631static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr,
632 __u16 state, __u16 flags)
633{
634 struct net_bridge *br = source->br;
635 struct hlist_head *head = &br->hash[br_mac_hash(addr)];
636 struct net_bridge_fdb_entry *fdb;
637
638 fdb = fdb_find(head, addr);
639 if (fdb == NULL) {
640 if (!(flags & NLM_F_CREATE))
641 return -ENOENT;
642
643 fdb = fdb_create(head, source, addr);
644 if (!fdb)
645 return -ENOMEM;
646 fdb_notify(br, fdb, RTM_NEWNEIGH);
647 } else {
648 if (flags & NLM_F_EXCL)
649 return -EEXIST;
650 }
651
652 if (fdb_to_nud(fdb) != state) {
653 if (state & NUD_PERMANENT)
654 fdb->is_local = fdb->is_static = 1;
655 else if (state & NUD_NOARP) {
656 fdb->is_local = 0;
657 fdb->is_static = 1;
658 } else
659 fdb->is_local = fdb->is_static = 0;
660
661 fdb->updated = fdb->used = jiffies;
662 fdb_notify(br, fdb, RTM_NEWNEIGH);
663 }
664
665 return 0;
666}
667
668/* Add new permanent fdb entry with RTM_NEWNEIGH */
669int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
670{
671 struct net *net = sock_net(skb->sk);
672 struct ndmsg *ndm;
673 struct nlattr *tb[NDA_MAX+1];
674 struct net_device *dev;
675 struct net_bridge_port *p;
676 const __u8 *addr;
677 int err;
678
679 ASSERT_RTNL();
680 err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
681 if (err < 0)
682 return err;
683
684 ndm = nlmsg_data(nlh);
685 if (ndm->ndm_ifindex == 0) {
686 pr_info("bridge: RTM_NEWNEIGH with invalid ifindex\n");
687 return -EINVAL;
688 }
689
690 dev = __dev_get_by_index(net, ndm->ndm_ifindex);
691 if (dev == NULL) {
692 pr_info("bridge: RTM_NEWNEIGH with unknown ifindex\n");
693 return -ENODEV;
694 }
695
696 if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) {
697 pr_info("bridge: RTM_NEWNEIGH with invalid address\n");
698 return -EINVAL;
699 }
700
701 addr = nla_data(tb[NDA_LLADDR]);
702 if (!is_valid_ether_addr(addr)) {
703 pr_info("bridge: RTM_NEWNEIGH with invalid ether address\n");
704 return -EINVAL;
705 }
706
707 if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE))) {
708 pr_info("bridge: RTM_NEWNEIGH with invalid state %#x\n", ndm->ndm_state);
709 return -EINVAL;
710 }
711
712 p = br_port_get_rtnl(dev);
713 if (p == NULL) {
714 pr_info("bridge: RTM_NEWNEIGH %s not a bridge port\n",
715 dev->name);
716 return -EINVAL;
717 }
718
719 if (ndm->ndm_flags & NTF_USE) {
720 local_bh_disable();
721 rcu_read_lock();
722 br_fdb_update(p->br, p, addr);
723 rcu_read_unlock();
724 local_bh_enable();
725 } else {
726 spin_lock_bh(&p->br->hash_lock);
727 err = fdb_add_entry(p, addr, ndm->ndm_state, nlh->nlmsg_flags);
728 spin_unlock_bh(&p->br->hash_lock);
729 }
730
731 return err;
732}
733
734static int fdb_delete_by_addr(struct net_bridge_port *p, const u8 *addr)
735{
736 struct net_bridge *br = p->br;
737 struct hlist_head *head = &br->hash[br_mac_hash(addr)];
738 struct net_bridge_fdb_entry *fdb;
739
740 fdb = fdb_find(head, addr);
741 if (!fdb)
742 return -ENOENT;
743
744 fdb_delete(p->br, fdb);
745 return 0;
746}
747
748/* Remove neighbor entry with RTM_DELNEIGH */
749int br_fdb_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
750{
751 struct net *net = sock_net(skb->sk);
752 struct ndmsg *ndm;
753 struct net_bridge_port *p;
754 struct nlattr *llattr;
755 const __u8 *addr;
756 struct net_device *dev;
757 int err;
758
759 ASSERT_RTNL();
760 if (nlmsg_len(nlh) < sizeof(*ndm))
761 return -EINVAL;
762
763 ndm = nlmsg_data(nlh);
764 if (ndm->ndm_ifindex == 0) {
765 pr_info("bridge: RTM_DELNEIGH with invalid ifindex\n");
766 return -EINVAL;
767 }
768
769 dev = __dev_get_by_index(net, ndm->ndm_ifindex);
770 if (dev == NULL) {
771 pr_info("bridge: RTM_DELNEIGH with unknown ifindex\n");
772 return -ENODEV;
773 }
774
775 llattr = nlmsg_find_attr(nlh, sizeof(*ndm), NDA_LLADDR);
776 if (llattr == NULL || nla_len(llattr) != ETH_ALEN) {
777 pr_info("bridge: RTM_DELNEIGH with invalid address\n");
778 return -EINVAL;
779 }
780
781 addr = nla_data(llattr);
782
783 p = br_port_get_rtnl(dev);
784 if (p == NULL) {
785 pr_info("bridge: RTM_DELNEIGH %s not a bridge port\n",
786 dev->name);
787 return -EINVAL;
788 }
789
790 spin_lock_bh(&p->br->hash_lock);
791 err = fdb_delete_by_addr(p, addr);
792 spin_unlock_bh(&p->br->hash_lock);
793
794 return err;
795}
796
797
798extern void tcpdumpin_sq(struct sk_buff *skb);
799
800//²Î¿¼br_dev_xmit£¬ÊµÏÖ¿ìËÙת·¢£¬Î´¹Ø×¢fdbÖеÄÁÙʱ״̬,ÁíÍ⣬ÐèҪȷ±£skb->mac_header±»ÓÐЧ¸³Öµ£¬·ñÔòÎÞ·¨»ñÈ¡µ½MACµØÖ·
801//ĿǰδʹÓÃÇý¶¯µ½Çý¶¯µÄ×îÓÅת·¢£¬Ó¦¸ÃûÓÐÎÊÌ⣬ºóÐøÒ»µ©Ê¹Óã¬ÐèÒªÔÚtry_fastnat_for_macdataÀà½Ó¿ÚÖÐÌí¼Óskb_reset_mac_headerÀ´½â¾ö
802int fast_br(struct sk_buff *skb)
803{
804 const unsigned char *dest = NULL;
805 struct hlist_head *head;
806 struct net_bridge_fdb_entry *fdb;
807 struct net_bridge_port *p;
808 struct net_bridge *br;
809
810 if(!skb->dev)
811 {
812 //print_sun(SUN_DBG, "fast_br skb->dev err skb->dev = %x\n", skb->dev);
813 return 0;
814 }
815
816 if(skb->mac_header == 0 || skb->mac_header == ~0U)
817 {
818 //panic("driver not set macheader !!!\n"); for xlat
819 return 0;
820 }
821
822 dest = eth_hdr(skb)->h_dest;
823
824 //²ÎÕÕbr_del_if½Ó¿Ú£¬È·±£Èë¿ÚdevÊÇÇŵ㣬ÒÔ·ÀÖ¹wan1µÈÍâÍø¿Úµ±ÇÅµã½øÐд¦Àí
825 p = br_port_get_rtnl(skb->dev);
826 if (p == NULL || p->br == NULL)
827 {
828 //print_sun(SUN_DBG, "fast_br br_port_get_rtnl err p = %x\n", p);
829 return 0;
830 }
831
832 br = p->br;
833 //еÄlinuxÄÚºËÖУ¬ÐèÒª½øÐÐif (br->vlan_enabled) return 0;ÒÔ½â¾övlan×÷ΪÇŵãÎÊÌ⣬»òÕß¶ÏÑÔÒ²¿É
834 head = &br->hash[br_mac_hash(dest)];
835
836 if((fdb = fdb_find_rcu(head, dest)) != NULL)
837 {
838 //ÈôÄ¿µÄMACµØÖ·ÎªÔ¶¶Ë£¬·½¿ÉÖ´ÐÐfastbr
839 if((!fdb->is_local) && fdb->dst && fdb->dst->dev &&
840 (((fdb->dst->flags & BR_HAIRPIN_MODE) || skb->dev != fdb->dst->dev) &&fdb->dst->state == BR_STATE_FORWARDING))
841 {
842 // tcpdumpin_sq(skb);
843 fast_tcpdump(skb);
844 skb->dev = fdb->dst->dev;
845 skb->isFastbr = 1;
846 fdb->updated = jiffies;
847 skb->now_location |= FASTBR_SUCC;
848 skb_rest_data_byproto(skb);
849 //´Ë´¦Ó¦¸Ã¿ÉÒÔÖ±½Óµ÷ÓÃdev_queue_xmit½Ó¿Ú£¬ºóÐø¸ð±ò¿É¹Ø×¢ÏÂ
850 br_dev_queue_push_xmit(skb);
851 return 1;
852 }
853
854 //»Ø»·µÄÊý¾ÝÖ±½Ó¶ªÆú
855 if((!fdb->is_local) && fdb->dst && fdb->dst->dev &&
856 (skb->dev == fdb->dst->dev) && fdb->dst->state == BR_STATE_FORWARDING)
857 {
858 skbinfo_add(NULL,SKB_LOOP);
859 //print_sun(SUN_ERR,"fast_br loop data discarded, dev:%s \n", skb->dev->name);
860 kfree_skb(skb);
861 return 1;
862 }
863 }
864 //print_sun(SUN_DBG, "fast_br fdb_find_rcu err fdb = %x \n",fdb);
865 return 0;
866}
867EXPORT_SYMBOL(fast_br);
868
869
870//ÒÔÄ¿µÄMAC×÷ΪƥÅäÌõ¼þ£¬µ±Èë²ÎdevΪbr0ʱ£¬·µ»ØÖµÎª¶þ²ãÇŵ㣬·ñÔòÈÔȻΪÈë²Îdev£¬ÕâÑù¿ÉÒÔ´ïµ½ÈÝ´íÄÜÁ¦£»È¡´úfastL2DBFind
871struct net_device *getbrport_bydst(struct net_device *dev,unsigned char *dest)
872{
873 struct hlist_head *head;
874 struct net_bridge_fdb_entry *fdb;
875 struct net_bridge_port *p;
876 struct net_bridge *br;
877
878 //±ØÐëÊÇbr0É豸
879 if (dev == NULL || !(dev->priv_flags & IFF_EBRIDGE))
880 return dev;
881
882 br = netdev_priv(dev);
883 //еÄlinuxÄÚºËÖУ¬ÐèÒª½øÐÐif (br->vlan_enabled) return dev;ÒÔ½â¾övlan×÷ΪÇŵãÎÊÌ⣬»òÕß¶ÏÑÔÒ²¿É
884 head = &br->hash[br_mac_hash(dest)];
885
886 if((fdb = fdb_find_rcu(head, dest)) != NULL)
887 {
888 //ÈôÄ¿µÄMACµØÖ·ÎªÔ¶¶Ë£¬·½¿ÉÖ´ÐÐfastbr
889 if((!fdb->is_local) && fdb->dst && fdb->dst->dev &&
890 (fdb->dst->state == BR_STATE_FORWARDING)) //(fdb->dst->flags & BR_HAIRPIN_MODE)
891 {
892 return fdb->dst->dev;
893 }
894 }
895 return dev;
896}
897extern void fast_tcpdump(struct sk_buff *skb);
898extern struct neigh_table arp_tbl;
899extern char default_route_name[IFNAMSIZ];
900char default_br_name[IFNAMSIZ] = {0};
901int fast_fwd_ip4addr_conflict(struct sk_buff *skb)
902{
903 struct iphdr *iph = ip_hdr(skb);
904 __be32 saddr,daddr,wan_ip,br_ip=0,br_bcast=0;
905 struct net_device* in_dev = NULL;
906 struct net_device* out_dev = NULL;
907 struct ethhdr *eth;
908 struct net_bridge_port *p;
909 struct net_bridge *br = NULL;
910 struct net_device *default_route_dev;
911 struct net_device *default_br_dev;
912 struct in_device *ip_ptr;
913
914 if(iph->version != 4 || skb->indev == NULL)
915 {
916 return 0;
917 }
918 default_route_dev = dev_get_by_name(&init_net, default_route_name);
919 if(default_route_dev == NULL)
920 {
921 return 0;
922 }
923 ip_ptr = __in_dev_get_rtnl(default_route_dev);
924 if(ip_ptr && ip_ptr->ifa_list)
925 {
926 wan_ip = ip_ptr->ifa_list->ifa_local;
927 }
928 else
929 {
930 default_br_name[0] = 0;
931 dev_put(default_route_dev);
932 return 0;
933 }
934 in_dev = skb->indev;
935 saddr = iph->saddr;
936 daddr = iph->daddr;
937 p = br_port_get_rtnl(in_dev);
938 if (p != NULL)
939 {
940 br = p->br;
941 if (br && br->dev && strncmp(br->dev->name, default_br_name, IFNAMSIZ-1))
942 {
943 strncpy(default_br_name, br->dev->name, IFNAMSIZ-1);
944 }
945 }
946 default_br_dev = dev_get_by_name(&init_net, default_br_name);
947 if(default_br_dev)
948 {
949 ip_ptr = __in_dev_get_rtnl(default_br_dev);
950 if(ip_ptr && ip_ptr->ifa_list)
951 {
952 br_ip = ip_ptr->ifa_list->ifa_local;
953 br_bcast = ip_ptr->ifa_list->ifa_broadcast;
954 }
955 }
956 else
957 {
958 dev_put(default_route_dev);
959 return 0;
960 }
961 if(br && ((daddr == br_ip) || (daddr == br_bcast) || (daddr == wan_ip)))
962 {
963 //printk("@!@1saddr=%08x,daddr=%08x,br_ip=%08x,br_bcast=%08x,wan_ip=%08x\n",saddr, daddr, br_ip, br_bcast, wan_ip);
964 if (IPPROTO_UDP == iph->protocol)
965 {
966 struct udphdr *udph = (struct udphdr *)(skb->data + iph->ihl * 4);
967 if(udph->source == 0x4300 || udph->source == 0x4400
968 || udph->dest == 0x4300 || udph->dest == 0x4400)
969 {
970 //printk("@!@dhcp packet\n");
971 dev_put(default_route_dev);
972 dev_put(default_br_dev);
973 return 0;
974 }
975 }
976 out_dev = default_route_dev;
977 skb_push(skb, ETH_HLEN);
978 eth = (struct ethhdr*)(skb->data);
979 memcpy(eth->h_source, in_dev->dev_addr, ETH_ALEN);
980 memcpy(eth->h_dest, out_dev->dev_addr, ETH_ALEN);
981 fast_tcpdump(skb);
982 skb->dev = out_dev;
983 }
984 else if(in_dev == default_route_dev && ((saddr == br_ip) || (saddr == br_bcast) || (saddr == wan_ip)))
985 {
986 struct neighbour *neigh = neigh_lookup(&arp_tbl, &daddr, default_br_dev);
987 //printk("@!@2saddr=%08x,daddr=%08x,neigh=%08x,wan_ip=%08x\n",saddr, daddr, neigh, wan_ip);
988 if(neigh)
989 {
990 //printk("@!@neigh=%s\n",neigh->dev->name);
991 out_dev = getbrport_bydst(default_br_dev,neigh->ha);
992 if(out_dev)
993 {
994 //printk("@!@out_dev=%s\n",out_dev->name);
995 skb_push(skb, ETH_HLEN);
996 eth = (struct ethhdr*)(skb->data);
997 memcpy(eth->h_source, out_dev->dev_addr, ETH_ALEN);
998 memcpy(eth->h_dest, neigh->ha, ETH_ALEN);
999 //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]);
1000 }
1001 neigh_release(neigh);
1002 }
1003 if(out_dev == NULL)
1004 {
1005 printk("@!@dev: br port not found\n");
1006 dev_put(default_route_dev);
1007 dev_put(default_br_dev);
1008 return 0;
1009 }
1010 fast_tcpdump(skb);
1011 skb->dev = out_dev;
1012 }
1013 else
1014 {
1015 dev_put(default_route_dev);
1016 dev_put(default_br_dev);
1017 return 0;
1018 }
1019
1020 eth->h_proto = htons(ETH_P_IP);
1021 skb->now_location |= FASTNAT_SUCC;
1022 dev_queue_xmit(skb);
1023
1024 dev_put(default_route_dev);
1025 dev_put(default_br_dev);
1026 return 1;
1027}
1028
1029int fast_for_multicast(struct sk_buff *skb)
1030{
1031 if (skb->indev && !strncmp(skb->indev->name, default_route_name, IFNAMSIZ-1))
1032 {
1033 struct net_device* dev = NULL;
1034 struct net_bridge *br;
1035 struct net_bridge_port *p;
1036
1037 dev = dev_get_by_name(&init_net, default_br_name);
1038 if (dev == NULL || !(dev->priv_flags & IFF_EBRIDGE))
1039 {
1040 printk("@!@dev: br not found\n");
1041 if(dev != NULL)
1042 {
1043 dev_put(dev);
1044 }
1045 return 0;
1046 }
1047 br = (struct net_bridge *)netdev_priv(dev);
1048 p = br_get_port(br, 1);
1049 if(p && p->dev)
1050 {
1051 struct ethhdr *eth;
1052 struct iphdr *iph = ip_hdr(skb);
1053
1054 skb_push(skb, ETH_HLEN);
1055 eth = (struct ethhdr *)skb->data;
1056 memcpy(eth->h_source, p->dev->dev_addr, ETH_ALEN);
1057 ip_eth_mc_map(iph->daddr, eth->h_dest);
1058 eth->h_proto = htons(ETH_P_IP);
1059 skb->dev = p->dev;
1060 skb->now_location |= FASTNAT_SUCC;
1061 dev_queue_xmit(skb);
1062 dev_put(dev);
1063 return 1;
1064 }
1065 dev_put(dev);
1066 }
1067 return 0;
1068}
1069