linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / net / bridge / br_if.c
index b1211d5..f36b35e 100644 (file)
@@ -210,8 +210,7 @@ static struct net_device *new_bridge_dev(const char *name)
 
        br->bridge_id.prio[0] = 0x80;
        br->bridge_id.prio[1] = 0x00;
-
-       memcpy(br->group_addr, br_group_address, ETH_ALEN);
+       memset(br->bridge_id.addr, 0, ETH_ALEN);
 
        br->feature_mask = dev->features;
        br->stp_enabled = 0;
@@ -238,11 +237,12 @@ static int find_portno(struct net_bridge *br)
        struct net_bridge_port *p;
        unsigned long *inuse;
 
-       inuse = kcalloc(BITS_TO_LONGS(BR_MAX_PORTS), sizeof(unsigned long),
+       inuse = kmalloc(BITS_TO_LONGS(BR_MAX_PORTS)*sizeof(unsigned long),
                        GFP_KERNEL);
        if (!inuse)
                return -ENOMEM;
 
+       memset(inuse, 0, BITS_TO_LONGS(BR_MAX_PORTS)*sizeof(unsigned long));
        set_bit(0, inuse);      /* zero is reserved */
        list_for_each_entry(p, &br->port_list, list) {
                set_bit(p->port_no, inuse);
@@ -264,10 +264,11 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
        if (index < 0)
                return ERR_PTR(index);
 
-       p = kzalloc(sizeof(*p), GFP_KERNEL);
+       p = kmalloc(sizeof(*p), GFP_KERNEL);
        if (p == NULL)
                return ERR_PTR(-ENOMEM);
 
+       memset(p, 0, sizeof(*p));
        p->br = br;
        dev_hold(dev);
        p->dev = dev;
@@ -300,22 +301,34 @@ int br_add_bridge(const char *name)
        rtnl_lock();
        if (strchr(dev->name, '%')) {
                ret = dev_alloc_name(dev, dev->name);
-               if (ret < 0) {
-                       free_netdev(dev);
-                       goto out;
-               }
+               if (ret < 0)
+                       goto err1;
        }
 
        ret = register_netdevice(dev);
        if (ret)
-               goto out;
+               goto err2;
+
+       /* network device kobject is not setup until
+        * after rtnl_unlock does it's hotplug magic.
+        * so hold reference to avoid race.
+        */
+       dev_hold(dev);
+       rtnl_unlock();
 
        ret = br_sysfs_addbr(dev);
-       if (ret)
-               unregister_netdevice(dev);
+       dev_put(dev);
+
+       if (ret) 
+               unregister_netdev(dev);
  out:
-       rtnl_unlock();
        return ret;
+
+ err2:
+       free_netdev(dev);
+ err1:
+       rtnl_unlock();
+       goto out;
 }
 
 int br_del_bridge(const char *name)
@@ -372,33 +385,17 @@ void br_features_recompute(struct net_bridge *br)
        struct net_bridge_port *p;
        unsigned long features, checksum;
 
-       checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0;
-       features = br->feature_mask & ~NETIF_F_ALL_CSUM;
+       features = br->feature_mask &~ NETIF_F_IP_CSUM;
+       checksum = br->feature_mask & NETIF_F_IP_CSUM;
 
        list_for_each_entry(p, &br->port_list, list) {
-               unsigned long feature = p->dev->features;
-
-               if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM))
-                       checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
-               if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM))
-                       checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM;
-               if (!(feature & NETIF_F_IP_CSUM))
+               if (!(p->dev->features 
+                     & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)))
                        checksum = 0;
-
-               if (feature & NETIF_F_GSO)
-                       feature |= NETIF_F_GSO_SOFTWARE;
-               feature |= NETIF_F_GSO;
-
-               features &= feature;
+               features &= p->dev->features;
        }
 
-       if (!(checksum & NETIF_F_ALL_CSUM))
-               features &= ~NETIF_F_SG;
-       if (!(features & NETIF_F_SG))
-               features &= ~NETIF_F_GSO_MASK;
-
-       br->dev->features = features | checksum | NETIF_F_LLTX |
-                           NETIF_F_GSO_ROBUST;
+       br->dev->features = features | checksum | NETIF_F_LLTX;
 }
 
 /* called with RTNL */