aboutsummaryrefslogtreecommitdiffstats
path: root/net/atm/clip.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/atm/clip.c')
-rw-r--r--net/atm/clip.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/net/atm/clip.c b/net/atm/clip.c
index c12c2582457c..ef95a30306fa 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -328,6 +328,8 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
328 struct atmarp_entry *entry; 328 struct atmarp_entry *entry;
329 struct neighbour *n; 329 struct neighbour *n;
330 struct atm_vcc *vcc; 330 struct atm_vcc *vcc;
331 struct rtable *rt;
332 __be32 *daddr;
331 int old; 333 int old;
332 unsigned long flags; 334 unsigned long flags;
333 335
@@ -338,7 +340,12 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
338 dev->stats.tx_dropped++; 340 dev->stats.tx_dropped++;
339 return NETDEV_TX_OK; 341 return NETDEV_TX_OK;
340 } 342 }
341 n = dst_get_neighbour_noref(dst); 343 rt = (struct rtable *) dst;
344 if (rt->rt_gateway)
345 daddr = &rt->rt_gateway;
346 else
347 daddr = &ip_hdr(skb)->daddr;
348 n = dst_neigh_lookup(dst, daddr);
342 if (!n) { 349 if (!n) {
343 pr_err("NO NEIGHBOUR !\n"); 350 pr_err("NO NEIGHBOUR !\n");
344 dev_kfree_skb(skb); 351 dev_kfree_skb(skb);
@@ -358,7 +365,7 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
358 dev_kfree_skb(skb); 365 dev_kfree_skb(skb);
359 dev->stats.tx_dropped++; 366 dev->stats.tx_dropped++;
360 } 367 }
361 return NETDEV_TX_OK; 368 goto out_release_neigh;
362 } 369 }
363 pr_debug("neigh %p, vccs %p\n", entry, entry->vccs); 370 pr_debug("neigh %p, vccs %p\n", entry, entry->vccs);
364 ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc; 371 ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc;
@@ -377,14 +384,14 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
377 old = xchg(&entry->vccs->xoff, 1); /* assume XOFF ... */ 384 old = xchg(&entry->vccs->xoff, 1); /* assume XOFF ... */
378 if (old) { 385 if (old) {
379 pr_warning("XOFF->XOFF transition\n"); 386 pr_warning("XOFF->XOFF transition\n");
380 return NETDEV_TX_OK; 387 goto out_release_neigh;
381 } 388 }
382 dev->stats.tx_packets++; 389 dev->stats.tx_packets++;
383 dev->stats.tx_bytes += skb->len; 390 dev->stats.tx_bytes += skb->len;
384 vcc->send(vcc, skb); 391 vcc->send(vcc, skb);
385 if (atm_may_send(vcc, 0)) { 392 if (atm_may_send(vcc, 0)) {
386 entry->vccs->xoff = 0; 393 entry->vccs->xoff = 0;
387 return NETDEV_TX_OK; 394 goto out_release_neigh;
388 } 395 }
389 spin_lock_irqsave(&clip_priv->xoff_lock, flags); 396 spin_lock_irqsave(&clip_priv->xoff_lock, flags);
390 netif_stop_queue(dev); /* XOFF -> throttle immediately */ 397 netif_stop_queue(dev); /* XOFF -> throttle immediately */
@@ -396,6 +403,8 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
396 of the brief netif_stop_queue. If this isn't true or if it 403 of the brief netif_stop_queue. If this isn't true or if it
397 changes, use netif_wake_queue instead. */ 404 changes, use netif_wake_queue instead. */
398 spin_unlock_irqrestore(&clip_priv->xoff_lock, flags); 405 spin_unlock_irqrestore(&clip_priv->xoff_lock, flags);
406out_release_neigh:
407 neigh_release(n);
399 return NETDEV_TX_OK; 408 return NETDEV_TX_OK;
400} 409}
401 410