Skip to content

Commit

Permalink
[BRIDGE]: set features based on enslaved devices
Browse files Browse the repository at this point in the history
Make features of the bridge pseudo-device be a subset of the underlying
devices.  Motivated by Xen and others who use bridging to do failover.

Signed-off-by: Catalin BOIE <catab at umrella.ro>
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed May 29, 2005
1 parent 81e8157 commit 81d3530
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 8 deletions.
15 changes: 7 additions & 8 deletions net/bridge/br_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@

static struct net_device_stats *br_dev_get_stats(struct net_device *dev)
{
struct net_bridge *br;

br = dev->priv;

struct net_bridge *br = netdev_priv(dev);
return &br->statistics;
}

Expand Down Expand Up @@ -54,9 +51,11 @@ int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)

static int br_dev_open(struct net_device *dev)
{
netif_start_queue(dev);
struct net_bridge *br = netdev_priv(dev);

br_stp_enable_bridge(dev->priv);
br_features_recompute(br);
netif_start_queue(dev);
br_stp_enable_bridge(br);

return 0;
}
Expand All @@ -67,7 +66,7 @@ static void br_dev_set_multicast_list(struct net_device *dev)

static int br_dev_stop(struct net_device *dev)
{
br_stp_disable_bridge(dev->priv);
br_stp_disable_bridge(netdev_priv(dev));

netif_stop_queue(dev);

Expand All @@ -76,7 +75,7 @@ static int br_dev_stop(struct net_device *dev)

static int br_change_mtu(struct net_device *dev, int new_mtu)
{
if ((new_mtu < 68) || new_mtu > br_min_mtu(dev->priv))
if (new_mtu < 68 || new_mtu > br_min_mtu(netdev_priv(dev)))
return -EINVAL;

dev->mtu = new_mtu;
Expand Down
23 changes: 23 additions & 0 deletions net/bridge/br_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,28 @@ int br_min_mtu(const struct net_bridge *br)
return mtu;
}

/*
* Recomputes features using slave's features
*/
void br_features_recompute(struct net_bridge *br)
{
struct net_bridge_port *p;
unsigned long features, checksum;

features = NETIF_F_SG | NETIF_F_FRAGLIST
| NETIF_F_HIGHDMA | NETIF_F_TSO;
checksum = NETIF_F_IP_CSUM; /* least commmon subset */

list_for_each_entry(p, &br->port_list, list) {
if (!(p->dev->features
& (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)))
checksum = 0;
features &= p->dev->features;
}

br->dev->features = features | checksum | NETIF_F_LLTX;
}

/* called with RTNL */
int br_add_if(struct net_bridge *br, struct net_device *dev)
{
Expand Down Expand Up @@ -368,6 +390,7 @@ 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);

return 0;
Expand Down
9 changes: 9 additions & 0 deletions net/bridge/br_notify.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
}
break;

case NETDEV_FEAT_CHANGE:
if (br->dev->flags & IFF_UP)
br_features_recompute(br);

/* could do recursive feature change notification
* but who would care??
*/
break;

case NETDEV_DOWN:
if (br->dev->flags & IFF_UP)
br_stp_disable_port(p);
Expand Down
1 change: 1 addition & 0 deletions net/bridge/br_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ extern int br_add_if(struct net_bridge *br,
extern int br_del_if(struct net_bridge *br,
struct net_device *dev);
extern int br_min_mtu(const struct net_bridge *br);
extern void br_features_recompute(struct net_bridge *br);

/* br_input.c */
extern int br_handle_frame_finish(struct sk_buff *skb);
Expand Down

0 comments on commit 81d3530

Please sign in to comment.