Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <ralf@linux-mips.org>
Cc: linux-hams@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Eric W. Biederman and committed by
David S. Miller
945db424 abb7b755

+26 -10
+26 -10
net/ax25/ax25_ip.c
··· 115 115 dst = (ax25_address *)(bp + 1); 116 116 src = (ax25_address *)(bp + 8); 117 117 118 - if (arp_find(bp + 1, skb)) 119 - return 1; 120 - 121 118 route = ax25_get_route(dst, NULL); 122 119 if (route) { 123 120 digipeat = route->digipeat; ··· 215 218 216 219 static int ax25_neigh_output(struct neighbour *neigh, struct sk_buff *skb) 217 220 { 218 - struct net_device *dev = skb->dev; 221 + /* Except for calling ax25_neigh_xmit instead of 222 + * dev_queue_xmit this is neigh_resolve_output. 223 + */ 224 + int rc = 0; 219 225 220 - __skb_pull(skb, skb_network_offset(skb)); 226 + if (!neigh_event_send(neigh, skb)) { 227 + int err; 228 + struct net_device *dev = neigh->dev; 229 + unsigned int seq; 221 230 222 - if (dev_hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL, 223 - skb->len) < 0 && 224 - ax25_neigh_xmit(skb)); 225 - return 0; 231 + do { 232 + __skb_pull(skb, skb_network_offset(skb)); 233 + seq = read_seqbegin(&neigh->ha_lock); 234 + err = dev_hard_header(skb, dev, ntohs(skb->protocol), 235 + neigh->ha, NULL, skb->len); 236 + } while (read_seqretry(&neigh->ha_lock, seq)); 226 237 227 - return dev_queue_xmit(skb); 238 + if (err >= 0) { 239 + ax25_neigh_xmit(skb); 240 + } else 241 + goto out_kfree_skb; 242 + } 243 + out: 244 + return rc; 245 + 246 + out_kfree_skb: 247 + rc = -EINVAL; 248 + kfree_skb(skb); 249 + goto out; 228 250 } 229 251 230 252 int ax25_neigh_construct(struct neighbour *neigh)