mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
commit
c9bdc0dde1
|
@ -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 @@
|
||||||
* @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 {
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
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)
|
||||||
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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue