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