aboutsummaryrefslogtreecommitdiffstats
path: root/net/phonet/af_phonet.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/phonet/af_phonet.c')
-rw-r--r--net/phonet/af_phonet.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index cc2eef169a8b..66737aa995ea 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -394,6 +394,38 @@ static int phonet_rcv(struct sk_buff *skb, struct net_device *dev,
394 send_obj_unreachable(skb); 394 send_obj_unreachable(skb);
395 send_reset_indications(skb); 395 send_reset_indications(skb);
396 } 396 }
397 } else if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
398 goto out; /* Race between address deletion and loopback */
399 else {
400 /* Phonet packet routing */
401 struct net_device *out_dev;
402
403 out_dev = phonet_route_output(net, pn_sockaddr_get_addr(&sa));
404 if (!out_dev) {
405 LIMIT_NETDEBUG(KERN_WARNING"No Phonet route to %02X\n",
406 pn_sockaddr_get_addr(&sa));
407 goto out;
408 }
409
410 __skb_push(skb, sizeof(struct phonethdr));
411 skb->dev = out_dev;
412 if (out_dev == dev) {
413 LIMIT_NETDEBUG(KERN_ERR"Phonet loop to %02X on %s\n",
414 pn_sockaddr_get_addr(&sa), dev->name);
415 goto out_dev;
416 }
417 /* Some drivers (e.g. TUN) do not allocate HW header space */
418 if (skb_cow_head(skb, out_dev->hard_header_len))
419 goto out_dev;
420
421 if (dev_hard_header(skb, out_dev, ETH_P_PHONET, NULL, NULL,
422 skb->len) < 0)
423 goto out_dev;
424 dev_queue_xmit(skb);
425 dev_put(out_dev);
426 return NET_RX_SUCCESS;
427out_dev:
428 dev_put(out_dev);
397 } 429 }
398 430
399out: 431out: