aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c120
1 files changed, 58 insertions, 62 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index b384e658dfeb..f9cd587e4090 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -818,17 +818,14 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff *buf)
818/** 818/**
819 * tipc_sk_proto_rcv - receive a connection mng protocol message 819 * tipc_sk_proto_rcv - receive a connection mng protocol message
820 * @tsk: receiving socket 820 * @tsk: receiving socket
821 * @dnode: node to send response message to, if any 821 * @skb: pointer to message buffer. Set to NULL if buffer is consumed.
822 * @buf: buffer containing protocol message
823 * Returns 0 (TIPC_OK) if message was consumed, 1 (TIPC_FWD_MSG) if
824 * (CONN_PROBE_REPLY) message should be forwarded.
825 */ 822 */
826static int tipc_sk_proto_rcv(struct tipc_sock *tsk, u32 *dnode, 823static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff **skb)
827 struct sk_buff *buf)
828{ 824{
829 struct tipc_msg *msg = buf_msg(buf); 825 struct tipc_msg *msg = buf_msg(*skb);
830 int conn_cong; 826 int conn_cong;
831 827 u32 dnode;
828 u32 own_node = tsk_own_node(tsk);
832 /* Ignore if connection cannot be validated: */ 829 /* Ignore if connection cannot be validated: */
833 if (!tsk_peer_msg(tsk, msg)) 830 if (!tsk_peer_msg(tsk, msg))
834 goto exit; 831 goto exit;
@@ -841,15 +838,15 @@ static int tipc_sk_proto_rcv(struct tipc_sock *tsk, u32 *dnode,
841 if (conn_cong) 838 if (conn_cong)
842 tsk->sk.sk_write_space(&tsk->sk); 839 tsk->sk.sk_write_space(&tsk->sk);
843 } else if (msg_type(msg) == CONN_PROBE) { 840 } else if (msg_type(msg) == CONN_PROBE) {
844 if (!tipc_msg_reverse(tsk_own_node(tsk), buf, dnode, TIPC_OK)) 841 if (tipc_msg_reverse(own_node, *skb, &dnode, TIPC_OK)) {
845 return TIPC_OK; 842 msg_set_type(msg, CONN_PROBE_REPLY);
846 msg_set_type(msg, CONN_PROBE_REPLY); 843 return;
847 return TIPC_FWD_MSG; 844 }
848 } 845 }
849 /* Do nothing if msg_type() == CONN_PROBE_REPLY */ 846 /* Do nothing if msg_type() == CONN_PROBE_REPLY */
850exit: 847exit:
851 kfree_skb(buf); 848 kfree_skb(*skb);
852 return TIPC_OK; 849 *skb = NULL;
853} 850}
854 851
855static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p) 852static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p)
@@ -1568,16 +1565,16 @@ static void tipc_data_ready(struct sock *sk)
1568/** 1565/**
1569 * filter_connect - Handle all incoming messages for a connection-based socket 1566 * filter_connect - Handle all incoming messages for a connection-based socket
1570 * @tsk: TIPC socket 1567 * @tsk: TIPC socket
1571 * @msg: message 1568 * @skb: pointer to message buffer. Set to NULL if buffer is consumed
1572 * 1569 *
1573 * Returns 0 (TIPC_OK) if everything ok, -TIPC_ERR_NO_PORT otherwise 1570 * Returns 0 (TIPC_OK) if everything ok, -TIPC_ERR_NO_PORT otherwise
1574 */ 1571 */
1575static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf) 1572static int filter_connect(struct tipc_sock *tsk, struct sk_buff **skb)
1576{ 1573{
1577 struct sock *sk = &tsk->sk; 1574 struct sock *sk = &tsk->sk;
1578 struct net *net = sock_net(sk); 1575 struct net *net = sock_net(sk);
1579 struct socket *sock = sk->sk_socket; 1576 struct socket *sock = sk->sk_socket;
1580 struct tipc_msg *msg = buf_msg(*buf); 1577 struct tipc_msg *msg = buf_msg(*skb);
1581 int retval = -TIPC_ERR_NO_PORT; 1578 int retval = -TIPC_ERR_NO_PORT;
1582 1579
1583 if (msg_mcast(msg)) 1580 if (msg_mcast(msg))
@@ -1627,8 +1624,8 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
1627 * connect() routine if sleeping. 1624 * connect() routine if sleeping.
1628 */ 1625 */
1629 if (msg_data_sz(msg) == 0) { 1626 if (msg_data_sz(msg) == 0) {
1630 kfree_skb(*buf); 1627 kfree_skb(*skb);
1631 *buf = NULL; 1628 *skb = NULL;
1632 if (waitqueue_active(sk_sleep(sk))) 1629 if (waitqueue_active(sk_sleep(sk)))
1633 wake_up_interruptible(sk_sleep(sk)); 1630 wake_up_interruptible(sk_sleep(sk));
1634 } 1631 }
@@ -1680,32 +1677,33 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *buf)
1680/** 1677/**
1681 * filter_rcv - validate incoming message 1678 * filter_rcv - validate incoming message
1682 * @sk: socket 1679 * @sk: socket
1683 * @buf: message 1680 * @skb: pointer to message. Set to NULL if buffer is consumed.
1684 * 1681 *
1685 * Enqueues message on receive queue if acceptable; optionally handles 1682 * Enqueues message on receive queue if acceptable; optionally handles
1686 * disconnect indication for a connected socket. 1683 * disconnect indication for a connected socket.
1687 * 1684 *
1688 * Called with socket lock already taken; port lock may also be taken. 1685 * Called with socket lock already taken
1689 * 1686 *
1690 * Returns 0 (TIPC_OK) if message was consumed, -TIPC error code if message 1687 * Returns 0 (TIPC_OK) if message was ok, -TIPC error code if rejected
1691 * to be rejected, 1 (TIPC_FWD_MSG) if (CONN_MANAGER) message to be forwarded
1692 */ 1688 */
1693static int filter_rcv(struct sock *sk, struct sk_buff *buf) 1689static int filter_rcv(struct sock *sk, struct sk_buff **skb)
1694{ 1690{
1695 struct socket *sock = sk->sk_socket; 1691 struct socket *sock = sk->sk_socket;
1696 struct tipc_sock *tsk = tipc_sk(sk); 1692 struct tipc_sock *tsk = tipc_sk(sk);
1697 struct tipc_msg *msg = buf_msg(buf); 1693 struct tipc_msg *msg = buf_msg(*skb);
1698 unsigned int limit = rcvbuf_limit(sk, buf); 1694 unsigned int limit = rcvbuf_limit(sk, *skb);
1699 u32 onode;
1700 int rc = TIPC_OK; 1695 int rc = TIPC_OK;
1701 1696
1702 if (unlikely(msg_user(msg) == CONN_MANAGER)) 1697 if (unlikely(msg_user(msg) == CONN_MANAGER)) {
1703 return tipc_sk_proto_rcv(tsk, &onode, buf); 1698 tipc_sk_proto_rcv(tsk, skb);
1699 return TIPC_OK;
1700 }
1704 1701
1705 if (unlikely(msg_user(msg) == SOCK_WAKEUP)) { 1702 if (unlikely(msg_user(msg) == SOCK_WAKEUP)) {
1706 kfree_skb(buf); 1703 kfree_skb(*skb);
1707 tsk->link_cong = 0; 1704 tsk->link_cong = 0;
1708 sk->sk_write_space(sk); 1705 sk->sk_write_space(sk);
1706 *skb = NULL;
1709 return TIPC_OK; 1707 return TIPC_OK;
1710 } 1708 }
1711 1709
@@ -1717,21 +1715,22 @@ static int filter_rcv(struct sock *sk, struct sk_buff *buf)
1717 if (msg_connected(msg)) 1715 if (msg_connected(msg))
1718 return -TIPC_ERR_NO_PORT; 1716 return -TIPC_ERR_NO_PORT;
1719 } else { 1717 } else {
1720 rc = filter_connect(tsk, &buf); 1718 rc = filter_connect(tsk, skb);
1721 if (rc != TIPC_OK || buf == NULL) 1719 if (rc != TIPC_OK || !*skb)
1722 return rc; 1720 return rc;
1723 } 1721 }
1724 1722
1725 /* Reject message if there isn't room to queue it */ 1723 /* Reject message if there isn't room to queue it */
1726 if (sk_rmem_alloc_get(sk) + buf->truesize >= limit) 1724 if (sk_rmem_alloc_get(sk) + (*skb)->truesize >= limit)
1727 return -TIPC_ERR_OVERLOAD; 1725 return -TIPC_ERR_OVERLOAD;
1728 1726
1729 /* Enqueue message */ 1727 /* Enqueue message */
1730 TIPC_SKB_CB(buf)->handle = NULL; 1728 TIPC_SKB_CB(*skb)->handle = NULL;
1731 __skb_queue_tail(&sk->sk_receive_queue, buf); 1729 __skb_queue_tail(&sk->sk_receive_queue, *skb);
1732 skb_set_owner_r(buf, sk); 1730 skb_set_owner_r(*skb, sk);
1733 1731
1734 sk->sk_data_ready(sk); 1732 sk->sk_data_ready(sk);
1733 *skb = NULL;
1735 return TIPC_OK; 1734 return TIPC_OK;
1736} 1735}
1737 1736
@@ -1746,25 +1745,22 @@ static int filter_rcv(struct sock *sk, struct sk_buff *buf)
1746 */ 1745 */
1747static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb) 1746static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
1748{ 1747{
1749 int rc; 1748 int err;
1750 u32 onode; 1749 atomic_t *dcnt;
1750 u32 dnode;
1751 struct tipc_sock *tsk = tipc_sk(sk); 1751 struct tipc_sock *tsk = tipc_sk(sk);
1752 struct net *net = sock_net(sk); 1752 struct net *net = sock_net(sk);
1753 uint truesize = skb->truesize; 1753 uint truesize = skb->truesize;
1754 1754
1755 rc = filter_rcv(sk, skb); 1755 err = filter_rcv(sk, &skb);
1756 1756 if (likely(!skb)) {
1757 if (likely(!rc)) { 1757 dcnt = &tsk->dupl_rcvcnt;
1758 if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT) 1758 if (atomic_read(dcnt) < TIPC_CONN_OVERLOAD_LIMIT)
1759 atomic_add(truesize, &tsk->dupl_rcvcnt); 1759 atomic_add(truesize, dcnt);
1760 return 0; 1760 return 0;
1761 } 1761 }
1762 1762 if (!err || tipc_msg_reverse(tsk_own_node(tsk), skb, &dnode, -err))
1763 if ((rc < 0) && !tipc_msg_reverse(tsk_own_node(tsk), skb, &onode, -rc)) 1763 tipc_link_xmit_skb(net, skb, dnode, tsk->portid);
1764 return 0;
1765
1766 tipc_link_xmit_skb(net, skb, onode, 0);
1767
1768 return 0; 1764 return 0;
1769} 1765}
1770 1766
@@ -1780,14 +1776,14 @@ int tipc_sk_rcv(struct net *net, struct sk_buff *skb)
1780 struct tipc_net *tn; 1776 struct tipc_net *tn;
1781 struct sock *sk; 1777 struct sock *sk;
1782 u32 dport = msg_destport(buf_msg(skb)); 1778 u32 dport = msg_destport(buf_msg(skb));
1783 int rc = TIPC_OK; 1779 int err = TIPC_OK;
1784 uint limit; 1780 uint limit;
1785 u32 dnode; 1781 u32 dnode;
1786 1782
1787 /* Validate destination and message */ 1783 /* Validate destination and message */
1788 tsk = tipc_sk_lookup(net, dport); 1784 tsk = tipc_sk_lookup(net, dport);
1789 if (unlikely(!tsk)) { 1785 if (unlikely(!tsk)) {
1790 rc = tipc_msg_eval(net, skb, &dnode); 1786 err = tipc_msg_eval(net, skb, &dnode);
1791 goto exit; 1787 goto exit;
1792 } 1788 }
1793 sk = &tsk->sk; 1789 sk = &tsk->sk;
@@ -1796,25 +1792,25 @@ int tipc_sk_rcv(struct net *net, struct sk_buff *skb)
1796 spin_lock_bh(&sk->sk_lock.slock); 1792 spin_lock_bh(&sk->sk_lock.slock);
1797 1793
1798 if (!sock_owned_by_user(sk)) { 1794 if (!sock_owned_by_user(sk)) {
1799 rc = filter_rcv(sk, skb); 1795 err = filter_rcv(sk, &skb);
1800 } else { 1796 } else {
1801 if (sk->sk_backlog.len == 0) 1797 if (sk->sk_backlog.len == 0)
1802 atomic_set(&tsk->dupl_rcvcnt, 0); 1798 atomic_set(&tsk->dupl_rcvcnt, 0);
1803 limit = rcvbuf_limit(sk, skb) + atomic_read(&tsk->dupl_rcvcnt); 1799 limit = rcvbuf_limit(sk, skb) + atomic_read(&tsk->dupl_rcvcnt);
1804 if (sk_add_backlog(sk, skb, limit)) 1800 if (likely(!sk_add_backlog(sk, skb, limit)))
1805 rc = -TIPC_ERR_OVERLOAD; 1801 skb = NULL;
1802 else
1803 err = -TIPC_ERR_OVERLOAD;
1806 } 1804 }
1807 spin_unlock_bh(&sk->sk_lock.slock); 1805 spin_unlock_bh(&sk->sk_lock.slock);
1808 sock_put(sk); 1806 sock_put(sk);
1809 if (likely(!rc))
1810 return 0;
1811exit: 1807exit:
1812 tn = net_generic(net, tipc_net_id); 1808 if (unlikely(skb)) {
1813 if ((rc < 0) && !tipc_msg_reverse(tn->own_addr, skb, &dnode, -rc)) 1809 tn = net_generic(net, tipc_net_id);
1814 return -EHOSTUNREACH; 1810 if (!err || tipc_msg_reverse(tn->own_addr, skb, &dnode, -err))
1815 1811 tipc_link_xmit_skb(net, skb, dnode, 0);
1816 tipc_link_xmit_skb(net, skb, dnode, 0); 1812 }
1817 return (rc < 0) ? -EHOSTUNREACH : 0; 1813 return err ? -EHOSTUNREACH : 0;
1818} 1814}
1819 1815
1820static int tipc_wait_for_connect(struct socket *sock, long *timeo_p) 1816static int tipc_wait_for_connect(struct socket *sock, long *timeo_p)