aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_alb.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2012-06-11 15:23:07 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-12 21:51:09 -0400
commitde063b7040dcd9fbc9a1847fa44f0af13e19d6de (patch)
treed828ad11df0863ae1594be4461bfdbcb5388c4a8 /drivers/net/bonding/bond_alb.c
parent072c0559e26bc35700b3a70dffc230f00d9262b8 (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.c20
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
345static int rlb_arp_recv(struct sk_buff *skb, struct bonding *bond, 345static 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 */