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>
此提交包含在:
@@ -342,27 +342,17 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
|
||||
_unlock_rx_hashtbl_bh(bond);
|
||||
}
|
||||
|
||||
static int rlb_arp_recv(struct sk_buff *skb, struct bonding *bond,
|
||||
struct slave *slave)
|
||||
static int rlb_arp_recv(const struct sk_buff *skb, struct bonding *bond,
|
||||
struct slave *slave)
|
||||
{
|
||||
struct arp_pkt *arp;
|
||||
struct arp_pkt *arp, _arp;
|
||||
|
||||
if (skb->protocol != cpu_to_be16(ETH_P_ARP))
|
||||
goto out;
|
||||
|
||||
arp = (struct arp_pkt *) skb->data;
|
||||
if (!arp) {
|
||||
pr_debug("Packet has no ARP data\n");
|
||||
arp = skb_header_pointer(skb, 0, sizeof(_arp), &_arp);
|
||||
if (!arp)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!pskb_may_pull(skb, arp_hdr_len(bond->dev)))
|
||||
goto out;
|
||||
|
||||
if (skb->len < sizeof(struct arp_pkt)) {
|
||||
pr_debug("Packet is too small to be an ARP\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (arp->op_code == htons(ARPOP_REPLY)) {
|
||||
/* update rx hash table for this ARP */
|
||||
|
新增問題並參考
封鎖使用者