diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b9c2ae62166d..f5a40b925f5e 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1445,8 +1445,8 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) | |||
1445 | struct sk_buff *skb = *pskb; | 1445 | struct sk_buff *skb = *pskb; |
1446 | struct slave *slave; | 1446 | struct slave *slave; |
1447 | struct bonding *bond; | 1447 | struct bonding *bond; |
1448 | int (*recv_probe)(struct sk_buff *, struct bonding *, | 1448 | int (*recv_probe)(const struct sk_buff *, struct bonding *, |
1449 | struct slave *); | 1449 | struct slave *); |
1450 | int ret = RX_HANDLER_ANOTHER; | 1450 | int ret = RX_HANDLER_ANOTHER; |
1451 | 1451 | ||
1452 | skb = skb_share_check(skb, GFP_ATOMIC); | 1452 | skb = skb_share_check(skb, GFP_ATOMIC); |
@@ -1463,15 +1463,10 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) | |||
1463 | 1463 | ||
1464 | recv_probe = ACCESS_ONCE(bond->recv_probe); | 1464 | recv_probe = ACCESS_ONCE(bond->recv_probe); |
1465 | if (recv_probe) { | 1465 | if (recv_probe) { |
1466 | struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); | 1466 | ret = recv_probe(skb, bond, slave); |
1467 | 1467 | if (ret == RX_HANDLER_CONSUMED) { | |
1468 | if (likely(nskb)) { | 1468 | consume_skb(skb); |
1469 | ret = recv_probe(nskb, bond, slave); | 1469 | return ret; |
1470 | dev_kfree_skb(nskb); | ||
1471 | if (ret == RX_HANDLER_CONSUMED) { | ||
1472 | consume_skb(skb); | ||
1473 | return ret; | ||
1474 | } | ||
1475 | } | 1470 | } |
1476 | } | 1471 | } |
1477 | 1472 | ||
@@ -2738,25 +2733,31 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 | |||
2738 | } | 2733 | } |
2739 | } | 2734 | } |
2740 | 2735 | ||
2741 | static int bond_arp_rcv(struct sk_buff *skb, struct bonding *bond, | 2736 | static int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, |
2742 | struct slave *slave) | 2737 | struct slave *slave) |
2743 | { | 2738 | { |
2744 | struct arphdr *arp; | 2739 | struct arphdr *arp = (struct arphdr *)skb->data; |
2745 | unsigned char *arp_ptr; | 2740 | unsigned char *arp_ptr; |
2746 | __be32 sip, tip; | 2741 | __be32 sip, tip; |
2742 | int alen; | ||
2747 | 2743 | ||
2748 | if (skb->protocol != __cpu_to_be16(ETH_P_ARP)) | 2744 | if (skb->protocol != __cpu_to_be16(ETH_P_ARP)) |
2749 | return RX_HANDLER_ANOTHER; | 2745 | return RX_HANDLER_ANOTHER; |
2750 | 2746 | ||
2751 | read_lock(&bond->lock); | 2747 | read_lock(&bond->lock); |
2748 | alen = arp_hdr_len(bond->dev); | ||
2752 | 2749 | ||
2753 | pr_debug("bond_arp_rcv: bond %s skb->dev %s\n", | 2750 | pr_debug("bond_arp_rcv: bond %s skb->dev %s\n", |
2754 | bond->dev->name, skb->dev->name); | 2751 | bond->dev->name, skb->dev->name); |
2755 | 2752 | ||
2756 | if (!pskb_may_pull(skb, arp_hdr_len(bond->dev))) | 2753 | if (alen > skb_headlen(skb)) { |
2757 | goto out_unlock; | 2754 | arp = kmalloc(alen, GFP_ATOMIC); |
2755 | if (!arp) | ||
2756 | goto out_unlock; | ||
2757 | if (skb_copy_bits(skb, 0, arp, alen) < 0) | ||
2758 | goto out_unlock; | ||
2759 | } | ||
2758 | 2760 | ||
2759 | arp = arp_hdr(skb); | ||
2760 | if (arp->ar_hln != bond->dev->addr_len || | 2761 | if (arp->ar_hln != bond->dev->addr_len || |
2761 | skb->pkt_type == PACKET_OTHERHOST || | 2762 | skb->pkt_type == PACKET_OTHERHOST || |
2762 | skb->pkt_type == PACKET_LOOPBACK || | 2763 | skb->pkt_type == PACKET_LOOPBACK || |
@@ -2791,6 +2792,8 @@ static int bond_arp_rcv(struct sk_buff *skb, struct bonding *bond, | |||
2791 | 2792 | ||
2792 | out_unlock: | 2793 | out_unlock: |
2793 | read_unlock(&bond->lock); | 2794 | read_unlock(&bond->lock); |
2795 | if (arp != (struct arphdr *)skb->data) | ||
2796 | kfree(arp); | ||
2794 | return RX_HANDLER_ANOTHER; | 2797 | return RX_HANDLER_ANOTHER; |
2795 | } | 2798 | } |
2796 | 2799 | ||
@@ -3987,7 +3990,7 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev | |||
3987 | out: | 3990 | out: |
3988 | if (res) { | 3991 | if (res) { |
3989 | /* no suitable interface, frame not sent */ | 3992 | /* no suitable interface, frame not sent */ |
3990 | dev_kfree_skb(skb); | 3993 | kfree_skb(skb); |
3991 | } | 3994 | } |
3992 | 3995 | ||
3993 | return NETDEV_TX_OK; | 3996 | return NETDEV_TX_OK; |
@@ -4009,11 +4012,11 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d | |||
4009 | res = bond_dev_queue_xmit(bond, skb, | 4012 | res = bond_dev_queue_xmit(bond, skb, |
4010 | bond->curr_active_slave->dev); | 4013 | bond->curr_active_slave->dev); |
4011 | 4014 | ||
4015 | read_unlock(&bond->curr_slave_lock); | ||
4016 | |||
4012 | if (res) | 4017 | if (res) |
4013 | /* no suitable interface, frame not sent */ | 4018 | /* no suitable interface, frame not sent */ |
4014 | dev_kfree_skb(skb); | 4019 | kfree_skb(skb); |
4015 | |||
4016 | read_unlock(&bond->curr_slave_lock); | ||
4017 | 4020 | ||
4018 | return NETDEV_TX_OK; | 4021 | return NETDEV_TX_OK; |
4019 | } | 4022 | } |
@@ -4052,7 +4055,7 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev) | |||
4052 | 4055 | ||
4053 | if (res) { | 4056 | if (res) { |
4054 | /* no suitable interface, frame not sent */ | 4057 | /* no suitable interface, frame not sent */ |
4055 | dev_kfree_skb(skb); | 4058 | kfree_skb(skb); |
4056 | } | 4059 | } |
4057 | 4060 | ||
4058 | return NETDEV_TX_OK; | 4061 | return NETDEV_TX_OK; |
@@ -4090,7 +4093,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) | |||
4090 | 4093 | ||
4091 | res = bond_dev_queue_xmit(bond, skb2, tx_dev); | 4094 | res = bond_dev_queue_xmit(bond, skb2, tx_dev); |
4092 | if (res) { | 4095 | if (res) { |
4093 | dev_kfree_skb(skb2); | 4096 | kfree_skb(skb2); |
4094 | continue; | 4097 | continue; |
4095 | } | 4098 | } |
4096 | } | 4099 | } |
@@ -4104,7 +4107,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) | |||
4104 | out: | 4107 | out: |
4105 | if (res) | 4108 | if (res) |
4106 | /* no suitable interface, frame not sent */ | 4109 | /* no suitable interface, frame not sent */ |
4107 | dev_kfree_skb(skb); | 4110 | kfree_skb(skb); |
4108 | 4111 | ||
4109 | /* frame sent to all suitable interfaces */ | 4112 | /* frame sent to all suitable interfaces */ |
4110 | return NETDEV_TX_OK; | 4113 | return NETDEV_TX_OK; |
@@ -4210,7 +4213,7 @@ static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev | |||
4210 | pr_err("%s: Error: Unknown bonding mode %d\n", | 4213 | pr_err("%s: Error: Unknown bonding mode %d\n", |
4211 | dev->name, bond->params.mode); | 4214 | dev->name, bond->params.mode); |
4212 | WARN_ON_ONCE(1); | 4215 | WARN_ON_ONCE(1); |
4213 | dev_kfree_skb(skb); | 4216 | kfree_skb(skb); |
4214 | return NETDEV_TX_OK; | 4217 | return NETDEV_TX_OK; |
4215 | } | 4218 | } |
4216 | } | 4219 | } |
@@ -4232,7 +4235,7 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4232 | if (bond->slave_cnt) | 4235 | if (bond->slave_cnt) |
4233 | ret = __bond_start_xmit(skb, dev); | 4236 | ret = __bond_start_xmit(skb, dev); |
4234 | else | 4237 | else |
4235 | dev_kfree_skb(skb); | 4238 | kfree_skb(skb); |
4236 | 4239 | ||
4237 | read_unlock(&bond->lock); | 4240 | read_unlock(&bond->lock); |
4238 | 4241 | ||