Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2502

kernel-2.6.18-238.el5.src.rpm

From: Herbert Xu <herbert.xu@redhat.com>
Date: Thu, 24 Jan 2008 14:53:41 +1100
Subject: [net] bridge br_if: fix oops in port_carrier_check
Message-id: 20080124035341.GA13412@gondor.apana.org.au
O-Subject: [RHEL5.2 PATCH] [BRIDGE] br_if: Fix oops in port_carrier_check
Bugzilla: 408791

Hi:

RHEL5.2 BZ 408791

This upstream changeset fixes a crash in the bridge device when the
bridge is created or destroyed quickly.

commit a10d567c89dfba90dde2e0515e25760fd74cde06
Author: Jarek Poplawski <jarkao2@o2.pl>
Date:   Tue Feb 13 12:35:26 2007 -0800

    [BRIDGE] br_if: Fix oops in port_carrier_check

    Signed-off-by: Jarek Poplawski <jarkao2@o2.pl>
    Acked-by: Stephen Hemminger <shemminger@linux-foundation.org>
    Signed-off-by: David S. Miller <davem@davemloft.net>

Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--

Acked-by: "David S. Miller" <davem@redhat.com>
Acked-by: Alexander Viro <aviro@redhat.com>
Acked-by: Thomas Graf <tgraf@redhat.com>
Acked-by: Alan Cox <alan@redhat.com>

diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 3ef82e9..9dff48c 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -104,6 +104,7 @@ static void port_carrier_check(void *arg)
 		spin_unlock_bh(&br->lock);
 	}
 done:
+	dev_put(dev);
 	rtnl_unlock();
 }
 
@@ -157,7 +158,8 @@ static void del_nbp(struct net_bridge_port *p)
 
 	dev_set_promiscuity(dev, -1);
 
-	cancel_delayed_work(&p->carrier_check);
+	if (cancel_delayed_work(&p->carrier_check))
+		dev_put(dev);
 
 	spin_lock_bh(&br->lock);
 	br_stp_disable_port(p);
@@ -420,7 +422,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
 	spin_lock_bh(&br->lock);
 	br_stp_recalculate_bridge_id(br);
 	br_features_recompute(br);
-	schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE);
+	if (schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE))
+		dev_hold(dev);
+
 	spin_unlock_bh(&br->lock);
 
 	dev_set_mtu(br->dev, br_min_mtu(br));
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index 2027849..c64742c 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -56,7 +56,9 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
 
 	case NETDEV_CHANGE:
 		if (br->dev->flags & IFF_UP)
-			schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE);
+			if (schedule_delayed_work(&p->carrier_check,
+						BR_PORT_DEBOUNCE))
+				dev_hold(dev);
 		break;
 
 	case NETDEV_FEAT_CHANGE: