diff options
author | Rémi Denis-Courmont <remi.denis-courmont@nokia.com> | 2009-10-14 00:48:31 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-14 15:04:18 -0700 |
commit | 86a0a1e52d0918125ffc21475537a032f9a71d7c (patch) | |
tree | 3399525f28536c68781c91e1e702111e7cc2dd6d /net/phonet/af_phonet.c | |
parent | aa6c45f32f7db292f8f6a76d7b39c19007d6a456 (diff) | |
download | linux-86a0a1e52d0918125ffc21475537a032f9a71d7c.tar.gz linux-86a0a1e52d0918125ffc21475537a032f9a71d7c.tar.bz2 linux-86a0a1e52d0918125ffc21475537a032f9a71d7c.zip |
Phonet: forward incoming packets
Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/phonet/af_phonet.c')
-rw-r--r-- | net/phonet/af_phonet.c | 32 |
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, send_obj_unreachable(skb); send_reset_indications(skb); } + } else if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) + goto out; /* Race between address deletion and loopback */ + else { + /* Phonet packet routing */ + struct net_device *out_dev; + + out_dev = phonet_route_output(net, pn_sockaddr_get_addr(&sa)); + if (!out_dev) { + LIMIT_NETDEBUG(KERN_WARNING"No Phonet route to %02X\n", + pn_sockaddr_get_addr(&sa)); + goto out; + } + + __skb_push(skb, sizeof(struct phonethdr)); + skb->dev = out_dev; + if (out_dev == dev) { + LIMIT_NETDEBUG(KERN_ERR"Phonet loop to %02X on %s\n", + pn_sockaddr_get_addr(&sa), dev->name); + goto out_dev; + } + /* Some drivers (e.g. TUN) do not allocate HW header space */ + if (skb_cow_head(skb, out_dev->hard_header_len)) + goto out_dev; + + if (dev_hard_header(skb, out_dev, ETH_P_PHONET, NULL, NULL, + skb->len) < 0) + goto out_dev; + dev_queue_xmit(skb); + dev_put(out_dev); + return NET_RX_SUCCESS; +out_dev: + dev_put(out_dev); } out: |