diff options
author | David S. Miller <davem@davemloft.net> | 2012-02-01 16:34:25 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-02-01 16:34:25 -0500 |
commit | 3329bdfc4071840816d6666c6463fdb0bd4c8264 (patch) | |
tree | 93e0cb011640d524fc54dedeb3d373068c138152 /net/decnet | |
parent | f79d52c254e4e2cef3da64dc02ade3bc8f10c539 (diff) |
decnet: Add missing neigh->ha locking to dn_neigh_output_packet()
Basically, mirror the logic in neigh_connected_output().
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/decnet')
-rw-r--r-- | net/decnet/dn_neigh.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index befe426491ba..ee7013f24fca 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c | |||
@@ -205,17 +205,23 @@ static int dn_neigh_output_packet(struct sk_buff *skb) | |||
205 | struct neighbour *neigh = dst_get_neighbour_noref(dst); | 205 | struct neighbour *neigh = dst_get_neighbour_noref(dst); |
206 | struct net_device *dev = neigh->dev; | 206 | struct net_device *dev = neigh->dev; |
207 | char mac_addr[ETH_ALEN]; | 207 | char mac_addr[ETH_ALEN]; |
208 | unsigned int seq; | ||
209 | int err; | ||
208 | 210 | ||
209 | dn_dn2eth(mac_addr, rt->rt_local_src); | 211 | dn_dn2eth(mac_addr, rt->rt_local_src); |
210 | if (dev_hard_header(skb, dev, ntohs(skb->protocol), neigh->ha, | 212 | do { |
211 | mac_addr, skb->len) >= 0) | 213 | seq = read_seqbegin(&neigh->ha_lock); |
212 | return dev_queue_xmit(skb); | 214 | err = dev_hard_header(skb, dev, ntohs(skb->protocol), |
213 | 215 | neigh->ha, mac_addr, skb->len); | |
214 | if (net_ratelimit()) | 216 | } while (read_seqretry(&neigh->ha_lock, seq)); |
215 | printk(KERN_DEBUG "dn_neigh_output_packet: oops, can't send packet\n"); | 217 | |
216 | 218 | if (err >= 0) | |
217 | kfree_skb(skb); | 219 | err = dev_queue_xmit(skb); |
218 | return -EINVAL; | 220 | else { |
221 | kfree_skb(skb); | ||
222 | err = -EINVAL; | ||
223 | } | ||
224 | return err; | ||
219 | } | 225 | } |
220 | 226 | ||
221 | static int dn_long_output(struct neighbour *neigh, struct sk_buff *skb) | 227 | static int dn_long_output(struct neighbour *neigh, struct sk_buff *skb) |