Merge to Fedora kernel-2.6.7-1.492
[linux-2.6.git] / net / bridge / br_if.c
index 2027560..092d451 100644 (file)
@@ -75,9 +75,8 @@ static int br_initial_port_cost(struct net_device *dev)
        return 100;     /* assume old 10Mbps */
 }
 
-static void destroy_nbp(void *arg)
+static void destroy_nbp(struct net_bridge_port *p)
 {
-       struct net_bridge_port *p = arg;
        struct net_device *dev = p->dev;
 
        dev->br_port = NULL;
@@ -88,6 +87,13 @@ static void destroy_nbp(void *arg)
        br_sysfs_freeif(p);
 }
 
+static void destroy_nbp_rcu(struct rcu_head *head)
+{
+       struct net_bridge_port *p =
+                       container_of(head, struct net_bridge_port, rcu);
+       destroy_nbp(p);
+}
+
 /* called with RTNL */
 static void del_nbp(struct net_bridge_port *p)
 {
@@ -108,7 +114,7 @@ static void del_nbp(struct net_bridge_port *p)
        del_timer_sync(&p->forward_delay_timer);
        del_timer_sync(&p->hold_timer);
        
-       call_rcu(&p->rcu, destroy_nbp, p);
+       call_rcu(&p->rcu, destroy_nbp_rcu);
 }
 
 /* called with RTNL */
@@ -289,6 +295,24 @@ int br_del_bridge(const char *name)
        return ret;
 }
 
+int br_min_mtu(const struct net_bridge *br)
+{
+       const struct net_bridge_port *p;
+       int mtu = 0;
+
+       ASSERT_RTNL();
+
+       if (list_empty(&br->port_list))
+               mtu = 1500;
+       else {
+               list_for_each_entry(p, &br->port_list, list) {
+                       if (!mtu  || p->dev->mtu < mtu)
+                               mtu = p->dev->mtu;
+               }
+       }
+       return mtu;
+}
+
 /* called with RTNL */
 int br_add_if(struct net_bridge *br, struct net_device *dev)
 {
@@ -322,6 +346,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
                if ((br->dev->flags & IFF_UP) && (dev->flags & IFF_UP))
                        br_stp_enable_port(p);
                spin_unlock_bh(&br->lock);
+
+               br->dev->mtu = br_min_mtu(br);
        }
 
        return err;