[Bridge] [PATCH 2.6.5] (6/9) bridge - forwarding database changes

Stephen Hemminger shemminger at osdl.org
Tue Apr 13 15:28:38 PDT 2004


Make forwarding database more robust.  
  + Don't insert invalid ether address,
  + Report errors back so adding an interface to bridge can fail
  + get rid of unneeded explicit pads in data structure
  + replace bitfields with byte's for simple booleans.

diff -Nru a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
--- a/net/bridge/br_fdb.c	Mon Apr 12 16:10:50 2004
+++ b/net/bridge/br_fdb.c	Mon Apr 12 16:10:50 2004
@@ -17,6 +17,7 @@
 #include <linux/spinlock.h>
 #include <linux/if_bridge.h>
 #include <linux/times.h>
+#include <linux/etherdevice.h>
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
 #include "br_private.h"
@@ -243,12 +244,16 @@
 	return num;
 }
 
-void br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
-		   const unsigned char *addr, int is_local)
+int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
+		  const unsigned char *addr, int is_local)
 {
 	struct hlist_node *h;
 	struct net_bridge_fdb_entry *fdb;
 	int hash = br_mac_hash(addr);
+	int ret = 0;
+
+	if (!is_valid_ether_addr(addr))
+		return -EADDRNOTAVAIL;
 
 	write_lock_bh(&br->hash_lock);
 	hlist_for_each(h, &br->hash[hash]) {
@@ -264,6 +269,7 @@
 					printk(KERN_WARNING "%s: received packet with "
 					       " own address as source address\n",
 					       source->dev->name);
+				ret = -EEXIST;
 				goto out;
 			}
 
@@ -278,8 +284,10 @@
 	}
 
 	fdb = kmalloc(sizeof(*fdb), GFP_ATOMIC);
-	if (fdb == NULL) 
+	if (unlikely(fdb == NULL)) {
+		ret = -ENOMEM;
 		goto out;
+	}
 
 	memcpy(fdb->addr.addr, addr, ETH_ALEN);
 	atomic_set(&fdb->use_count, 1);
@@ -298,4 +306,6 @@
 	list_add_tail(&fdb->age_list, &br->age_list);
  out:
 	write_unlock_bh(&br->hash_lock);
+
+	return ret;
 }
diff -Nru a/net/bridge/br_if.c b/net/bridge/br_if.c
--- a/net/bridge/br_if.c	Mon Apr 12 16:10:50 2004
+++ b/net/bridge/br_if.c	Mon Apr 12 16:10:50 2004
@@ -277,13 +277,15 @@
 	else if (IS_ERR(p = new_nbp(br, dev, cost)))
 		err = PTR_ERR(p);
 
+ 	else if ((err = br_fdb_insert(br, p, dev->dev_addr, 1)))
+ 		 destroy_nbp(p);
+ 
 	else {
 		dev_set_promiscuity(dev, 1);
 
 		list_add_rcu(&p->list, &br->port_list);
 
 		br_stp_recalculate_bridge_id(br);
-		br_fdb_insert(br, p, dev->dev_addr, 1);
 		if ((br->dev->flags & IFF_UP) && (dev->flags & IFF_UP))
 			br_stp_enable_port(p);
 
diff -Nru a/net/bridge/br_private.h b/net/bridge/br_private.h
--- a/net/bridge/br_private.h	Mon Apr 12 16:10:50 2004
+++ b/net/bridge/br_private.h	Mon Apr 12 16:10:50 2004
@@ -37,7 +37,6 @@
 struct mac_addr
 {
 	unsigned char	addr[6];
-	unsigned char	pad[2];
 };
 
 struct net_bridge_fdb_entry
@@ -48,8 +47,8 @@
 	atomic_t			use_count;
 	unsigned long			ageing_timer;
 	mac_addr			addr;
-	unsigned			is_local:1;
-	unsigned			is_static:1;
+	unsigned char			is_local;
+	unsigned char			is_static;
 };
 
 struct net_bridge_port
@@ -135,10 +134,10 @@
 extern void br_fdb_put(struct net_bridge_fdb_entry *ent);
 extern int  br_fdb_get_entries(struct net_bridge *br, void __user *buf,
 			       int maxnum, int offset);
-extern void br_fdb_insert(struct net_bridge *br,
-			  struct net_bridge_port *source,
-			  const unsigned char *addr,
-			  int is_local);
+extern int br_fdb_insert(struct net_bridge *br,
+			 struct net_bridge_port *source,
+			 const unsigned char *addr,
+			 int is_local);
 
 /* br_forward.c */
 extern void br_deliver(const struct net_bridge_port *to,



More information about the Bridge mailing list