diff options
Diffstat (limited to 'net/bridge/br_if.c')
| -rw-r--r-- | net/bridge/br_if.c | 107 | 
1 files changed, 19 insertions, 88 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 718b60366df..1bacca4cb67 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -36,8 +36,8 @@ static int port_cost(struct net_device *dev)  	if (dev->ethtool_ops && dev->ethtool_ops->get_settings) {  		struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET, }; -		if (!dev->ethtool_ops->get_settings(dev, &ecmd)) { -			switch(ecmd.speed) { +		if (!dev_ethtool_get_settings(dev, &ecmd)) { +			switch (ethtool_cmd_speed(&ecmd)) {  			case SPEED_10000:  				return 2;  			case SPEED_1000: @@ -147,6 +147,7 @@ static void del_nbp(struct net_bridge_port *p)  	dev->priv_flags &= ~IFF_BRIDGE_PORT;  	netdev_rx_handler_unregister(dev); +	synchronize_net();  	netdev_set_master(dev, NULL); @@ -175,56 +176,6 @@ static void del_br(struct net_bridge *br, struct list_head *head)  	unregister_netdevice_queue(br->dev, head);  } -static struct net_device *new_bridge_dev(struct net *net, const char *name) -{ -	struct net_bridge *br; -	struct net_device *dev; - -	dev = alloc_netdev(sizeof(struct net_bridge), name, -			   br_dev_setup); - -	if (!dev) -		return NULL; -	dev_net_set(dev, net); - -	br = netdev_priv(dev); -	br->dev = dev; - -	br->stats = alloc_percpu(struct br_cpu_netstats); -	if (!br->stats) { -		free_netdev(dev); -		return NULL; -	} - -	spin_lock_init(&br->lock); -	INIT_LIST_HEAD(&br->port_list); -	spin_lock_init(&br->hash_lock); - -	br->bridge_id.prio[0] = 0x80; -	br->bridge_id.prio[1] = 0x00; - -	memcpy(br->group_addr, br_group_address, ETH_ALEN); - -	br->feature_mask = dev->features; -	br->stp_enabled = BR_NO_STP; -	br->designated_root = br->bridge_id; -	br->root_path_cost = 0; -	br->root_port = 0; -	br->bridge_max_age = br->max_age = 20 * HZ; -	br->bridge_hello_time = br->hello_time = 2 * HZ; -	br->bridge_forward_delay = br->forward_delay = 15 * HZ; -	br->topology_change = 0; -	br->topology_change_detected = 0; -	br->ageing_time = 300 * HZ; - -	br_netfilter_rtable_init(br); - -	br_stp_timer_init(br); -	br_multicast_init(br); - -	return dev; -} -  /* find an available port number */  static int find_portno(struct net_bridge *br)  { @@ -277,42 +228,19 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,  	return p;  } -static struct device_type br_type = { -	.name	= "bridge", -}; -  int br_add_bridge(struct net *net, const char *name)  {  	struct net_device *dev; -	int ret; -	dev = new_bridge_dev(net, name); +	dev = alloc_netdev(sizeof(struct net_bridge), name, +			   br_dev_setup); +  	if (!dev)  		return -ENOMEM; -	rtnl_lock(); -	if (strchr(dev->name, '%')) { -		ret = dev_alloc_name(dev, dev->name); -		if (ret < 0) -			goto out_free; -	} - -	SET_NETDEV_DEVTYPE(dev, &br_type); - -	ret = register_netdevice(dev); -	if (ret) -		goto out_free; - -	ret = br_sysfs_addbr(dev); -	if (ret) -		unregister_netdevice(dev); - out: -	rtnl_unlock(); -	return ret; +	dev_net_set(dev, net); -out_free: -	free_netdev(dev); -	goto out; +	return register_netdev(dev);  }  int br_del_bridge(struct net *net, const char *name) @@ -364,15 +292,15 @@ int br_min_mtu(const struct net_bridge *br)  /*   * Recomputes features using slave's features   */ -void br_features_recompute(struct net_bridge *br) +u32 br_features_recompute(struct net_bridge *br, u32 features)  {  	struct net_bridge_port *p; -	u32 features, mask; +	u32 mask; -	features = mask = br->feature_mask;  	if (list_empty(&br->port_list)) -		goto done; +		return features; +	mask = features;  	features &= ~NETIF_F_ONE_FOR_ALL;  	list_for_each_entry(p, &br->port_list, list) { @@ -380,8 +308,7 @@ void br_features_recompute(struct net_bridge *br)  						     p->dev->features, mask);  	} -done: -	br->dev->features = netdev_fix_features(br->dev, features); +	return features;  }  /* called with RTNL */ @@ -412,6 +339,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)  	if (IS_ERR(p))  		return PTR_ERR(p); +	call_netdevice_notifiers(NETDEV_JOIN, dev); +  	err = dev_set_promiscuity(dev, 1);  	if (err)  		goto put_back; @@ -446,9 +375,10 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)  	list_add_rcu(&p->list, &br->port_list); +	netdev_update_features(br->dev); +  	spin_lock_bh(&br->lock);  	changed_addr = br_stp_recalculate_bridge_id(br); -	br_features_recompute(br);  	if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) &&  	    (br->dev->flags & IFF_UP)) @@ -496,9 +426,10 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)  	spin_lock_bh(&br->lock);  	br_stp_recalculate_bridge_id(br); -	br_features_recompute(br);  	spin_unlock_bh(&br->lock); +	netdev_update_features(br->dev); +  	return 0;  }  |