patch-2.3.49 linux/net/core/dev.c

Next file: linux/net/core/netfilter.c
Previous file: linux/net/bridge/br_device.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.48/linux/net/core/dev.c linux/net/core/dev.c
@@ -76,6 +76,7 @@
 #include <linux/etherdevice.h>
 #include <linux/notifier.h>
 #include <linux/skbuff.h>
+#include <linux/brlock.h>
 #include <net/sock.h>
 #include <linux/rtnetlink.h>
 #include <net/slhc.h>
@@ -129,7 +130,6 @@
 
 static struct packet_type *ptype_base[16];		/* 16 way hashed list */
 static struct packet_type *ptype_all = NULL;		/* Taps */
-static rwlock_t ptype_lock = RW_LOCK_UNLOCKED;
 
 /*
  *	Our notifier list
@@ -181,7 +181,7 @@
 {
 	int hash;
 
-	write_lock_bh(&ptype_lock);
+	br_write_lock_bh(BR_NETPROTO_LOCK);
 
 #ifdef CONFIG_NET_FASTROUTE
 	/* Hack to detect packet socket */
@@ -199,7 +199,7 @@
 		pt->next = ptype_base[hash];
 		ptype_base[hash] = pt;
 	}
-	write_unlock_bh(&ptype_lock);
+	br_write_unlock_bh(BR_NETPROTO_LOCK);
 }
 
 
@@ -211,7 +211,7 @@
 {
 	struct packet_type **pt1;
 
-	write_lock_bh(&ptype_lock);
+	br_write_lock_bh(BR_NETPROTO_LOCK);
 
 	if (pt->type == htons(ETH_P_ALL)) {
 		netdev_nit--;
@@ -227,11 +227,11 @@
 			if (pt->data)
 				netdev_fastroute_obstacles--;
 #endif
-			write_unlock_bh(&ptype_lock);
+			br_write_unlock_bh(BR_NETPROTO_LOCK);
 			return;
 		}
 	}
-	write_unlock_bh(&ptype_lock);
+	br_write_unlock_bh(BR_NETPROTO_LOCK);
 	printk(KERN_WARNING "dev_remove_pack: %p not found.\n", pt);
 }
 
@@ -581,7 +581,7 @@
 	struct packet_type *ptype;
 	get_fast_time(&skb->stamp);
 
-	read_lock(&ptype_lock);
+	br_read_lock(BR_NETPROTO_LOCK);
 	for (ptype = ptype_all; ptype!=NULL; ptype = ptype->next) 
 	{
 		/* Never send packets back to the socket
@@ -615,7 +615,7 @@
 			ptype->func(skb2, skb->dev, ptype);
 		}
 	}
-	read_unlock(&ptype_lock);
+	br_read_unlock(BR_NETPROTO_LOCK);
 }
 
 /*
@@ -863,8 +863,8 @@
 }
 
 /* Reparent skb to master device. This function is called
- * only from net_rx_action under ptype_lock. It is misuse
- * of ptype_lock, but it is OK for now.
+ * only from net_rx_action under BR_NETPROTO_LOCK. It is misuse
+ * of BR_NETPROTO_LOCK, but it is OK for now.
  */
 static __inline__ void skb_bond(struct sk_buff *skb)
 {
@@ -924,9 +924,9 @@
 
 void net_call_rx_atomic(void (*fn)(void))
 {
-	write_lock_bh(&ptype_lock);
+	br_write_lock_bh(BR_NETPROTO_LOCK);
 	fn();
-	write_unlock_bh(&ptype_lock);
+	br_write_unlock_bh(BR_NETPROTO_LOCK);
 }
 
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
@@ -936,11 +936,13 @@
 static void __inline__ handle_bridge(struct sk_buff *skb,
 				     struct packet_type *pt_prev)
 {
-	if (pt_prev)
-		deliver_to_old_ones(pt_prev, skb, 0);
-	else {
-		atomic_inc(&skb->users);
-		pt_prev->func(skb, skb->dev, pt_prev);
+	if (pt_prev) {
+		if (!pt_prev->data)
+			deliver_to_old_ones(pt_prev, skb, 0);
+		else {
+			atomic_inc(&skb->users);
+			pt_prev->func(skb, skb->dev, pt_prev);
+		}
 	}
 
 	br_handle_frame_hook(skb);
@@ -954,7 +956,7 @@
 	unsigned long start_time = jiffies;
 	int bugdet = netdev_max_backlog;
 
-	read_lock(&ptype_lock);
+	br_read_lock(BR_NETPROTO_LOCK);
 
 	for (;;) {
 		struct sk_buff *skb;
@@ -1034,7 +1036,7 @@
 		if (bugdet-- < 0 || jiffies - start_time > 1)
 			goto softnet_break;
 	}
-	read_unlock(&ptype_lock);
+	br_read_unlock(BR_NETPROTO_LOCK);
 
 	local_irq_disable();
 	if (queue->throttle) {
@@ -1050,7 +1052,7 @@
 	return;
 
 softnet_break:
-	read_unlock(&ptype_lock);
+	br_read_unlock(BR_NETPROTO_LOCK);
 
 	local_irq_disable();
 	netdev_rx_stat[this_cpu].time_squeeze++;
@@ -1391,9 +1393,9 @@
 		dev_hold(master);
 	}
 
-	write_lock_bh(&ptype_lock);
+	br_write_lock_bh(BR_NETPROTO_LOCK);
 	slave->master = master;
-	write_unlock_bh(&ptype_lock);
+	br_write_unlock_bh(BR_NETPROTO_LOCK);
 
 	if (old)
 		dev_put(old);
@@ -1516,7 +1518,7 @@
 		case SIOCGIFFLAGS:	/* Get interface flags */
 			ifr->ifr_flags = (dev->flags&~(IFF_PROMISC|IFF_ALLMULTI|IFF_RUNNING))
 				|(dev->gflags&(IFF_PROMISC|IFF_ALLMULTI));
-			if (netif_running(dev))
+			if (netif_running(dev) && netif_carrier_ok(dev))
 				ifr->ifr_flags |= IFF_RUNNING;
 			return 0;
 
@@ -2129,6 +2131,7 @@
 			if (dev->rebuild_header == NULL)
 				dev->rebuild_header = default_rebuild_header;
 			dev_init_scheduler(dev);
+			set_bit(__LINK_STATE_PRESENT, &dev->state);
 		}
 	}
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)