Commit 8d77e99e authored by Shmulik Hen's avatar Shmulik Hen Committed by Jeff Garzik

[PATCH] bonding cleanup 2.6 - Consolidate error handling in all xmit functions

parent e2ed8a6c
...@@ -2360,32 +2360,18 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) ...@@ -2360,32 +2360,18 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
int i; int i;
struct ad_info ad_info; struct ad_info ad_info;
if (!IS_UP(dev)) { /* bond down */ /* make sure that the slaves list will
dev_kfree_skb(skb); * not change during tx
return 0; */
}
if (bond == NULL) {
printk(KERN_ERR DRV_NAME ": Error: bond is NULL on device %s\n", dev->name);
dev_kfree_skb(skb);
return 0;
}
read_lock(&bond->lock); read_lock(&bond->lock);
/* check if bond is empty */ if (!BOND_IS_OK(bond)) {
if (bond->slave_cnt == 0) { goto free_out;
printk(KERN_DEBUG DRV_NAME ": Error: bond is empty\n");
dev_kfree_skb(skb);
read_unlock(&bond->lock);
return 0;
} }
if (bond_3ad_get_active_agg_info(bond, &ad_info)) { if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
printk(KERN_DEBUG "ERROR: bond_3ad_get_active_agg_info failed\n"); printk(KERN_DEBUG "ERROR: bond_3ad_get_active_agg_info failed\n");
dev_kfree_skb(skb); goto free_out;
read_unlock(&bond->lock);
return 0;
} }
slaves_in_agg = ad_info.ports; slaves_in_agg = ad_info.ports;
...@@ -2394,9 +2380,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) ...@@ -2394,9 +2380,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
if (slaves_in_agg == 0) { if (slaves_in_agg == 0) {
/*the aggregator is empty*/ /*the aggregator is empty*/
printk(KERN_DEBUG "ERROR: active aggregator is empty\n"); printk(KERN_DEBUG "ERROR: active aggregator is empty\n");
dev_kfree_skb(skb); goto free_out;
read_unlock(&bond->lock);
return 0;
} }
slave_agg_no = (data->h_dest[5]^bond->dev->dev_addr[5]) % slaves_in_agg; slave_agg_no = (data->h_dest[5]^bond->dev->dev_addr[5]) % slaves_in_agg;
...@@ -2414,9 +2398,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) ...@@ -2414,9 +2398,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
if (slave_agg_no >= 0) { if (slave_agg_no >= 0) {
printk(KERN_ERR DRV_NAME ": Error: Couldn't find a slave to tx on for aggregator ID %d\n", agg_id); printk(KERN_ERR DRV_NAME ": Error: Couldn't find a slave to tx on for aggregator ID %d\n", agg_id);
dev_kfree_skb(skb); goto free_out;
read_unlock(&bond->lock);
return 0;
} }
start_at = slave; start_at = slave;
...@@ -2434,15 +2416,17 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) ...@@ -2434,15 +2416,17 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
skb->dev = slave->dev; skb->dev = slave->dev;
skb->priority = 1; skb->priority = 1;
dev_queue_xmit(skb); dev_queue_xmit(skb);
read_unlock(&bond->lock);
return 0;
} }
} }
/* no suitable interface, frame not sent */ out:
dev_kfree_skb(skb);
read_unlock(&bond->lock); read_unlock(&bond->lock);
return 0; return 0;
free_out:
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
goto out;
} }
int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype) int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype)
......
...@@ -1158,25 +1158,16 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) ...@@ -1158,25 +1158,16 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
u32 hash_index = 0; u32 hash_index = 0;
u8 *hash_start = NULL; u8 *hash_start = NULL;
if (!IS_UP(bond_dev)) { /* bond down */
dev_kfree_skb(skb);
return 0;
}
/* make sure that the curr_active_slave and the slaves list do /* make sure that the curr_active_slave and the slaves list do
* not change during tx * not change during tx
*/ */
read_lock(&bond->lock); read_lock(&bond->lock);
read_lock(&bond->curr_slave_lock);
if (bond->slave_cnt == 0) { if (!BOND_IS_OK(bond)) {
/* no suitable interface, frame not sent */ goto free_out;
dev_kfree_skb(skb);
read_unlock(&bond->lock);
return 0;
} }
read_lock(&bond->curr_slave_lock);
switch (ntohs(skb->protocol)) { switch (ntohs(skb->protocol)) {
case ETH_P_IP: case ETH_P_IP:
if ((memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) || if ((memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) ||
...@@ -1256,12 +1247,17 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) ...@@ -1256,12 +1247,17 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
if (tx_slave) { if (tx_slave) {
tlb_clear_slave(bond, tx_slave, 0); tlb_clear_slave(bond, tx_slave, 0);
} }
dev_kfree_skb(skb); goto free_out;
} }
out:
read_unlock(&bond->curr_slave_lock); read_unlock(&bond->curr_slave_lock);
read_unlock(&bond->lock); read_unlock(&bond->lock);
return 0; return 0;
free_out:
dev_kfree_skb(skb);
goto out;
} }
void bond_alb_monitor(struct bonding *bond) void bond_alb_monitor(struct bonding *bond)
......
...@@ -2913,22 +2913,18 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) ...@@ -2913,22 +2913,18 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
struct net_device *tx_dev = NULL; struct net_device *tx_dev = NULL;
int i; int i;
if (!IS_UP(bond_dev)) { /* bond down */
dev_kfree_skb(skb);
return 0;
}
read_lock(&bond->lock); read_lock(&bond->lock);
if (!BOND_IS_OK(bond)) {
goto free_out;
}
read_lock(&bond->curr_slave_lock); read_lock(&bond->curr_slave_lock);
start_at = bond->curr_active_slave; start_at = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock); read_unlock(&bond->curr_slave_lock);
if (!start_at) { /* we're at the root, get the first slave */ if (!start_at) {
/* no suitable interface, frame not sent */ goto free_out;
read_unlock(&bond->lock);
dev_kfree_skb(skb);
return 0;
} }
bond_for_each_slave_from(bond, slave, i, start_at) { bond_for_each_slave_from(bond, slave, i, start_at) {
...@@ -2957,12 +2953,18 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) ...@@ -2957,12 +2953,18 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
skb->priority = 1; skb->priority = 1;
dev_queue_xmit(skb); dev_queue_xmit(skb);
} else { } else {
dev_kfree_skb(skb); goto free_out;
} }
out:
/* frame sent to all suitable interfaces */ /* frame sent to all suitable interfaces */
read_unlock(&bond->lock); read_unlock(&bond->lock);
return 0; return 0;
free_out:
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
goto out;
} }
static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev) static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev)
...@@ -2971,22 +2973,18 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev ...@@ -2971,22 +2973,18 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
struct slave *slave, *start_at; struct slave *slave, *start_at;
int i; int i;
if (!IS_UP(bond_dev)) { /* bond down */
dev_kfree_skb(skb);
return 0;
}
read_lock(&bond->lock); read_lock(&bond->lock);
if (!BOND_IS_OK(bond)) {
goto free_out;
}
read_lock(&bond->curr_slave_lock); read_lock(&bond->curr_slave_lock);
slave = start_at = bond->curr_active_slave; slave = start_at = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock); read_unlock(&bond->curr_slave_lock);
if (!slave) { /* we're at the root, get the first slave */ if (!slave) {
/* no suitable interface, frame not sent */ goto free_out;
dev_kfree_skb(skb);
read_unlock(&bond->lock);
return 0;
} }
bond_for_each_slave_from(bond, slave, i, start_at) { bond_for_each_slave_from(bond, slave, i, start_at) {
...@@ -3002,15 +3000,18 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev ...@@ -3002,15 +3000,18 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
bond->curr_active_slave = slave->next; bond->curr_active_slave = slave->next;
write_unlock(&bond->curr_slave_lock); write_unlock(&bond->curr_slave_lock);
read_unlock(&bond->lock); goto out;
return 0;
} }
} }
/* no suitable interface, frame not sent */ out:
dev_kfree_skb(skb);
read_unlock(&bond->lock); read_unlock(&bond->lock);
return 0; return 0;
free_out:
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
goto out;
} }
/* /*
...@@ -3026,18 +3027,10 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev) ...@@ -3026,18 +3027,10 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
int slave_no; int slave_no;
int i; int i;
if (!IS_UP(bond_dev)) { /* bond down */
dev_kfree_skb(skb);
return 0;
}
read_lock(&bond->lock); read_lock(&bond->lock);
if (bond->slave_cnt == 0) { if (!BOND_IS_OK(bond)) {
/* no suitable interface, frame not sent */ goto free_out;
dev_kfree_skb(skb);
read_unlock(&bond->lock);
return 0;
} }
slave_no = (data->h_dest[5]^bond_dev->dev_addr[5]) % bond->slave_cnt; slave_no = (data->h_dest[5]^bond_dev->dev_addr[5]) % bond->slave_cnt;
...@@ -3060,15 +3053,18 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev) ...@@ -3060,15 +3053,18 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
skb->priority = 1; skb->priority = 1;
dev_queue_xmit(skb); dev_queue_xmit(skb);
read_unlock(&bond->lock); goto out;
return 0;
} }
} }
/* no suitable interface, frame not sent */ out:
dev_kfree_skb(skb);
read_unlock(&bond->lock); read_unlock(&bond->lock);
return 0; return 0;
free_out:
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
goto out;
} }
/* /*
...@@ -3079,11 +3075,6 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d ...@@ -3079,11 +3075,6 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
{ {
struct bonding *bond = (struct bonding *)bond_dev->priv; struct bonding *bond = (struct bonding *)bond_dev->priv;
if (!IS_UP(bond_dev)) { /* bond down */
dev_kfree_skb(skb);
return 0;
}
/* if we are sending arp packets, try to at least /* if we are sending arp packets, try to at least
identify our own ip address */ identify our own ip address */
if (arp_interval && !my_ip && if (arp_interval && !my_ip &&
...@@ -3096,24 +3087,29 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d ...@@ -3096,24 +3087,29 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
} }
read_lock(&bond->lock); read_lock(&bond->lock);
read_lock(&bond->curr_slave_lock); read_lock(&bond->curr_slave_lock);
if (!BOND_IS_OK(bond)) {
goto free_out;
}
if (bond->curr_active_slave) { /* one usable interface */ if (bond->curr_active_slave) { /* one usable interface */
skb->dev = bond->curr_active_slave->dev; skb->dev = bond->curr_active_slave->dev;
read_unlock(&bond->curr_slave_lock);
skb->priority = 1; skb->priority = 1;
dev_queue_xmit(skb); dev_queue_xmit(skb);
read_unlock(&bond->lock); goto out;
return 0;
} else { } else {
read_unlock(&bond->curr_slave_lock); goto free_out;
} }
out:
read_unlock(&bond->curr_slave_lock);
read_unlock(&bond->lock);
return 0;
free_out:
/* no suitable interface, frame not sent */ /* no suitable interface, frame not sent */
dprintk("There was no suitable interface, so we don't transmit\n");
dev_kfree_skb(skb); dev_kfree_skb(skb);
read_unlock(&bond->lock); goto out;
return 0;
} }
static struct net_device_stats *bond_get_stats(struct net_device *bond_dev) static struct net_device_stats *bond_get_stats(struct net_device *bond_dev)
......
...@@ -45,18 +45,27 @@ ...@@ -45,18 +45,27 @@
#define dprintk(fmt, args...) #define dprintk(fmt, args...)
#endif /* BONDING_DEBUG */ #endif /* BONDING_DEBUG */
#define IS_UP(dev) ((((dev)->flags & (IFF_UP)) == (IFF_UP)) && \ #define IS_UP(dev) \
(netif_running(dev) && netif_carrier_ok(dev))) ((((dev)->flags & IFF_UP) == IFF_UP) && \
netif_running(dev) && \
/* Checks whether the dev is ready for transmit. We do not check netif_running netif_carrier_ok(dev))
* since a device can be stopped by the driver for short periods of time for
* maintainance. dev_queue_xmit() handles this by queing the packet until the /*
* the dev is running again. Keeping packets ordering requires sticking the * Checks whether bond is ready for transmit.
* same dev as much as possible *
* Caller must hold bond->lock
*/
#define BOND_IS_OK(bond) \
(((bond)->dev->flags & IFF_UP) && \
netif_running((bond)->dev) && \
((bond)->slave_cnt > 0))
/*
* Checks whether slave is ready for transmit.
*/ */
#define SLAVE_IS_OK(slave) \ #define SLAVE_IS_OK(slave) \
((((slave)->dev->flags & (IFF_UP)) == (IFF_UP)) && \ (((slave)->dev->flags & IFF_UP) && \
netif_carrier_ok((slave)->dev) && \ netif_running((slave)->dev) && \
((slave)->link == BOND_LINK_UP) && \ ((slave)->link == BOND_LINK_UP) && \
((slave)->state == BOND_STATE_ACTIVE)) ((slave)->state == BOND_STATE_ACTIVE))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment