From 945db424bfbcb7b72a92702a487dc0000cd1efed Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Mon, 2 Mar 2015 00:09:42 -0600 Subject: ax25: Stop depending on arp_find Have ax25_neigh_output perform ordinary arp resolution before calling ax25_neigh_xmit. Call dev_hard_header in ax25_neigh_output with a destination address so it will not fail, and the destination mac address will not need to be set in ax25_neigh_xmit. Remove arp_find from ax25_neigh_xmit (the ordinary arp resolution added to ax25_neigh_output removes the need for calling arp_find). Document how close ax25_neigh_output is to neigh_resolve_output. Cc: Ralf Baechle Cc: linux-hams@vger.kernel.org Signed-off-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- net/ax25/ax25_ip.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'net/ax25') diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c index 08803e820f1d..e030c64ebfb7 100644 --- a/net/ax25/ax25_ip.c +++ b/net/ax25/ax25_ip.c @@ -115,9 +115,6 @@ static int ax25_neigh_xmit(struct sk_buff *skb) dst = (ax25_address *)(bp + 1); src = (ax25_address *)(bp + 8); - if (arp_find(bp + 1, skb)) - return 1; - route = ax25_get_route(dst, NULL); if (route) { digipeat = route->digipeat; @@ -218,16 +215,35 @@ put: static int ax25_neigh_output(struct neighbour *neigh, struct sk_buff *skb) { - struct net_device *dev = skb->dev; - - __skb_pull(skb, skb_network_offset(skb)); - - if (dev_hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL, - skb->len) < 0 && - ax25_neigh_xmit(skb)); - return 0; + /* Except for calling ax25_neigh_xmit instead of + * dev_queue_xmit this is neigh_resolve_output. + */ + int rc = 0; + + if (!neigh_event_send(neigh, skb)) { + int err; + struct net_device *dev = neigh->dev; + unsigned int seq; + + do { + __skb_pull(skb, skb_network_offset(skb)); + seq = read_seqbegin(&neigh->ha_lock); + err = dev_hard_header(skb, dev, ntohs(skb->protocol), + neigh->ha, NULL, skb->len); + } while (read_seqretry(&neigh->ha_lock, seq)); + + if (err >= 0) { + ax25_neigh_xmit(skb); + } else + goto out_kfree_skb; + } +out: + return rc; - return dev_queue_xmit(skb); +out_kfree_skb: + rc = -EINVAL; + kfree_skb(skb); + goto out; } int ax25_neigh_construct(struct neighbour *neigh) -- cgit v1.2.3