diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 1d98bfcda6f6..e14b2aedb212 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -1739,7 +1739,7 @@ static int filter_rcv(struct sock *sk, struct sk_buff **skb) | |||
1739 | * @sk: socket | 1739 | * @sk: socket |
1740 | * @skb: message | 1740 | * @skb: message |
1741 | * | 1741 | * |
1742 | * Caller must hold socket lock, but not port lock. | 1742 | * Caller must hold socket lock |
1743 | * | 1743 | * |
1744 | * Returns 0 | 1744 | * Returns 0 |
1745 | */ | 1745 | */ |
@@ -1805,27 +1805,31 @@ int tipc_sk_rcv(struct net *net, struct sk_buff *skb) | |||
1805 | struct tipc_net *tn; | 1805 | struct tipc_net *tn; |
1806 | struct sock *sk; | 1806 | struct sock *sk; |
1807 | u32 dport = msg_destport(buf_msg(skb)); | 1807 | u32 dport = msg_destport(buf_msg(skb)); |
1808 | int err; | 1808 | int err = -TIPC_ERR_NO_PORT; |
1809 | u32 dnode; | 1809 | u32 dnode; |
1810 | 1810 | ||
1811 | /* Validate destination and message */ | 1811 | /* Find destination */ |
1812 | tsk = tipc_sk_lookup(net, dport); | 1812 | tsk = tipc_sk_lookup(net, dport); |
1813 | if (unlikely(!tsk)) { | 1813 | if (likely(tsk)) { |
1814 | err = tipc_msg_eval(net, skb, &dnode); | 1814 | sk = &tsk->sk; |
1815 | goto exit; | 1815 | spin_lock_bh(&sk->sk_lock.slock); |
1816 | } | 1816 | err = tipc_sk_enqueue_skb(sk, &skb); |
1817 | sk = &tsk->sk; | 1817 | spin_unlock_bh(&sk->sk_lock.slock); |
1818 | 1818 | sock_put(sk); | |
1819 | spin_lock_bh(&sk->sk_lock.slock); | ||
1820 | err = tipc_sk_enqueue_skb(sk, &skb); | ||
1821 | spin_unlock_bh(&sk->sk_lock.slock); | ||
1822 | sock_put(sk); | ||
1823 | exit: | ||
1824 | if (unlikely(skb)) { | ||
1825 | tn = net_generic(net, tipc_net_id); | ||
1826 | if (!err || tipc_msg_reverse(tn->own_addr, skb, &dnode, -err)) | ||
1827 | tipc_link_xmit_skb(net, skb, dnode, 0); | ||
1828 | } | 1819 | } |
1820 | if (likely(!skb)) | ||
1821 | return 0; | ||
1822 | if (tipc_msg_lookup_dest(net, skb, &dnode, &err)) | ||
1823 | goto xmit; | ||
1824 | if (!err) { | ||
1825 | dnode = msg_destnode(buf_msg(skb)); | ||
1826 | goto xmit; | ||
1827 | } | ||
1828 | tn = net_generic(net, tipc_net_id); | ||
1829 | if (!tipc_msg_reverse(tn->own_addr, skb, &dnode, -err)) | ||
1830 | return -EHOSTUNREACH; | ||
1831 | xmit: | ||
1832 | tipc_link_xmit_skb(net, skb, dnode, dport); | ||
1829 | return err ? -EHOSTUNREACH : 0; | 1833 | return err ? -EHOSTUNREACH : 0; |
1830 | } | 1834 | } |
1831 | 1835 | ||