diff options
author | Eric Dumazet <edumazet@google.com> | 2012-06-11 15:23:07 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-06-12 21:51:09 -0400 |
commit | de063b7040dcd9fbc9a1847fa44f0af13e19d6de (patch) | |
tree | d828ad11df0863ae1594be4461bfdbcb5388c4a8 /drivers/net/bonding/bond_alb.c | |
parent | 072c0559e26bc35700b3a70dffc230f00d9262b8 (diff) |
bonding: remove packet cloning in recv_probe()
Cloning all packets in input path have a significant cost.
Use skb_header_pointer()/skb_copy_bits() instead of pskb_may_pull() so
that recv_probe handlers (bond_3ad_lacpdu_recv / bond_arp_rcv /
rlb_arp_recv ) dont touch input skb.
bond_handle_frame() can avoid the skb_clone()/dev_kfree_skb()
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Jay Vosburgh <fubar@us.ibm.com>
Cc: Andy Gospodarek <andy@greyhouse.net>
Cc: Jiri Bohac <jbohac@suse.cz>
Cc: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
Cc: Maciej Żenczykowski <maze@google.com>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding/bond_alb.c')
-rw-r--r-- | drivers/net/bonding/bond_alb.c | 20 |
1 files changed, 5 insertions, 15 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 0f59c1564e53..ef3791a09ad8 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -342,27 +342,17 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp) | |||
342 | _unlock_rx_hashtbl_bh(bond); | 342 | _unlock_rx_hashtbl_bh(bond); |
343 | } | 343 | } |
344 | 344 | ||
345 | static int rlb_arp_recv(struct sk_buff *skb, struct bonding *bond, | 345 | static int rlb_arp_recv(const struct sk_buff *skb, struct bonding *bond, |
346 | struct slave *slave) | 346 | struct slave *slave) |
347 | { | 347 | { |
348 | struct arp_pkt *arp; | 348 | struct arp_pkt *arp, _arp; |
349 | 349 | ||
350 | if (skb->protocol != cpu_to_be16(ETH_P_ARP)) | 350 | if (skb->protocol != cpu_to_be16(ETH_P_ARP)) |
351 | goto out; | 351 | goto out; |
352 | 352 | ||
353 | arp = (struct arp_pkt *) skb->data; | 353 | arp = skb_header_pointer(skb, 0, sizeof(_arp), &_arp); |
354 | if (!arp) { | 354 | if (!arp) |
355 | pr_debug("Packet has no ARP data\n"); | ||
356 | goto out; | 355 | goto out; |
357 | } | ||
358 | |||
359 | if (!pskb_may_pull(skb, arp_hdr_len(bond->dev))) | ||
360 | goto out; | ||
361 | |||
362 | if (skb->len < sizeof(struct arp_pkt)) { | ||
363 | pr_debug("Packet is too small to be an ARP\n"); | ||
364 | goto out; | ||
365 | } | ||
366 | 356 | ||
367 | if (arp->op_code == htons(ARPOP_REPLY)) { | 357 | if (arp->op_code == htons(ARPOP_REPLY)) { |
368 | /* update rx hash table for this ARP */ | 358 | /* update rx hash table for this ARP */ |