bonding: split alb_send_learning_packets()

Create alb_send_lp_vid(), which will handle the skb/lp creation, vlan
tagging and sending, and use it in alb_send_learning_packets().

This way all the logic remains in alb_send_learning_packets(), which
becomes a lot more cleaner and easier to understand.

CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Veaceslav Falico 2013-08-28 23:25:13 +02:00 committed by David S. Miller
parent a59d3d21ea
commit 7aa6498123

View file

@ -971,35 +971,53 @@ static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
/*********************** tlb/rlb shared functions *********************/ /*********************** tlb/rlb shared functions *********************/
static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]) static void alb_send_lp_vid(struct slave *slave, u8 mac_addr[],
u16 vid)
{ {
struct bonding *bond = bond_get_bond_by_slave(slave);
struct learning_pkt pkt; struct learning_pkt pkt;
struct sk_buff *skb;
int size = sizeof(struct learning_pkt); int size = sizeof(struct learning_pkt);
int i; char *data;
memset(&pkt, 0, size); memset(&pkt, 0, size);
memcpy(pkt.mac_dst, mac_addr, ETH_ALEN); memcpy(pkt.mac_dst, mac_addr, ETH_ALEN);
memcpy(pkt.mac_src, mac_addr, ETH_ALEN); memcpy(pkt.mac_src, mac_addr, ETH_ALEN);
pkt.type = cpu_to_be16(ETH_P_LOOP); pkt.type = cpu_to_be16(ETH_P_LOOP);
for (i = 0; i < MAX_LP_BURST; i++) { skb = dev_alloc_skb(size);
struct sk_buff *skb; if (!skb)
char *data; return;
skb = dev_alloc_skb(size); data = skb_put(skb, size);
memcpy(data, &pkt, size);
skb_reset_mac_header(skb);
skb->network_header = skb->mac_header + ETH_HLEN;
skb->protocol = pkt.type;
skb->priority = TC_PRIO_CONTROL;
skb->dev = slave->dev;
if (vid) {
skb = vlan_put_tag(skb, htons(ETH_P_8021Q), vid);
if (!skb) { if (!skb) {
pr_err("%s: Error: failed to insert VLAN tag\n",
slave->bond->dev->name);
return; return;
} }
}
data = skb_put(skb, size); dev_queue_xmit(skb);
memcpy(data, &pkt, size); }
skb_reset_mac_header(skb);
skb->network_header = skb->mac_header + ETH_HLEN; static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
skb->protocol = pkt.type; {
skb->priority = TC_PRIO_CONTROL; struct bonding *bond = bond_get_bond_by_slave(slave);
skb->dev = slave->dev; u16 vlan_id;
int i;
for (i = 0; i < MAX_LP_BURST; i++) {
vlan_id = 0;
if (bond_vlan_used(bond)) { if (bond_vlan_used(bond)) {
struct vlan_entry *vlan; struct vlan_entry *vlan;
@ -1008,20 +1026,13 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
bond->alb_info.current_alb_vlan); bond->alb_info.current_alb_vlan);
bond->alb_info.current_alb_vlan = vlan; bond->alb_info.current_alb_vlan = vlan;
if (!vlan) { if (!vlan)
kfree_skb(skb);
continue; continue;
}
skb = vlan_put_tag(skb, htons(ETH_P_8021Q), vlan->vlan_id); vlan_id = vlan->vlan_id;
if (!skb) {
pr_err("%s: Error: failed to insert VLAN tag\n",
bond->dev->name);
continue;
}
} }
dev_queue_xmit(skb); alb_send_lp_vid(slave, mac_addr, vlan_id);
} }
} }