patch-2.0.37 linux/net/bridge/br.c

Next file: linux/net/bridge/br_tree.c
Previous file: linux/net/appletalk/ddp.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.36/linux/net/bridge/br.c linux/net/bridge/br.c
@@ -91,6 +91,8 @@
 
 void transmit_config(int port_no)			  /* (4.6.1)	 */
 {
+	if(!(br_stats.flags & BR_UP))
+		return; /* this should not happen but happens */
 	if (hold_timer[port_no].active) {	  /* (4.6.1.3.1)	 */
 		port_info[port_no].config_pending = TRUE;	/* (4.6.1.3.1)	 */
 	} else {				  /* (4.6.1.3.2)	 */
@@ -871,11 +873,12 @@
 
 int send_config_bpdu(int port_no, Config_bpdu *config_bpdu)
 {
-struct sk_buff *skb;
-struct device *dev = port_info[port_no].dev;
-int size;
-unsigned long flags;
+	struct sk_buff *skb;
+	struct device *dev = port_info[port_no].dev;
+	int size;
 	
+	if(!(br_stats.flags & BR_UP))
+		return(-1); /* this should not happen but happens */
 	if (port_info[port_no].state == Disabled) {
 		printk(KERN_DEBUG "send_config_bpdu: port %i not valid\n",port_no);
 		return(-1);
@@ -927,11 +930,12 @@
 
 int send_tcn_bpdu(int port_no, Tcn_bpdu *bpdu)
 {
-struct sk_buff *skb;
-struct device *dev = port_info[port_no].dev;
-int size;
-unsigned long flags;
+	struct sk_buff *skb;
+	struct device *dev = port_info[port_no].dev;
+	int size;
 	
+	if(!(br_stats.flags & BR_UP))
+		return(-1); /* this should not happen but happens */
 	if (port_info[port_no].state == Disabled) {
 		printk(KERN_DEBUG "send_tcn_bpdu: port %i not valid\n",port_no);
 		return(-1);
@@ -1047,7 +1051,6 @@
 int br_receive_frame(struct sk_buff *skb)	/* 3.5 */
 {
 	int port;
-	int i;
 	
 	if (br_stats.flags & BR_DEBUG)
 		printk("br_receive_frame: ");
@@ -1301,9 +1304,16 @@
 		/*
 		 *	Sending
 		 */
-		if (f->port!=port && port_info[f->port].state == Forwarding) {
+
+		/*
+		 * Vova Oksman: There was the BUG, we must to check timer 
+		 * before comparing source and destination ports, becouse
+		 * case that destination was switched from same port with
+		 * source to other port. 
+		 */
 			/* has entry expired? */
-			if (f->timer + fdb_aging_time < CURRENT_TIME) {
+		if (port_info[f->port].state == Forwarding &&
+		    f->timer + fdb_aging_time < CURRENT_TIME) {
 				/* timer expired, invalidate entry */
 				f->flags &= ~FDB_ENT_VALID;
 				if (br_stats.flags & BR_DEBUG)
@@ -1314,6 +1324,7 @@
 				br_flood(skb, port);
 				return(br_dev_drop(skb));
 			}
+		if (f->port!=port && port_info[f->port].state == Forwarding) {
 			/* mark that's we've been here... */
 			skb->pkt_bridged = IS_BRIDGED;
 			

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov