aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-03-19 12:26:01 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-19 12:26:01 -0400
commitc9bdc0dde187e5f6b481989b4084c1b7cbe2726f (patch)
treeaebead12cc0faf722ad62b94826730754830dd1b /net/tipc
parentde1cf8a7d7a369bc7d63f7be27e3d84ad6a69bb2 (diff)
parentf2f8036e391eb82ee78764483f869f2feafb5da8 (diff)
Merge branch 'tipc-next'
Erik Hugne says: ==================== tipc: small bugfix an support for datagram connect() Most notable in this series is patch#3 that allows programs to associate a tipc address with a connectionless (RDM/DGRAM) socket. v2: Fix indent issue in patch#3 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/link.c6
-rw-r--r--net/tipc/socket.c39
2 files changed, 28 insertions, 17 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index bc49120bfb44..8c98c4d00ad6 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -845,8 +845,10 @@ int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dnode,
845 if (link) 845 if (link)
846 return rc; 846 return rc;
847 847
848 if (likely(in_own_node(net, dnode))) 848 if (likely(in_own_node(net, dnode))) {
849 return tipc_sk_rcv(net, list); 849 tipc_sk_rcv(net, list);
850 return 0;
851 }
850 852
851 __skb_queue_purge(list); 853 __skb_queue_purge(list);
852 return rc; 854 return rc;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index d7a6c10202e9..c03a3d33806f 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -74,6 +74,7 @@
74 * @link_cong: non-zero if owner must sleep because of link congestion 74 * @link_cong: non-zero if owner must sleep because of link congestion
75 * @sent_unacked: # messages sent by socket, and not yet acked by peer 75 * @sent_unacked: # messages sent by socket, and not yet acked by peer
76 * @rcv_unacked: # messages read by user, but not yet acked back to peer 76 * @rcv_unacked: # messages read by user, but not yet acked back to peer
77 * @remote: 'connected' peer for dgram/rdm
77 * @node: hash table node 78 * @node: hash table node
78 * @rcu: rcu struct for tipc_sock 79 * @rcu: rcu struct for tipc_sock
79 */ 80 */
@@ -96,6 +97,7 @@ struct tipc_sock {
96 bool link_cong; 97 bool link_cong;
97 uint sent_unacked; 98 uint sent_unacked;
98 uint rcv_unacked; 99 uint rcv_unacked;
100 struct sockaddr_tipc remote;
99 struct rhash_head node; 101 struct rhash_head node;
100 struct rcu_head rcu; 102 struct rcu_head rcu;
101}; 103};
@@ -854,22 +856,23 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
854 u32 dnode, dport; 856 u32 dnode, dport;
855 struct sk_buff_head *pktchain = &sk->sk_write_queue; 857 struct sk_buff_head *pktchain = &sk->sk_write_queue;
856 struct sk_buff *skb; 858 struct sk_buff *skb;
857 struct tipc_name_seq *seq = &dest->addr.nameseq; 859 struct tipc_name_seq *seq;
858 struct iov_iter save; 860 struct iov_iter save;
859 u32 mtu; 861 u32 mtu;
860 long timeo; 862 long timeo;
861 int rc; 863 int rc;
862 864
863 if (unlikely(!dest))
864 return -EDESTADDRREQ;
865
866 if (unlikely((m->msg_namelen < sizeof(*dest)) ||
867 (dest->family != AF_TIPC)))
868 return -EINVAL;
869
870 if (dsz > TIPC_MAX_USER_MSG_SIZE) 865 if (dsz > TIPC_MAX_USER_MSG_SIZE)
871 return -EMSGSIZE; 866 return -EMSGSIZE;
872 867 if (unlikely(!dest)) {
868 if (tsk->connected && sock->state == SS_READY)
869 dest = &tsk->remote;
870 else
871 return -EDESTADDRREQ;
872 } else if (unlikely(m->msg_namelen < sizeof(*dest)) ||
873 dest->family != AF_TIPC) {
874 return -EINVAL;
875 }
873 if (unlikely(sock->state != SS_READY)) { 876 if (unlikely(sock->state != SS_READY)) {
874 if (sock->state == SS_LISTENING) 877 if (sock->state == SS_LISTENING)
875 return -EPIPE; 878 return -EPIPE;
@@ -882,7 +885,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
882 tsk->conn_instance = dest->addr.name.name.instance; 885 tsk->conn_instance = dest->addr.name.name.instance;
883 } 886 }
884 } 887 }
885 888 seq = &dest->addr.nameseq;
886 timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); 889 timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
887 890
888 if (dest->addrtype == TIPC_ADDR_MCAST) { 891 if (dest->addrtype == TIPC_ADDR_MCAST) {
@@ -1833,17 +1836,24 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
1833 int destlen, int flags) 1836 int destlen, int flags)
1834{ 1837{
1835 struct sock *sk = sock->sk; 1838 struct sock *sk = sock->sk;
1839 struct tipc_sock *tsk = tipc_sk(sk);
1836 struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest; 1840 struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest;
1837 struct msghdr m = {NULL,}; 1841 struct msghdr m = {NULL,};
1838 long timeout = (flags & O_NONBLOCK) ? 0 : tipc_sk(sk)->conn_timeout; 1842 long timeout = (flags & O_NONBLOCK) ? 0 : tsk->conn_timeout;
1839 socket_state previous; 1843 socket_state previous;
1840 int res; 1844 int res = 0;
1841 1845
1842 lock_sock(sk); 1846 lock_sock(sk);
1843 1847
1844 /* For now, TIPC does not allow use of connect() with DGRAM/RDM types */ 1848 /* DGRAM/RDM connect(), just save the destaddr */
1845 if (sock->state == SS_READY) { 1849 if (sock->state == SS_READY) {
1846 res = -EOPNOTSUPP; 1850 if (dst->family == AF_UNSPEC) {
1851 memset(&tsk->remote, 0, sizeof(struct sockaddr_tipc));
1852 tsk->connected = 0;
1853 } else {
1854 memcpy(&tsk->remote, dest, destlen);
1855 tsk->connected = 1;
1856 }
1847 goto exit; 1857 goto exit;
1848 } 1858 }
1849 1859
@@ -2078,7 +2088,6 @@ restart:
2078 TIPC_CONN_SHUTDOWN)) 2088 TIPC_CONN_SHUTDOWN))
2079 tipc_link_xmit_skb(net, skb, dnode, 2089 tipc_link_xmit_skb(net, skb, dnode,
2080 tsk->portid); 2090 tsk->portid);
2081 tipc_node_remove_conn(net, dnode, tsk->portid);
2082 } else { 2091 } else {
2083 dnode = tsk_peer_node(tsk); 2092 dnode = tsk_peer_node(tsk);
2084 2093