1/* Modified by Broadcom Corp. Portions Copyright (c) Broadcom Corp, 2012. */ 2/* 3 * Forwarding database 4 * Linux ethernet bridge 5 * 6 * Authors: 7 * Lennert Buytenhek <buytenh@gnu.org> 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License 11 * as published by the Free Software Foundation; either version 12 * 2 of the License, or (at your option) any later version. 13 */ 14 15#include <linux/kernel.h> 16#include <linux/init.h> 17#include <linux/rculist.h> 18#include <linux/spinlock.h> 19#include <linux/times.h> 20#include <linux/netdevice.h> 21#include <linux/etherdevice.h> 22#include <linux/jhash.h> 23#include <linux/random.h> 24#include <linux/slab.h> 25#include <asm/atomic.h> 26#include <asm/unaligned.h> 27#include "br_private.h" 28#ifdef HNDCTF 29#include <linux/if.h> 30#include <linux/if_vlan.h> 31#include <linux/if_ether.h> 32#include <net/arp.h> 33#include <typedefs.h> 34#include <osl.h> 35#include <ctf/hndctf.h> 36#else 37#define BCMFASTPATH_HOST 38#endif /* HNDCTF */ 39 40#ifdef HNDCTF 41static void 42br_brc_init(ctf_brc_t *brc, unsigned char *ea, struct net_device *rxdev, unsigned char *sip) 43{ 44 memset(brc, 0, sizeof(ctf_brc_t)); 45 46 memcpy(brc->dhost.octet, ea, ETH_ALEN); 47 48 if (rxdev->priv_flags & IFF_802_1Q_VLAN) { 49 brc->txifp = (void *)vlan_dev_real_dev(rxdev); 50 brc->vid = vlan_dev_vlan_id(rxdev); 51 brc->action = ((vlan_dev_vlan_flags(rxdev) & 1) ? 52 CTF_ACTION_TAG : CTF_ACTION_UNTAG); 53 } else { 54 brc->txifp = (void *)rxdev; 55 brc->action = CTF_ACTION_UNTAG; 56 } 57 58 if (sip) 59 memcpy(&brc->ip, sip, IPV4_ADDR_LEN); 60 61#ifdef DEBUG 62 printk("mac %02x:%02x:%02x:%02x:%02x:%02x\n", 63 brc->dhost.octet[0], brc->dhost.octet[1], 64 brc->dhost.octet[2], brc->dhost.octet[3], 65 brc->dhost.octet[4], brc->dhost.octet[5]); 66 printk("vid: %d action %x\n", brc->vid, brc->action); 67 printk("txif: %s\n", ((struct net_device *)brc->txifp)->name); 68#endif 69 70 return; 71} 72 73/* 74 * Add bridge cache entry. 75 */ 76void 77br_brc_add(unsigned char *ea, struct net_device *rxdev, struct sk_buff *skb) 78{ 79 ctf_brc_t brc_entry, *brcp; 80 struct ethhdr *eth; 81 struct arphdr *arp; 82 unsigned char *arp_ptr = NULL; 83 84 /* Add brc entry only if packet is received on ctf 85 * enabled interface 86 */ 87 if (!ctf_isenabled(kcih, ((rxdev->priv_flags & IFF_802_1Q_VLAN) ? 88 vlan_dev_real_dev(rxdev) : rxdev))) 89 return; 90 91 if (skb) { 92 /* Only handle ARP Reply */ 93 eth = (struct ethhdr *)skb_mac_header(skb); 94 if (eth->h_proto == htons(ETHER_TYPE_ARP)) { 95 arp = (struct arphdr *)skb_network_header(skb); 96 if (arp->ar_hrd == htons(ARPHRD_ETHER) && 97 arp->ar_pro == htons(ETH_P_IP) && 98 arp->ar_op == htons(ARPOP_REPLY)) { 99 /* Extract source ip fields */ 100 arp_ptr = (unsigned char *)(arp+1); 101 arp_ptr += skb->dev->addr_len; 102 } 103 } 104 } 105 106 br_brc_init(&brc_entry, ea, rxdev, arp_ptr); 107 108#ifdef DEBUG 109 printk("%s: Adding brc entry\n", __FUNCTION__); 110#endif 111 112 /* Add the bridge cache entry */ 113 if ((brcp = ctf_brc_lkup(kcih, ea)) == NULL) 114 ctf_brc_add(kcih, &brc_entry); 115 else { 116 ctf_brc_release(kcih, brcp); 117 ctf_brc_update(kcih, &brc_entry); 118 } 119 120 return; 121} 122 123#endif /* HNDCTF */ 124 125static struct kmem_cache *br_fdb_cache __read_mostly; 126static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, 127 const unsigned char *addr); 128 129static u32 fdb_salt __read_mostly; 130 131int __init br_fdb_init(void) 132{ 133 br_fdb_cache = kmem_cache_create("bridge_fdb_cache", 134 sizeof(struct net_bridge_fdb_entry), 135 0, 136 SLAB_HWCACHE_ALIGN, NULL); 137 if (!br_fdb_cache) 138 return -ENOMEM; 139 140 get_random_bytes(&fdb_salt, sizeof(fdb_salt)); 141 return 0; 142} 143 144void br_fdb_fini(void) 145{ 146 kmem_cache_destroy(br_fdb_cache); 147} 148 149 150/* if topology_changing then use forward_delay (default 15 sec) 151 * otherwise keep longer (default 5 minutes) 152 */ 153static inline unsigned long hold_time(const struct net_bridge *br) 154{ 155 return br->topology_change ? br->forward_delay : br->ageing_time; 156} 157 158static inline int has_expired(const struct net_bridge *br, 159 const struct net_bridge_fdb_entry *fdb) 160{ 161 return !fdb->is_static && 162 time_before_eq(fdb->ageing_timer + hold_time(br), jiffies); 163} 164 165static inline int br_mac_hash(const unsigned char *mac) 166{ 167 /* use 1 byte of OUI cnd 3 bytes of NIC */ 168 u32 key = get_unaligned((u32 *)(mac + 2)); 169 return jhash_1word(key, fdb_salt) & (BR_HASH_SIZE - 1); 170} 171 172static void fdb_rcu_free(struct rcu_head *head) 173{ 174 struct net_bridge_fdb_entry *ent 175 = container_of(head, struct net_bridge_fdb_entry, rcu); 176 kmem_cache_free(br_fdb_cache, ent); 177} 178 179static inline void fdb_delete(struct net_bridge_fdb_entry *f) 180{ 181 hlist_del_rcu(&f->hlist); 182 183#ifdef HNDCTF 184 /* Delete the corresponding brc entry when it expires 185 * or deleted by user. 186 */ 187 ctf_brc_delete(kcih, f->addr.addr); 188#endif /* HNDCTF */ 189 190 call_rcu(&f->rcu, fdb_rcu_free); 191} 192 193void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) 194{ 195 struct net_bridge *br = p->br; 196 int i; 197 198 spin_lock_bh(&br->hash_lock); 199 200 /* Search all chains since old address/hash is unknown */ 201 for (i = 0; i < BR_HASH_SIZE; i++) { 202 struct hlist_node *h; 203 hlist_for_each(h, &br->hash[i]) { 204 struct net_bridge_fdb_entry *f; 205 206 f = hlist_entry(h, struct net_bridge_fdb_entry, hlist); 207 if (f->dst == p && f->is_local) { 208 /* maybe another port has same hw addr? */ 209 struct net_bridge_port *op; 210 list_for_each_entry(op, &br->port_list, list) { 211 if (op != p && 212 !compare_ether_addr(op->dev->dev_addr, 213 f->addr.addr)) { 214 f->dst = op; 215 goto insert; 216 } 217 } 218 219 /* delete old one */ 220 fdb_delete(f); 221 goto insert; 222 } 223 } 224 } 225 insert: 226 /* insert new address, may fail if invalid address or dup. */ 227 fdb_insert(br, p, newaddr); 228 229 spin_unlock_bh(&br->hash_lock); 230} 231 232void br_fdb_cleanup(unsigned long _data) 233{ 234 struct net_bridge *br = (struct net_bridge *)_data; 235 unsigned long delay = hold_time(br); 236 unsigned long next_timer = jiffies + br->ageing_time; 237 int i; 238 239 spin_lock_bh(&br->hash_lock); 240 for (i = 0; i < BR_HASH_SIZE; i++) { 241 struct net_bridge_fdb_entry *f; 242 struct hlist_node *h, *n; 243 244 hlist_for_each_entry_safe(f, h, n, &br->hash[i], hlist) { 245 unsigned long this_timer; 246 if (f->is_static) 247 continue; 248 this_timer = f->ageing_timer + delay; 249 if (time_before_eq(this_timer, jiffies)) { 250#ifdef HNDCTF 251 ctf_brc_t *brcp; 252 253 /* Before expiring the fdb entry check the brc 254 * live counter to make sure there are no frames 255 * on this connection for timeout period. 256 */ 257 brcp = ctf_brc_lkup(kcih, f->addr.addr); 258 if (brcp != NULL) { 259 uint32 arpip = 0; 260 261 if (brcp->live > 0) { 262 brcp->live = 0; 263 brcp->hitting = 0; 264 ctf_brc_release(kcih, brcp); 265 f->ageing_timer = jiffies; 266 continue; 267 } else if (brcp->hitting > 0) { 268 /* When bridge deletes a CTF hitting cache entry, 269 /* we use DHCP "probes" (ARP Request) to trigger 270 * the CTF fast path restoration. 271 */ 272 brcp->hitting = 0; 273 if (brcp->ip != 0) 274 arpip = brcp->ip; 275 } 276 ctf_brc_release(kcih, brcp); 277 if (arpip != 0) 278 arp_send(ARPOP_REQUEST, ETH_P_ARP, 279 arpip, br->dev, 0, NULL, 280 NULL, NULL); 281 } 282#endif /* HNDCTF */ 283 fdb_delete(f); 284 } else if (time_before(this_timer, next_timer)) 285 next_timer = this_timer; 286 } 287 } 288 spin_unlock_bh(&br->hash_lock); 289 290 mod_timer(&br->gc_timer, round_jiffies_up(next_timer)); 291} 292 293/* Completely flush all dynamic entries in forwarding database.*/ 294void br_fdb_flush(struct net_bridge *br) 295{ 296 int i; 297 298 spin_lock_bh(&br->hash_lock); 299 for (i = 0; i < BR_HASH_SIZE; i++) { 300 struct net_bridge_fdb_entry *f; 301 struct hlist_node *h, *n; 302 hlist_for_each_entry_safe(f, h, n, &br->hash[i], hlist) { 303 if (!f->is_static) 304 fdb_delete(f); 305 } 306 } 307 spin_unlock_bh(&br->hash_lock); 308} 309 310/* Flush all entries refering to a specific port. 311 * if do_all is set also flush static entries 312 */ 313void br_fdb_delete_by_port(struct net_bridge *br, 314 const struct net_bridge_port *p, 315 int do_all) 316{ 317 int i; 318 319 spin_lock_bh(&br->hash_lock); 320 for (i = 0; i < BR_HASH_SIZE; i++) { 321 struct hlist_node *h, *g; 322 323 hlist_for_each_safe(h, g, &br->hash[i]) { 324 struct net_bridge_fdb_entry *f 325 = hlist_entry(h, struct net_bridge_fdb_entry, hlist); 326 if (f->dst != p) 327 continue; 328 329 if (f->is_static && !do_all) 330 continue; 331 /* 332 * if multiple ports all have the same device address 333 * then when one port is deleted, assign 334 * the local entry to other port 335 */ 336 if (f->is_local) { 337 struct net_bridge_port *op; 338 list_for_each_entry(op, &br->port_list, list) { 339 if (op != p && 340 !compare_ether_addr(op->dev->dev_addr, 341 f->addr.addr)) { 342 f->dst = op; 343 goto skip_delete; 344 } 345 } 346 } 347 348 fdb_delete(f); 349 skip_delete: ; 350 } 351 } 352 spin_unlock_bh(&br->hash_lock); 353} 354 355/* No locking or refcounting, assumes caller has rcu_read_lock */ 356struct net_bridge_fdb_entry * BCMFASTPATH_HOST __br_fdb_get(struct net_bridge *br, 357 const unsigned char *addr) 358{ 359 struct hlist_node *h; 360 struct net_bridge_fdb_entry *fdb; 361 362 hlist_for_each_entry_rcu(fdb, h, &br->hash[br_mac_hash(addr)], hlist) { 363 if (!compare_ether_addr(fdb->addr.addr, addr)) { 364 if (unlikely(has_expired(br, fdb))) 365 break; 366 return fdb; 367 } 368 } 369 370 return NULL; 371} 372 373#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) 374/* Interface used by ATM LANE hook to test 375 * if an addr is on some other bridge port */ 376int br_fdb_test_addr(struct net_device *dev, unsigned char *addr) 377{ 378 struct net_bridge_fdb_entry *fdb; 379 int ret; 380 381 if (!br_port_exists(dev)) 382 return 0; 383 384 rcu_read_lock(); 385 fdb = __br_fdb_get(br_port_get_rcu(dev)->br, addr); 386 ret = fdb && fdb->dst->dev != dev && 387 fdb->dst->state == BR_STATE_FORWARDING; 388 rcu_read_unlock(); 389 390 return ret; 391} 392#endif /* CONFIG_ATM_LANE */ 393 394/* 395 * Fill buffer with forwarding table records in 396 * the API format. 397 */ 398int br_fdb_fillbuf(struct net_bridge *br, void *buf, 399 unsigned long maxnum, unsigned long skip) 400{ 401 struct __fdb_entry *fe = buf; 402 int i, num = 0; 403 struct hlist_node *h; 404 struct net_bridge_fdb_entry *f; 405 406 memset(buf, 0, maxnum*sizeof(struct __fdb_entry)); 407 408 rcu_read_lock(); 409 for (i = 0; i < BR_HASH_SIZE; i++) { 410 hlist_for_each_entry_rcu(f, h, &br->hash[i], hlist) { 411 if (num >= maxnum) 412 goto out; 413 414 if (has_expired(br, f)) 415 continue; 416 417 if (skip) { 418 --skip; 419 continue; 420 } 421 422 /* convert from internal format to API */ 423 memcpy(fe->mac_addr, f->addr.addr, ETH_ALEN); 424 425 /* due to ABI compat need to split into hi/lo */ 426 fe->port_no = f->dst->port_no; 427 fe->port_hi = f->dst->port_no >> 8; 428 429 fe->is_local = f->is_local; 430 if (!f->is_static) 431 fe->ageing_timer_value = jiffies_to_clock_t(jiffies - f->ageing_timer); 432 ++fe; 433 ++num; 434 } 435 } 436 437 out: 438 rcu_read_unlock(); 439 440 return num; 441} 442 443static inline struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head, 444 const unsigned char *addr) 445{ 446 struct hlist_node *h; 447 struct net_bridge_fdb_entry *fdb; 448 449 hlist_for_each_entry_rcu(fdb, h, head, hlist) { 450 if (!compare_ether_addr(fdb->addr.addr, addr)) 451 return fdb; 452 } 453 return NULL; 454} 455 456#ifdef HNDCTF 457static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, 458 struct net_bridge_port *source, 459 const unsigned char *addr, 460 int is_local, 461 struct sk_buff *skb) 462#else 463static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, 464 struct net_bridge_port *source, 465 const unsigned char *addr, 466 int is_local) 467#endif 468{ 469 struct net_bridge_fdb_entry *fdb; 470 471 fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC); 472 if (fdb) { 473 memcpy(fdb->addr.addr, addr, ETH_ALEN); 474 hlist_add_head_rcu(&fdb->hlist, head); 475 476 fdb->dst = source; 477 fdb->is_local = is_local; 478 fdb->is_static = is_local; 479 fdb->ageing_timer = jiffies; 480 481 /* Add bridge cache entry for non local hosts */ 482#ifdef HNDCTF 483 if (!is_local && (source->state == BR_STATE_FORWARDING)) 484 br_brc_add((unsigned char *)addr, source->dev, skb); 485#endif /* HNDCTF */ 486 } 487 return fdb; 488} 489 490static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, 491 const unsigned char *addr) 492{ 493 struct hlist_head *head = &br->hash[br_mac_hash(addr)]; 494 struct net_bridge_fdb_entry *fdb; 495 496 if (!is_valid_ether_addr(addr)) 497 return -EINVAL; 498 499 fdb = fdb_find(head, addr); 500 if (fdb) { 501 /* it is okay to have multiple ports with same 502 * address, just use the first one. 503 */ 504 if (fdb->is_local) 505 return 0; 506 br_warn(br, "adding interface %s with same address " 507 "as a received packet\n", 508 source->dev->name); 509 fdb_delete(fdb); 510 } 511 512#ifdef HNDCTF 513 if (!fdb_create(head, source, addr, 1, NULL)) 514#else 515 if (!fdb_create(head, source, addr, 1)) 516#endif 517 return -ENOMEM; 518 519 return 0; 520} 521 522int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source, 523 const unsigned char *addr) 524{ 525 int ret; 526 527 spin_lock_bh(&br->hash_lock); 528 ret = fdb_insert(br, source, addr); 529 spin_unlock_bh(&br->hash_lock); 530 return ret; 531} 532 533#ifdef HNDCTF 534void BCMFASTPATH_HOST br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, 535 const unsigned char *addr, struct sk_buff *skb) 536#else 537void BCMFASTPATH_HOST br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, 538 const unsigned char *addr) 539#endif 540{ 541 struct hlist_head *head = &br->hash[br_mac_hash(addr)]; 542 struct net_bridge_fdb_entry *fdb; 543 544 /* some users want to always flood. */ 545 if (hold_time(br) == 0) 546 return; 547 548 /* ignore packets unless we are using this port */ 549 if (!(source->state == BR_STATE_LEARNING || 550 source->state == BR_STATE_FORWARDING)) 551 return; 552 553 fdb = fdb_find(head, addr); 554 if (likely(fdb)) { 555 /* attempt to update an entry for a local interface */ 556 if (unlikely(fdb->is_local)) { 557 if (net_ratelimit()) 558 br_debug(br, "received packet on %s with " 559 "own address as source address\n", 560 source->dev->name); 561 } else { 562 /* fastpath: update of existing entry */ 563#ifdef HNDCTF 564 /* Add the entry if the addr is new, or 565 * update the brc entry incase the host moved from 566 * one bridge to another or to a different port under 567 * the same bridge. 568 */ 569 if (source->state == BR_STATE_FORWARDING) 570 br_brc_add((unsigned char *)addr, source->dev, skb); 571#endif /* HNDCTF */ 572 573 fdb->dst = source; 574 fdb->ageing_timer = jiffies; 575 } 576 } else { 577 spin_lock(&br->hash_lock); 578 if (!fdb_find(head, addr)) 579#ifdef HNDCTF 580 fdb_create(head, source, addr, 0, skb); 581#else 582 fdb_create(head, source, addr, 0); 583#endif 584 /* else we lose race and someone else inserts 585 * it first, don't bother updating 586 */ 587 spin_unlock(&br->hash_lock); 588 } 589} 590