From: David S. Miller Date: Wed, 1 Feb 2012 21:34:25 +0000 (-0500) Subject: decnet: Add missing neigh->ha locking to dn_neigh_output_packet() X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=3329bdfc4071840816d6666c6463fdb0bd4c8264;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git 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 --- 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) struct neighbour *neigh = dst_get_neighbour_noref(dst); struct net_device *dev = neigh->dev; char mac_addr[ETH_ALEN]; + unsigned int seq; + int err; dn_dn2eth(mac_addr, rt->rt_local_src); - if (dev_hard_header(skb, dev, ntohs(skb->protocol), neigh->ha, - mac_addr, skb->len) >= 0) - return dev_queue_xmit(skb); - - if (net_ratelimit()) - printk(KERN_DEBUG "dn_neigh_output_packet: oops, can't send packet\n"); - - kfree_skb(skb); - return -EINVAL; + do { + seq = read_seqbegin(&neigh->ha_lock); + err = dev_hard_header(skb, dev, ntohs(skb->protocol), + neigh->ha, mac_addr, skb->len); + } while (read_seqretry(&neigh->ha_lock, seq)); + + if (err >= 0) + err = dev_queue_xmit(skb); + else { + kfree_skb(skb); + err = -EINVAL; + } + return err; } static int dn_long_output(struct neighbour *neigh, struct sk_buff *skb)