Commit c9bdc0dd authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents de1cf8a7 f2f8036e
...@@ -845,8 +845,10 @@ int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dnode, ...@@ -845,8 +845,10 @@ int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dnode,
if (link) if (link)
return rc; return rc;
if (likely(in_own_node(net, dnode))) if (likely(in_own_node(net, dnode))) {
return tipc_sk_rcv(net, list); tipc_sk_rcv(net, list);
return 0;
}
__skb_queue_purge(list); __skb_queue_purge(list);
return rc; return rc;
......
...@@ -74,6 +74,7 @@ ...@@ -74,6 +74,7 @@
* @link_cong: non-zero if owner must sleep because of link congestion * @link_cong: non-zero if owner must sleep because of link congestion
* @sent_unacked: # messages sent by socket, and not yet acked by peer * @sent_unacked: # messages sent by socket, and not yet acked by peer
* @rcv_unacked: # messages read by user, but not yet acked back to peer * @rcv_unacked: # messages read by user, but not yet acked back to peer
* @remote: 'connected' peer for dgram/rdm
* @node: hash table node * @node: hash table node
* @rcu: rcu struct for tipc_sock * @rcu: rcu struct for tipc_sock
*/ */
...@@ -96,6 +97,7 @@ struct tipc_sock { ...@@ -96,6 +97,7 @@ struct tipc_sock {
bool link_cong; bool link_cong;
uint sent_unacked; uint sent_unacked;
uint rcv_unacked; uint rcv_unacked;
struct sockaddr_tipc remote;
struct rhash_head node; struct rhash_head node;
struct rcu_head rcu; struct rcu_head rcu;
}; };
...@@ -854,22 +856,23 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz) ...@@ -854,22 +856,23 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
u32 dnode, dport; u32 dnode, dport;
struct sk_buff_head *pktchain = &sk->sk_write_queue; struct sk_buff_head *pktchain = &sk->sk_write_queue;
struct sk_buff *skb; struct sk_buff *skb;
struct tipc_name_seq *seq = &dest->addr.nameseq; struct tipc_name_seq *seq;
struct iov_iter save; struct iov_iter save;
u32 mtu; u32 mtu;
long timeo; long timeo;
int rc; int rc;
if (unlikely(!dest))
return -EDESTADDRREQ;
if (unlikely((m->msg_namelen < sizeof(*dest)) ||
(dest->family != AF_TIPC)))
return -EINVAL;
if (dsz > TIPC_MAX_USER_MSG_SIZE) if (dsz > TIPC_MAX_USER_MSG_SIZE)
return -EMSGSIZE; return -EMSGSIZE;
if (unlikely(!dest)) {
if (tsk->connected && sock->state == SS_READY)
dest = &tsk->remote;
else
return -EDESTADDRREQ;
} else if (unlikely(m->msg_namelen < sizeof(*dest)) ||
dest->family != AF_TIPC) {
return -EINVAL;
}
if (unlikely(sock->state != SS_READY)) { if (unlikely(sock->state != SS_READY)) {
if (sock->state == SS_LISTENING) if (sock->state == SS_LISTENING)
return -EPIPE; return -EPIPE;
...@@ -882,7 +885,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz) ...@@ -882,7 +885,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
tsk->conn_instance = dest->addr.name.name.instance; tsk->conn_instance = dest->addr.name.name.instance;
} }
} }
seq = &dest->addr.nameseq;
timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
if (dest->addrtype == TIPC_ADDR_MCAST) { if (dest->addrtype == TIPC_ADDR_MCAST) {
...@@ -1833,17 +1836,24 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest, ...@@ -1833,17 +1836,24 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
int destlen, int flags) int destlen, int flags)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct tipc_sock *tsk = tipc_sk(sk);
struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest; struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest;
struct msghdr m = {NULL,}; struct msghdr m = {NULL,};
long timeout = (flags & O_NONBLOCK) ? 0 : tipc_sk(sk)->conn_timeout; long timeout = (flags & O_NONBLOCK) ? 0 : tsk->conn_timeout;
socket_state previous; socket_state previous;
int res; int res = 0;
lock_sock(sk); lock_sock(sk);
/* For now, TIPC does not allow use of connect() with DGRAM/RDM types */ /* DGRAM/RDM connect(), just save the destaddr */
if (sock->state == SS_READY) { if (sock->state == SS_READY) {
res = -EOPNOTSUPP; if (dst->family == AF_UNSPEC) {
memset(&tsk->remote, 0, sizeof(struct sockaddr_tipc));
tsk->connected = 0;
} else {
memcpy(&tsk->remote, dest, destlen);
tsk->connected = 1;
}
goto exit; goto exit;
} }
...@@ -2078,7 +2088,6 @@ static int tipc_shutdown(struct socket *sock, int how) ...@@ -2078,7 +2088,6 @@ static int tipc_shutdown(struct socket *sock, int how)
TIPC_CONN_SHUTDOWN)) TIPC_CONN_SHUTDOWN))
tipc_link_xmit_skb(net, skb, dnode, tipc_link_xmit_skb(net, skb, dnode,
tsk->portid); tsk->portid);
tipc_node_remove_conn(net, dnode, tsk->portid);
} else { } else {
dnode = tsk_peer_node(tsk); dnode = tsk_peer_node(tsk);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment