blob: 6a699671245ba092f7d48e12d190b7f4b809fc11 [file] [log] [blame]
Per Lidenb97bf3f2006-01-02 19:04:38 +01001/*
Jon Paul Maloy02c00c22014-06-09 11:08:18 -05002 * net/tipc/socket.c: TIPC socket API
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09003 *
Jon Paul Maloy8826cde2014-03-12 11:31:09 -04004 * Copyright (c) 2001-2007, 2012-2014, Ericsson AB
Ying Xuec5fa7b32013-06-17 10:54:39 -04005 * Copyright (c) 2004-2008, 2010-2013, Wind River Systems
Per Lidenb97bf3f2006-01-02 19:04:38 +01006 * All rights reserved.
7 *
Per Liden9ea1fd32006-01-11 13:30:43 +01008 * Redistribution and use in source and binary forms, with or without
Per Lidenb97bf3f2006-01-02 19:04:38 +01009 * modification, are permitted provided that the following conditions are met:
10 *
Per Liden9ea1fd32006-01-11 13:30:43 +010011 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
Per Lidenb97bf3f2006-01-02 19:04:38 +010019 *
Per Liden9ea1fd32006-01-11 13:30:43 +010020 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Per Lidenb97bf3f2006-01-02 19:04:38 +010034 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
Per Lidenb97bf3f2006-01-02 19:04:38 +010037#include "core.h"
Jon Paul Maloye2dafe82014-06-25 20:41:37 -050038#include "name_table.h"
Erik Hugne78acb1f2014-04-24 16:26:47 +020039#include "node.h"
Jon Paul Maloye2dafe82014-06-25 20:41:37 -050040#include "link.h"
Erik Hugne2cf8aa12012-06-29 00:16:37 -040041#include <linux/export.h>
Jon Paul Maloy5a9ee0be2014-08-22 18:09:14 -040042#include "config.h"
Jon Paul Maloy2e84c602014-08-22 18:09:18 -040043#include "socket.h"
Erik Hugne2cf8aa12012-06-29 00:16:37 -040044
Per Lidenb97bf3f2006-01-02 19:04:38 +010045#define SS_LISTENING -1 /* socket is listening */
46#define SS_READY -2 /* socket is connectionless */
47
Allan Stephens3654ea02008-04-13 21:35:11 -070048#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */
Jon Paul Maloydadebc02014-08-22 18:09:11 -040049#define CONN_PROBING_INTERVAL 3600000 /* [ms] => 1 h */
Jon Paul Maloyac0074e2014-06-25 20:41:41 -050050#define TIPC_FWD_MSG 1
Per Lidenb97bf3f2006-01-02 19:04:38 +010051
Jon Paul Maloy4f4482d2014-05-14 05:39:09 -040052static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb);
David S. Miller676d2362014-04-11 16:15:36 -040053static void tipc_data_ready(struct sock *sk);
Ying Xuef288bef2012-08-21 11:16:57 +080054static void tipc_write_space(struct sock *sk);
Ying Xue247f0f32014-02-18 16:06:46 +080055static int tipc_release(struct socket *sock);
56static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags);
Jon Paul Maloy0abd8ff2014-07-16 20:41:01 -040057static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p);
Jon Paul Maloy57289012014-08-22 18:09:09 -040058static void tipc_sk_timeout(unsigned long ref);
Jon Paul Maloy0fc87aa2014-08-22 18:09:17 -040059static int tipc_sk_publish(struct tipc_port *port, uint scope,
60 struct tipc_name_seq const *seq);
61static int tipc_sk_withdraw(struct tipc_port *port, uint scope,
62 struct tipc_name_seq const *seq);
Jon Paul Maloy808d90f2014-08-22 18:09:19 -040063static u32 tipc_sk_ref_acquire(struct tipc_sock *tsk);
64static void tipc_sk_ref_discard(u32 ref);
65static struct tipc_sock *tipc_sk_get(u32 ref);
66static struct tipc_sock *tipc_sk_get_next(u32 *ref);
67static void tipc_sk_put(struct tipc_sock *tsk);
Per Lidenb97bf3f2006-01-02 19:04:38 +010068
Florian Westphalbca65ea2008-02-07 18:18:01 -080069static const struct proto_ops packet_ops;
70static const struct proto_ops stream_ops;
71static const struct proto_ops msg_ops;
Per Lidenb97bf3f2006-01-02 19:04:38 +010072
73static struct proto tipc_proto;
Ying Xuec5fa7b32013-06-17 10:54:39 -040074static struct proto tipc_proto_kern;
Per Lidenb97bf3f2006-01-02 19:04:38 +010075
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +090076/*
Allan Stephens0c3141e2008-04-15 00:22:02 -070077 * Revised TIPC socket locking policy:
78 *
79 * Most socket operations take the standard socket lock when they start
80 * and hold it until they finish (or until they need to sleep). Acquiring
81 * this lock grants the owner exclusive access to the fields of the socket
82 * data structures, with the exception of the backlog queue. A few socket
83 * operations can be done without taking the socket lock because they only
84 * read socket information that never changes during the life of the socket.
85 *
86 * Socket operations may acquire the lock for the associated TIPC port if they
87 * need to perform an operation on the port. If any routine needs to acquire
88 * both the socket lock and the port lock it must take the socket lock first
89 * to avoid the risk of deadlock.
90 *
91 * The dispatcher handling incoming messages cannot grab the socket lock in
92 * the standard fashion, since invoked it runs at the BH level and cannot block.
93 * Instead, it checks to see if the socket lock is currently owned by someone,
94 * and either handles the message itself or adds it to the socket's backlog
95 * queue; in the latter case the queued message is processed once the process
96 * owning the socket lock releases it.
97 *
98 * NOTE: Releasing the socket lock while an operation is sleeping overcomes
99 * the problem of a blocked socket operation preventing any other operations
100 * from occurring. However, applications must be careful if they have
101 * multiple threads trying to send (or receive) on the same socket, as these
102 * operations might interfere with each other. For example, doing a connect
103 * and a receive at the same time might allow the receive to consume the
104 * ACK message meant for the connect. While additional work could be done
105 * to try and overcome this, it doesn't seem to be worthwhile at the present.
106 *
107 * NOTE: Releasing the socket lock while an operation is sleeping also ensures
108 * that another operation that must be performed in a non-blocking manner is
109 * not delayed for very long because the lock has already been taken.
110 *
111 * NOTE: This code assumes that certain fields of a port/socket pair are
112 * constant over its lifetime; such fields can be examined without taking
113 * the socket lock and/or port lock, and do not need to be re-read even
114 * after resuming processing after waiting. These fields include:
115 * - socket type
116 * - pointer to socket sk structure (aka tipc_sock structure)
117 * - pointer to port structure
118 * - port reference
Per Lidenb97bf3f2006-01-02 19:04:38 +0100119 */
Per Lidenb97bf3f2006-01-02 19:04:38 +0100120
Jon Paul Maloy2e84c602014-08-22 18:09:18 -0400121static u32 tsk_peer_node(struct tipc_port *p_ptr)
122{
123 return msg_destnode(&p_ptr->phdr);
124}
125
126static u32 tsk_peer_port(struct tipc_port *p_ptr)
127{
128 return msg_destport(&p_ptr->phdr);
129}
130
131static bool tsk_unreliable(struct tipc_port *port)
132{
133 return msg_src_droppable(&port->phdr) != 0;
134}
135
136static void tsk_set_unreliable(struct tipc_port *port, bool unreliable)
137{
138 msg_set_src_droppable(&port->phdr, unreliable ? 1 : 0);
139}
140
141static bool tsk_unreturnable(struct tipc_port *port)
142{
143 return msg_dest_droppable(&port->phdr) != 0;
144}
145
146static void tsk_set_unreturnable(struct tipc_port *port, bool unreturnable)
147{
148 msg_set_dest_droppable(&port->phdr, unreturnable ? 1 : 0);
149}
150
151static int tsk_importance(struct tipc_port *port)
152{
153 return msg_importance(&port->phdr);
154}
155
156static int tsk_set_importance(struct tipc_port *port, int imp)
157{
158 if (imp > TIPC_CRITICAL_IMPORTANCE)
159 return -EINVAL;
160 msg_set_importance(&port->phdr, (u32)imp);
161 return 0;
162}
Jon Paul Maloy8826cde2014-03-12 11:31:09 -0400163
Per Lidenb97bf3f2006-01-02 19:04:38 +0100164/**
Jon Paul Maloy2e84c602014-08-22 18:09:18 -0400165 * tsk_advance_rx_queue - discard first buffer in socket receive queue
Allan Stephens0c3141e2008-04-15 00:22:02 -0700166 *
167 * Caller must hold socket lock
Per Lidenb97bf3f2006-01-02 19:04:38 +0100168 */
Jon Paul Maloy2e84c602014-08-22 18:09:18 -0400169static void tsk_advance_rx_queue(struct sock *sk)
Per Lidenb97bf3f2006-01-02 19:04:38 +0100170{
Allan Stephens5f6d9122011-11-04 13:24:29 -0400171 kfree_skb(__skb_dequeue(&sk->sk_receive_queue));
Per Lidenb97bf3f2006-01-02 19:04:38 +0100172}
173
174/**
Jon Paul Maloy2e84c602014-08-22 18:09:18 -0400175 * tsk_rej_rx_queue - reject all buffers in socket receive queue
Allan Stephens0c3141e2008-04-15 00:22:02 -0700176 *
177 * Caller must hold socket lock
178 */
Jon Paul Maloy2e84c602014-08-22 18:09:18 -0400179static void tsk_rej_rx_queue(struct sock *sk)
Allan Stephens0c3141e2008-04-15 00:22:02 -0700180{
181 struct sk_buff *buf;
Jon Paul Maloy8db1bae2014-06-25 20:41:35 -0500182 u32 dnode;
Allan Stephens0c3141e2008-04-15 00:22:02 -0700183
Jon Paul Maloy8db1bae2014-06-25 20:41:35 -0500184 while ((buf = __skb_dequeue(&sk->sk_receive_queue))) {
185 if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT))
Jon Paul Maloy9fbfb8b2014-07-16 20:41:03 -0400186 tipc_link_xmit(buf, dnode, 0);
Jon Paul Maloy8db1bae2014-06-25 20:41:35 -0500187 }
Allan Stephens0c3141e2008-04-15 00:22:02 -0700188}
189
Jon Paul Maloy2e84c602014-08-22 18:09:18 -0400190/* tsk_peer_msg - verify if message was sent by connected port's peer
Jon Paul Maloy0fc87aa2014-08-22 18:09:17 -0400191 *
192 * Handles cases where the node's network address has changed from
193 * the default of <0.0.0> to its configured setting.
194 */
Jon Paul Maloy2e84c602014-08-22 18:09:18 -0400195static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
Jon Paul Maloy0fc87aa2014-08-22 18:09:17 -0400196{
Jon Paul Maloy2e84c602014-08-22 18:09:18 -0400197 u32 peer_port = tsk_peer_port(&tsk->port);
Jon Paul Maloy0fc87aa2014-08-22 18:09:17 -0400198 u32 orig_node;
199 u32 peer_node;
200
201 if (unlikely(!tsk->port.connected))
202 return false;
203
204 if (unlikely(msg_origport(msg) != peer_port))
205 return false;
206
207 orig_node = msg_orignode(msg);
Jon Paul Maloy2e84c602014-08-22 18:09:18 -0400208 peer_node = tsk_peer_node(&tsk->port);
Jon Paul Maloy0fc87aa2014-08-22 18:09:17 -0400209
210 if (likely(orig_node == peer_node))
211 return true;
212
213 if (!orig_node && (peer_node == tipc_own_addr))
214 return true;
215
216 if (!peer_node && (orig_node == tipc_own_addr))
217 return true;
218
219 return false;
220}
221
Allan Stephens0c3141e2008-04-15 00:22:02 -0700222/**
Ying Xuec5fa7b32013-06-17 10:54:39 -0400223 * tipc_sk_create - create a TIPC socket
Allan Stephens0c3141e2008-04-15 00:22:02 -0700224 * @net: network namespace (must be default network)
Per Lidenb97bf3f2006-01-02 19:04:38 +0100225 * @sock: pre-allocated socket structure
226 * @protocol: protocol indicator (must be 0)
Eric Paris3f378b62009-11-05 22:18:14 -0800227 * @kern: caused by kernel or by userspace?
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900228 *
Allan Stephens0c3141e2008-04-15 00:22:02 -0700229 * This routine creates additional data structures used by the TIPC socket,
230 * initializes them, and links them together.
Per Lidenb97bf3f2006-01-02 19:04:38 +0100231 *
232 * Returns 0 on success, errno otherwise
233 */
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400234static int tipc_sk_create(struct net *net, struct socket *sock,
235 int protocol, int kern)
Per Lidenb97bf3f2006-01-02 19:04:38 +0100236{
Allan Stephens0c3141e2008-04-15 00:22:02 -0700237 const struct proto_ops *ops;
238 socket_state state;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100239 struct sock *sk;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400240 struct tipc_sock *tsk;
241 struct tipc_port *port;
Jon Paul Maloy5b8fa7c2014-08-22 18:09:13 -0400242 struct tipc_msg *msg;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400243 u32 ref;
Allan Stephens0c3141e2008-04-15 00:22:02 -0700244
245 /* Validate arguments */
Per Lidenb97bf3f2006-01-02 19:04:38 +0100246 if (unlikely(protocol != 0))
247 return -EPROTONOSUPPORT;
248
Per Lidenb97bf3f2006-01-02 19:04:38 +0100249 switch (sock->type) {
250 case SOCK_STREAM:
Allan Stephens0c3141e2008-04-15 00:22:02 -0700251 ops = &stream_ops;
252 state = SS_UNCONNECTED;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100253 break;
254 case SOCK_SEQPACKET:
Allan Stephens0c3141e2008-04-15 00:22:02 -0700255 ops = &packet_ops;
256 state = SS_UNCONNECTED;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100257 break;
258 case SOCK_DGRAM:
Per Lidenb97bf3f2006-01-02 19:04:38 +0100259 case SOCK_RDM:
Allan Stephens0c3141e2008-04-15 00:22:02 -0700260 ops = &msg_ops;
261 state = SS_READY;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100262 break;
Allan Stephens49978652006-06-25 23:47:18 -0700263 default:
Allan Stephens49978652006-06-25 23:47:18 -0700264 return -EPROTOTYPE;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100265 }
266
Allan Stephens0c3141e2008-04-15 00:22:02 -0700267 /* Allocate socket's protocol area */
Ying Xuec5fa7b32013-06-17 10:54:39 -0400268 if (!kern)
269 sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto);
270 else
271 sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto_kern);
272
Allan Stephens0c3141e2008-04-15 00:22:02 -0700273 if (sk == NULL)
274 return -ENOMEM;
275
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400276 tsk = tipc_sk(sk);
277 port = &tsk->port;
Jon Paul Maloy808d90f2014-08-22 18:09:19 -0400278 ref = tipc_sk_ref_acquire(tsk);
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400279 if (!ref) {
Jon Paul Maloy5b8fa7c2014-08-22 18:09:13 -0400280 pr_warn("Socket create failed; reference table exhausted\n");
Per Lidenb97bf3f2006-01-02 19:04:38 +0100281 return -ENOMEM;
282 }
Jon Paul Maloy5b8fa7c2014-08-22 18:09:13 -0400283 port->max_pkt = MAX_PKT_DEFAULT;
284 port->ref = ref;
285 INIT_LIST_HEAD(&port->publications);
Jon Paul Maloy5b8fa7c2014-08-22 18:09:13 -0400286
Jon Paul Maloy5b8fa7c2014-08-22 18:09:13 -0400287 msg = &port->phdr;
288 tipc_msg_init(msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG,
289 NAMED_H_SIZE, 0);
290 msg_set_origport(msg, ref);
Per Lidenb97bf3f2006-01-02 19:04:38 +0100291
Allan Stephens0c3141e2008-04-15 00:22:02 -0700292 /* Finish initializing socket data structures */
Allan Stephens0c3141e2008-04-15 00:22:02 -0700293 sock->ops = ops;
294 sock->state = state;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100295 sock_init_data(sock, sk);
Jon Paul Maloy57289012014-08-22 18:09:09 -0400296 k_init_timer(&port->timer, (Handler)tipc_sk_timeout, ref);
Jon Paul Maloy4f4482d2014-05-14 05:39:09 -0400297 sk->sk_backlog_rcv = tipc_backlog_rcv;
Ying Xuecc79dd12013-06-17 10:54:37 -0400298 sk->sk_rcvbuf = sysctl_tipc_rmem[1];
Ying Xuef288bef2012-08-21 11:16:57 +0800299 sk->sk_data_ready = tipc_data_ready;
300 sk->sk_write_space = tipc_write_space;
Jon Paul Maloy4f4482d2014-05-14 05:39:09 -0400301 tsk->conn_timeout = CONN_TIMEOUT_DEFAULT;
Jon Paul Maloy60120522014-06-25 20:41:42 -0500302 tsk->sent_unacked = 0;
Jon Paul Maloy4f4482d2014-05-14 05:39:09 -0400303 atomic_set(&tsk->dupl_rcvcnt, 0);
Allan Stephens7ef43eb2008-05-12 15:42:28 -0700304
Allan Stephens0c3141e2008-04-15 00:22:02 -0700305 if (sock->state == SS_READY) {
Jon Paul Maloy2e84c602014-08-22 18:09:18 -0400306 tsk_set_unreturnable(port, true);
Allan Stephens0c3141e2008-04-15 00:22:02 -0700307 if (sock->type == SOCK_DGRAM)
Jon Paul Maloy2e84c602014-08-22 18:09:18 -0400308 tsk_set_unreliable(port, true);
Allan Stephens0c3141e2008-04-15 00:22:02 -0700309 }
Per Lidenb97bf3f2006-01-02 19:04:38 +0100310 return 0;
311}
312
313/**
Ying Xuec5fa7b32013-06-17 10:54:39 -0400314 * tipc_sock_create_local - create TIPC socket from inside TIPC module
315 * @type: socket type - SOCK_RDM or SOCK_SEQPACKET
316 *
317 * We cannot use sock_creat_kern here because it bumps module user count.
318 * Since socket owner and creator is the same module we must make sure
319 * that module count remains zero for module local sockets, otherwise
320 * we cannot do rmmod.
321 *
322 * Returns 0 on success, errno otherwise
323 */
324int tipc_sock_create_local(int type, struct socket **res)
325{
326 int rc;
Ying Xuec5fa7b32013-06-17 10:54:39 -0400327
328 rc = sock_create_lite(AF_TIPC, type, 0, res);
329 if (rc < 0) {
330 pr_err("Failed to create kernel socket\n");
331 return rc;
332 }
333 tipc_sk_create(&init_net, *res, 0, 1);
334
Ying Xuec5fa7b32013-06-17 10:54:39 -0400335 return 0;
336}
337
338/**
339 * tipc_sock_release_local - release socket created by tipc_sock_create_local
340 * @sock: the socket to be released.
341 *
342 * Module reference count is not incremented when such sockets are created,
343 * so we must keep it from being decremented when they are released.
344 */
345void tipc_sock_release_local(struct socket *sock)
346{
Ying Xue247f0f32014-02-18 16:06:46 +0800347 tipc_release(sock);
Ying Xuec5fa7b32013-06-17 10:54:39 -0400348 sock->ops = NULL;
349 sock_release(sock);
350}
351
352/**
353 * tipc_sock_accept_local - accept a connection on a socket created
354 * with tipc_sock_create_local. Use this function to avoid that
355 * module reference count is inadvertently incremented.
356 *
357 * @sock: the accepting socket
358 * @newsock: reference to the new socket to be created
359 * @flags: socket flags
360 */
361
362int tipc_sock_accept_local(struct socket *sock, struct socket **newsock,
Paul Gortmakerae8509c2013-06-17 10:54:47 -0400363 int flags)
Ying Xuec5fa7b32013-06-17 10:54:39 -0400364{
365 struct sock *sk = sock->sk;
366 int ret;
367
368 ret = sock_create_lite(sk->sk_family, sk->sk_type,
369 sk->sk_protocol, newsock);
370 if (ret < 0)
371 return ret;
372
Ying Xue247f0f32014-02-18 16:06:46 +0800373 ret = tipc_accept(sock, *newsock, flags);
Ying Xuec5fa7b32013-06-17 10:54:39 -0400374 if (ret < 0) {
375 sock_release(*newsock);
376 return ret;
377 }
378 (*newsock)->ops = sock->ops;
379 return ret;
380}
381
382/**
Ying Xue247f0f32014-02-18 16:06:46 +0800383 * tipc_release - destroy a TIPC socket
Per Lidenb97bf3f2006-01-02 19:04:38 +0100384 * @sock: socket to destroy
385 *
386 * This routine cleans up any messages that are still queued on the socket.
387 * For DGRAM and RDM socket types, all queued messages are rejected.
388 * For SEQPACKET and STREAM socket types, the first message is rejected
389 * and any others are discarded. (If the first message on a STREAM socket
390 * is partially-read, it is discarded and the next one is rejected instead.)
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900391 *
Per Lidenb97bf3f2006-01-02 19:04:38 +0100392 * NOTE: Rejected messages are not necessarily returned to the sender! They
393 * are returned or discarded according to the "destination droppable" setting
394 * specified for the message by the sender.
395 *
396 * Returns 0 on success, errno otherwise
397 */
Ying Xue247f0f32014-02-18 16:06:46 +0800398static int tipc_release(struct socket *sock)
Per Lidenb97bf3f2006-01-02 19:04:38 +0100399{
Per Lidenb97bf3f2006-01-02 19:04:38 +0100400 struct sock *sk = sock->sk;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400401 struct tipc_sock *tsk;
402 struct tipc_port *port;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100403 struct sk_buff *buf;
Jon Paul Maloy8db1bae2014-06-25 20:41:35 -0500404 u32 dnode;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100405
Allan Stephens0c3141e2008-04-15 00:22:02 -0700406 /*
407 * Exit if socket isn't fully initialized (occurs when a failed accept()
408 * releases a pre-allocated child socket that was never used)
409 */
Allan Stephens0c3141e2008-04-15 00:22:02 -0700410 if (sk == NULL)
411 return 0;
412
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400413 tsk = tipc_sk(sk);
414 port = &tsk->port;
Allan Stephens0c3141e2008-04-15 00:22:02 -0700415 lock_sock(sk);
416
417 /*
418 * Reject all unreceived messages, except on an active connection
419 * (which disconnects locally & sends a 'FIN+' to peer)
420 */
Jon Paul Maloy2e84c602014-08-22 18:09:18 -0400421 dnode = tsk_peer_node(port);
Per Lidenb97bf3f2006-01-02 19:04:38 +0100422 while (sock->state != SS_DISCONNECTING) {
Allan Stephens0c3141e2008-04-15 00:22:02 -0700423 buf = __skb_dequeue(&sk->sk_receive_queue);
424 if (buf == NULL)
Per Lidenb97bf3f2006-01-02 19:04:38 +0100425 break;
Ying Xue40682432013-10-18 07:23:16 +0200426 if (TIPC_SKB_CB(buf)->handle != NULL)
Allan Stephens5f6d9122011-11-04 13:24:29 -0400427 kfree_skb(buf);
Allan Stephens0c3141e2008-04-15 00:22:02 -0700428 else {
429 if ((sock->state == SS_CONNECTING) ||
430 (sock->state == SS_CONNECTED)) {
431 sock->state = SS_DISCONNECTING;
Jon Paul Maloydadebc02014-08-22 18:09:11 -0400432 port->connected = 0;
Jon Paul Maloy5b8fa7c2014-08-22 18:09:13 -0400433 tipc_node_remove_conn(dnode, port->ref);
Allan Stephens0c3141e2008-04-15 00:22:02 -0700434 }
Jon Paul Maloy8db1bae2014-06-25 20:41:35 -0500435 if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT))
Jon Paul Maloy9fbfb8b2014-07-16 20:41:03 -0400436 tipc_link_xmit(buf, dnode, 0);
Allan Stephens0c3141e2008-04-15 00:22:02 -0700437 }
Per Lidenb97bf3f2006-01-02 19:04:38 +0100438 }
439
Jon Paul Maloy0fc87aa2014-08-22 18:09:17 -0400440 tipc_sk_withdraw(port, 0, NULL);
Jon Paul Maloy808d90f2014-08-22 18:09:19 -0400441 tipc_sk_ref_discard(port->ref);
Jon Paul Maloy5b8fa7c2014-08-22 18:09:13 -0400442 k_cancel_timer(&port->timer);
443 if (port->connected) {
444 buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
445 SHORT_H_SIZE, 0, dnode, tipc_own_addr,
Jon Paul Maloy2e84c602014-08-22 18:09:18 -0400446 tsk_peer_port(port),
Jon Paul Maloy5b8fa7c2014-08-22 18:09:13 -0400447 port->ref, TIPC_ERR_NO_PORT);
448 if (buf)
449 tipc_link_xmit(buf, dnode, port->ref);
450 tipc_node_remove_conn(dnode, port->ref);
451 }
Jon Paul Maloy5b8fa7c2014-08-22 18:09:13 -0400452 k_term_timer(&port->timer);
Per Lidenb97bf3f2006-01-02 19:04:38 +0100453
Allan Stephens0c3141e2008-04-15 00:22:02 -0700454 /* Discard any remaining (connection-based) messages in receive queue */
Ying Xue57467e52013-01-20 23:30:08 +0100455 __skb_queue_purge(&sk->sk_receive_queue);
Per Lidenb97bf3f2006-01-02 19:04:38 +0100456
Allan Stephens0c3141e2008-04-15 00:22:02 -0700457 /* Reject any messages that accumulated in backlog queue */
Allan Stephens0c3141e2008-04-15 00:22:02 -0700458 sock->state = SS_DISCONNECTING;
459 release_sock(sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +0100460 sock_put(sk);
Allan Stephens0c3141e2008-04-15 00:22:02 -0700461 sock->sk = NULL;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100462
Geert Uytterhoeven065d7e32014-04-06 15:56:14 +0200463 return 0;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100464}
465
466/**
Ying Xue247f0f32014-02-18 16:06:46 +0800467 * tipc_bind - associate or disassocate TIPC name(s) with a socket
Per Lidenb97bf3f2006-01-02 19:04:38 +0100468 * @sock: socket structure
469 * @uaddr: socket address describing name(s) and desired operation
470 * @uaddr_len: size of socket address data structure
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900471 *
Per Lidenb97bf3f2006-01-02 19:04:38 +0100472 * Name and name sequence binding is indicated using a positive scope value;
473 * a negative scope value unbinds the specified name. Specifying no name
474 * (i.e. a socket address length of 0) unbinds all names from the socket.
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900475 *
Per Lidenb97bf3f2006-01-02 19:04:38 +0100476 * Returns 0 on success, errno otherwise
Allan Stephens0c3141e2008-04-15 00:22:02 -0700477 *
478 * NOTE: This routine doesn't need to take the socket lock since it doesn't
479 * access any non-constant socket information.
Per Lidenb97bf3f2006-01-02 19:04:38 +0100480 */
Ying Xue247f0f32014-02-18 16:06:46 +0800481static int tipc_bind(struct socket *sock, struct sockaddr *uaddr,
482 int uaddr_len)
Per Lidenb97bf3f2006-01-02 19:04:38 +0100483{
Ying Xue84602762013-12-27 10:18:28 +0800484 struct sock *sk = sock->sk;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100485 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400486 struct tipc_sock *tsk = tipc_sk(sk);
Ying Xue84602762013-12-27 10:18:28 +0800487 int res = -EINVAL;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100488
Ying Xue84602762013-12-27 10:18:28 +0800489 lock_sock(sk);
490 if (unlikely(!uaddr_len)) {
Jon Paul Maloy0fc87aa2014-08-22 18:09:17 -0400491 res = tipc_sk_withdraw(&tsk->port, 0, NULL);
Ying Xue84602762013-12-27 10:18:28 +0800492 goto exit;
493 }
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900494
Ying Xue84602762013-12-27 10:18:28 +0800495 if (uaddr_len < sizeof(struct sockaddr_tipc)) {
496 res = -EINVAL;
497 goto exit;
498 }
499 if (addr->family != AF_TIPC) {
500 res = -EAFNOSUPPORT;
501 goto exit;
502 }
Per Lidenb97bf3f2006-01-02 19:04:38 +0100503
Per Lidenb97bf3f2006-01-02 19:04:38 +0100504 if (addr->addrtype == TIPC_ADDR_NAME)
505 addr->addr.nameseq.upper = addr->addr.nameseq.lower;
Ying Xue84602762013-12-27 10:18:28 +0800506 else if (addr->addrtype != TIPC_ADDR_NAMESEQ) {
507 res = -EAFNOSUPPORT;
508 goto exit;
509 }
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900510
Ying Xue13a2e892013-06-17 10:54:40 -0400511 if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) &&
Ying Xue7d0ab172013-06-17 10:54:41 -0400512 (addr->addr.nameseq.type != TIPC_TOP_SRV) &&
Ying Xue84602762013-12-27 10:18:28 +0800513 (addr->addr.nameseq.type != TIPC_CFG_SRV)) {
514 res = -EACCES;
515 goto exit;
516 }
Allan Stephensc422f1b2011-11-02 15:49:40 -0400517
Ying Xue84602762013-12-27 10:18:28 +0800518 res = (addr->scope > 0) ?
Jon Paul Maloy0fc87aa2014-08-22 18:09:17 -0400519 tipc_sk_publish(&tsk->port, addr->scope, &addr->addr.nameseq) :
520 tipc_sk_withdraw(&tsk->port, -addr->scope, &addr->addr.nameseq);
Ying Xue84602762013-12-27 10:18:28 +0800521exit:
522 release_sock(sk);
523 return res;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100524}
525
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900526/**
Ying Xue247f0f32014-02-18 16:06:46 +0800527 * tipc_getname - get port ID of socket or peer socket
Per Lidenb97bf3f2006-01-02 19:04:38 +0100528 * @sock: socket structure
529 * @uaddr: area for returned socket address
530 * @uaddr_len: area for returned length of socket address
Allan Stephens2da59912008-07-14 22:43:32 -0700531 * @peer: 0 = own ID, 1 = current peer ID, 2 = current/former peer ID
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900532 *
Per Lidenb97bf3f2006-01-02 19:04:38 +0100533 * Returns 0 on success, errno otherwise
Allan Stephens0c3141e2008-04-15 00:22:02 -0700534 *
Allan Stephens2da59912008-07-14 22:43:32 -0700535 * NOTE: This routine doesn't need to take the socket lock since it only
536 * accesses socket information that is unchanging (or which changes in
Allan Stephens0e659672010-12-31 18:59:32 +0000537 * a completely predictable manner).
Per Lidenb97bf3f2006-01-02 19:04:38 +0100538 */
Ying Xue247f0f32014-02-18 16:06:46 +0800539static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
540 int *uaddr_len, int peer)
Per Lidenb97bf3f2006-01-02 19:04:38 +0100541{
Per Lidenb97bf3f2006-01-02 19:04:38 +0100542 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400543 struct tipc_sock *tsk = tipc_sk(sock->sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +0100544
Kulikov Vasiliy88f8a5e2010-10-31 07:10:32 +0000545 memset(addr, 0, sizeof(*addr));
Allan Stephens0c3141e2008-04-15 00:22:02 -0700546 if (peer) {
Allan Stephens2da59912008-07-14 22:43:32 -0700547 if ((sock->state != SS_CONNECTED) &&
548 ((peer != 2) || (sock->state != SS_DISCONNECTING)))
549 return -ENOTCONN;
Jon Paul Maloy2e84c602014-08-22 18:09:18 -0400550 addr->addr.id.ref = tsk_peer_port(&tsk->port);
551 addr->addr.id.node = tsk_peer_node(&tsk->port);
Allan Stephens0c3141e2008-04-15 00:22:02 -0700552 } else {
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400553 addr->addr.id.ref = tsk->port.ref;
Allan Stephensb924dcf2010-11-30 12:01:03 +0000554 addr->addr.id.node = tipc_own_addr;
Allan Stephens0c3141e2008-04-15 00:22:02 -0700555 }
Per Lidenb97bf3f2006-01-02 19:04:38 +0100556
557 *uaddr_len = sizeof(*addr);
558 addr->addrtype = TIPC_ADDR_ID;
559 addr->family = AF_TIPC;
560 addr->scope = 0;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100561 addr->addr.name.domain = 0;
562
Allan Stephens0c3141e2008-04-15 00:22:02 -0700563 return 0;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100564}
565
566/**
Ying Xue247f0f32014-02-18 16:06:46 +0800567 * tipc_poll - read and possibly block on pollmask
Per Lidenb97bf3f2006-01-02 19:04:38 +0100568 * @file: file structure associated with the socket
569 * @sock: socket for which to calculate the poll bits
570 * @wait: ???
571 *
Allan Stephens9b674e82008-03-26 16:48:21 -0700572 * Returns pollmask value
573 *
574 * COMMENTARY:
575 * It appears that the usual socket locking mechanisms are not useful here
576 * since the pollmask info is potentially out-of-date the moment this routine
577 * exits. TCP and other protocols seem to rely on higher level poll routines
578 * to handle any preventable race conditions, so TIPC will do the same ...
579 *
580 * TIPC sets the returned events as follows:
Allan Stephens9b674e82008-03-26 16:48:21 -0700581 *
Allan Stephensf662c072010-08-17 11:00:06 +0000582 * socket state flags set
583 * ------------ ---------
584 * unconnected no read flags
Erik Hugnec4fc2982012-10-16 16:47:06 +0200585 * POLLOUT if port is not congested
Allan Stephensf662c072010-08-17 11:00:06 +0000586 *
587 * connecting POLLIN/POLLRDNORM if ACK/NACK in rx queue
588 * no write flags
589 *
590 * connected POLLIN/POLLRDNORM if data in rx queue
591 * POLLOUT if port is not congested
592 *
593 * disconnecting POLLIN/POLLRDNORM/POLLHUP
594 * no write flags
595 *
596 * listening POLLIN if SYN in rx queue
597 * no write flags
598 *
599 * ready POLLIN/POLLRDNORM if data in rx queue
600 * [connectionless] POLLOUT (since port cannot be congested)
601 *
602 * IMPORTANT: The fact that a read or write operation is indicated does NOT
603 * imply that the operation will succeed, merely that it should be performed
604 * and will not block.
Per Lidenb97bf3f2006-01-02 19:04:38 +0100605 */
Ying Xue247f0f32014-02-18 16:06:46 +0800606static unsigned int tipc_poll(struct file *file, struct socket *sock,
607 poll_table *wait)
Per Lidenb97bf3f2006-01-02 19:04:38 +0100608{
Allan Stephens9b674e82008-03-26 16:48:21 -0700609 struct sock *sk = sock->sk;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400610 struct tipc_sock *tsk = tipc_sk(sk);
Allan Stephensf662c072010-08-17 11:00:06 +0000611 u32 mask = 0;
Allan Stephens9b674e82008-03-26 16:48:21 -0700612
Ying Xuef288bef2012-08-21 11:16:57 +0800613 sock_poll_wait(file, sk_sleep(sk), wait);
Allan Stephens9b674e82008-03-26 16:48:21 -0700614
Allan Stephensf662c072010-08-17 11:00:06 +0000615 switch ((int)sock->state) {
Erik Hugnec4fc2982012-10-16 16:47:06 +0200616 case SS_UNCONNECTED:
Jon Paul Maloy60120522014-06-25 20:41:42 -0500617 if (!tsk->link_cong)
Erik Hugnec4fc2982012-10-16 16:47:06 +0200618 mask |= POLLOUT;
619 break;
Allan Stephensf662c072010-08-17 11:00:06 +0000620 case SS_READY:
621 case SS_CONNECTED:
Jon Paul Maloy60120522014-06-25 20:41:42 -0500622 if (!tsk->link_cong && !tipc_sk_conn_cong(tsk))
Allan Stephensf662c072010-08-17 11:00:06 +0000623 mask |= POLLOUT;
624 /* fall thru' */
625 case SS_CONNECTING:
626 case SS_LISTENING:
627 if (!skb_queue_empty(&sk->sk_receive_queue))
628 mask |= (POLLIN | POLLRDNORM);
629 break;
630 case SS_DISCONNECTING:
631 mask = (POLLIN | POLLRDNORM | POLLHUP);
632 break;
633 }
Allan Stephens9b674e82008-03-26 16:48:21 -0700634
635 return mask;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100636}
637
Jon Paul Maloy0abd8ff2014-07-16 20:41:01 -0400638/**
639 * tipc_sendmcast - send multicast message
640 * @sock: socket structure
641 * @seq: destination address
642 * @iov: message data to send
643 * @dsz: total length of message data
644 * @timeo: timeout to wait for wakeup
645 *
646 * Called from function tipc_sendmsg(), which has done all sanity checks
647 * Returns the number of bytes sent on success, or errno
648 */
649static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
650 struct iovec *iov, size_t dsz, long timeo)
651{
652 struct sock *sk = sock->sk;
653 struct tipc_msg *mhdr = &tipc_sk(sk)->port.phdr;
654 struct sk_buff *buf;
655 uint mtu;
656 int rc;
657
658 msg_set_type(mhdr, TIPC_MCAST_MSG);
659 msg_set_lookup_scope(mhdr, TIPC_CLUSTER_SCOPE);
660 msg_set_destport(mhdr, 0);
661 msg_set_destnode(mhdr, 0);
662 msg_set_nametype(mhdr, seq->type);
663 msg_set_namelower(mhdr, seq->lower);
664 msg_set_nameupper(mhdr, seq->upper);
665 msg_set_hdr_sz(mhdr, MCAST_H_SIZE);
666
667new_mtu:
668 mtu = tipc_bclink_get_mtu();
Jon Paul Maloy9fbfb8b2014-07-16 20:41:03 -0400669 rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf);
Jon Paul Maloy0abd8ff2014-07-16 20:41:01 -0400670 if (unlikely(rc < 0))
671 return rc;
672
673 do {
674 rc = tipc_bclink_xmit(buf);
675 if (likely(rc >= 0)) {
676 rc = dsz;
677 break;
678 }
679 if (rc == -EMSGSIZE)
680 goto new_mtu;
681 if (rc != -ELINKCONG)
682 break;
Jon Paul Maloy50100a52014-08-22 18:09:07 -0400683 tipc_sk(sk)->link_cong = 1;
Jon Paul Maloy0abd8ff2014-07-16 20:41:01 -0400684 rc = tipc_wait_for_sndmsg(sock, &timeo);
685 if (rc)
686 kfree_skb_list(buf);
687 } while (!rc);
688 return rc;
689}
690
Jon Paul Maloy078bec82014-07-16 20:41:00 -0400691/* tipc_sk_mcast_rcv - Deliver multicast message to all destination sockets
692 */
693void tipc_sk_mcast_rcv(struct sk_buff *buf)
694{
695 struct tipc_msg *msg = buf_msg(buf);
696 struct tipc_port_list dports = {0, NULL, };
697 struct tipc_port_list *item;
698 struct sk_buff *b;
699 uint i, last, dst = 0;
700 u32 scope = TIPC_CLUSTER_SCOPE;
701
702 if (in_own_node(msg_orignode(msg)))
703 scope = TIPC_NODE_SCOPE;
704
705 /* Create destination port list: */
706 tipc_nametbl_mc_translate(msg_nametype(msg),
707 msg_namelower(msg),
708 msg_nameupper(msg),
709 scope,
710 &dports);
711 last = dports.count;
712 if (!last) {
713 kfree_skb(buf);
714 return;
715 }
716
717 for (item = &dports; item; item = item->next) {
718 for (i = 0; i < PLSIZE && ++dst <= last; i++) {
719 b = (dst != last) ? skb_clone(buf, GFP_ATOMIC) : buf;
720 if (!b) {
721 pr_warn("Failed do clone mcast rcv buffer\n");
722 continue;
723 }
724 msg_set_destport(msg, item->ports[i]);
725 tipc_sk_rcv(b);
726 }
727 }
728 tipc_port_list_free(&dports);
729}
730
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900731/**
Jon Paul Maloyac0074e2014-06-25 20:41:41 -0500732 * tipc_sk_proto_rcv - receive a connection mng protocol message
733 * @tsk: receiving socket
734 * @dnode: node to send response message to, if any
735 * @buf: buffer containing protocol message
736 * Returns 0 (TIPC_OK) if message was consumed, 1 (TIPC_FWD_MSG) if
737 * (CONN_PROBE_REPLY) message should be forwarded.
738 */
Wei Yongjun52f50ce2014-07-20 13:14:28 +0800739static int tipc_sk_proto_rcv(struct tipc_sock *tsk, u32 *dnode,
740 struct sk_buff *buf)
Jon Paul Maloyac0074e2014-06-25 20:41:41 -0500741{
742 struct tipc_msg *msg = buf_msg(buf);
743 struct tipc_port *port = &tsk->port;
Jon Paul Maloy60120522014-06-25 20:41:42 -0500744 int conn_cong;
Jon Paul Maloyac0074e2014-06-25 20:41:41 -0500745
746 /* Ignore if connection cannot be validated: */
Jon Paul Maloy2e84c602014-08-22 18:09:18 -0400747 if (!tsk_peer_msg(tsk, msg))
Jon Paul Maloyac0074e2014-06-25 20:41:41 -0500748 goto exit;
749
750 port->probing_state = TIPC_CONN_OK;
751
752 if (msg_type(msg) == CONN_ACK) {
Jon Paul Maloy60120522014-06-25 20:41:42 -0500753 conn_cong = tipc_sk_conn_cong(tsk);
754 tsk->sent_unacked -= msg_msgcnt(msg);
755 if (conn_cong)
Jon Paul Maloy50100a52014-08-22 18:09:07 -0400756 tsk->sk.sk_write_space(&tsk->sk);
Jon Paul Maloyac0074e2014-06-25 20:41:41 -0500757 } else if (msg_type(msg) == CONN_PROBE) {
758 if (!tipc_msg_reverse(buf, dnode, TIPC_OK))
759 return TIPC_OK;
760 msg_set_type(msg, CONN_PROBE_REPLY);
761 return TIPC_FWD_MSG;
762 }
763 /* Do nothing if msg_type() == CONN_PROBE_REPLY */
764exit:
765 kfree_skb(buf);
766 return TIPC_OK;
767}
768
769/**
Per Lidenb97bf3f2006-01-02 19:04:38 +0100770 * dest_name_check - verify user is permitted to send to specified port name
771 * @dest: destination address
772 * @m: descriptor for message to be sent
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900773 *
Per Lidenb97bf3f2006-01-02 19:04:38 +0100774 * Prevents restricted configuration commands from being issued by
775 * unauthorized users.
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900776 *
Per Lidenb97bf3f2006-01-02 19:04:38 +0100777 * Returns 0 if permission is granted, otherwise errno
778 */
Sam Ravnborg05790c62006-03-20 22:37:04 -0800779static int dest_name_check(struct sockaddr_tipc *dest, struct msghdr *m)
Per Lidenb97bf3f2006-01-02 19:04:38 +0100780{
781 struct tipc_cfg_msg_hdr hdr;
782
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500783 if (unlikely(dest->addrtype == TIPC_ADDR_ID))
784 return 0;
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900785 if (likely(dest->addr.name.name.type >= TIPC_RESERVED_TYPES))
786 return 0;
787 if (likely(dest->addr.name.name.type == TIPC_TOP_SRV))
788 return 0;
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900789 if (likely(dest->addr.name.name.type != TIPC_CFG_SRV))
790 return -EACCES;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100791
Allan Stephens3f8dd942011-01-18 13:09:29 -0500792 if (!m->msg_iovlen || (m->msg_iov[0].iov_len < sizeof(hdr)))
793 return -EMSGSIZE;
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900794 if (copy_from_user(&hdr, m->msg_iov[0].iov_base, sizeof(hdr)))
Per Lidenb97bf3f2006-01-02 19:04:38 +0100795 return -EFAULT;
Allan Stephens70cb2342006-06-25 23:41:47 -0700796 if ((ntohs(hdr.tcm_type) & 0xC000) && (!capable(CAP_NET_ADMIN)))
Per Lidenb97bf3f2006-01-02 19:04:38 +0100797 return -EACCES;
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900798
Per Lidenb97bf3f2006-01-02 19:04:38 +0100799 return 0;
800}
801
Ying Xue3f405042014-01-17 09:50:05 +0800802static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p)
803{
804 struct sock *sk = sock->sk;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400805 struct tipc_sock *tsk = tipc_sk(sk);
Ying Xue3f405042014-01-17 09:50:05 +0800806 DEFINE_WAIT(wait);
807 int done;
808
809 do {
810 int err = sock_error(sk);
811 if (err)
812 return err;
813 if (sock->state == SS_DISCONNECTING)
814 return -EPIPE;
815 if (!*timeo_p)
816 return -EAGAIN;
817 if (signal_pending(current))
818 return sock_intr_errno(*timeo_p);
819
820 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
Jon Paul Maloy60120522014-06-25 20:41:42 -0500821 done = sk_wait_event(sk, timeo_p, !tsk->link_cong);
Ying Xue3f405042014-01-17 09:50:05 +0800822 finish_wait(sk_sleep(sk), &wait);
823 } while (!done);
824 return 0;
825}
826
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500827/**
Ying Xue247f0f32014-02-18 16:06:46 +0800828 * tipc_sendmsg - send message in connectionless manner
Allan Stephens0c3141e2008-04-15 00:22:02 -0700829 * @iocb: if NULL, indicates that socket lock is already held
Per Lidenb97bf3f2006-01-02 19:04:38 +0100830 * @sock: socket structure
831 * @m: message to send
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500832 * @dsz: amount of user data to be sent
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900833 *
Per Lidenb97bf3f2006-01-02 19:04:38 +0100834 * Message must have an destination specified explicitly.
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900835 * Used for SOCK_RDM and SOCK_DGRAM messages,
Per Lidenb97bf3f2006-01-02 19:04:38 +0100836 * and for 'SYN' messages on SOCK_SEQPACKET and SOCK_STREAM connections.
837 * (Note: 'SYN+' is prohibited on SOCK_STREAM.)
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900838 *
Per Lidenb97bf3f2006-01-02 19:04:38 +0100839 * Returns the number of bytes sent on success, or errno otherwise
840 */
Ying Xue247f0f32014-02-18 16:06:46 +0800841static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500842 struct msghdr *m, size_t dsz)
Per Lidenb97bf3f2006-01-02 19:04:38 +0100843{
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500844 DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
Allan Stephens0c3141e2008-04-15 00:22:02 -0700845 struct sock *sk = sock->sk;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400846 struct tipc_sock *tsk = tipc_sk(sk);
Jon Paul Maloy5c311422014-03-12 11:31:13 -0400847 struct tipc_port *port = &tsk->port;
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500848 struct tipc_msg *mhdr = &port->phdr;
849 struct iovec *iov = m->msg_iov;
850 u32 dnode, dport;
851 struct sk_buff *buf;
852 struct tipc_name_seq *seq = &dest->addr.nameseq;
853 u32 mtu;
Ying Xue3f405042014-01-17 09:50:05 +0800854 long timeo;
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500855 int rc = -EINVAL;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100856
857 if (unlikely(!dest))
858 return -EDESTADDRREQ;
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500859
Allan Stephens51f9cc12006-06-25 23:49:06 -0700860 if (unlikely((m->msg_namelen < sizeof(*dest)) ||
861 (dest->family != AF_TIPC)))
Per Lidenb97bf3f2006-01-02 19:04:38 +0100862 return -EINVAL;
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500863
864 if (dsz > TIPC_MAX_USER_MSG_SIZE)
Allan Stephensc29c3f72010-04-20 17:58:24 -0400865 return -EMSGSIZE;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100866
Allan Stephens0c3141e2008-04-15 00:22:02 -0700867 if (iocb)
868 lock_sock(sk);
869
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500870 if (unlikely(sock->state != SS_READY)) {
Allan Stephens0c3141e2008-04-15 00:22:02 -0700871 if (sock->state == SS_LISTENING) {
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500872 rc = -EPIPE;
Allan Stephens0c3141e2008-04-15 00:22:02 -0700873 goto exit;
Allan Stephens33880072006-06-25 23:44:57 -0700874 }
Allan Stephens0c3141e2008-04-15 00:22:02 -0700875 if (sock->state != SS_UNCONNECTED) {
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500876 rc = -EISCONN;
Allan Stephens0c3141e2008-04-15 00:22:02 -0700877 goto exit;
878 }
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400879 if (tsk->port.published) {
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500880 rc = -EOPNOTSUPP;
Allan Stephens0c3141e2008-04-15 00:22:02 -0700881 goto exit;
882 }
883 if (dest->addrtype == TIPC_ADDR_NAME) {
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400884 tsk->port.conn_type = dest->addr.name.name.type;
885 tsk->port.conn_instance = dest->addr.name.name.instance;
Allan Stephens0c3141e2008-04-15 00:22:02 -0700886 }
Per Lidenb97bf3f2006-01-02 19:04:38 +0100887 }
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500888 rc = dest_name_check(dest, m);
889 if (rc)
890 goto exit;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100891
Ying Xue3f405042014-01-17 09:50:05 +0800892 timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500893
894 if (dest->addrtype == TIPC_ADDR_MCAST) {
895 rc = tipc_sendmcast(sock, seq, iov, dsz, timeo);
896 goto exit;
897 } else if (dest->addrtype == TIPC_ADDR_NAME) {
898 u32 type = dest->addr.name.name.type;
899 u32 inst = dest->addr.name.name.instance;
900 u32 domain = dest->addr.name.domain;
901
902 dnode = domain;
903 msg_set_type(mhdr, TIPC_NAMED_MSG);
904 msg_set_hdr_sz(mhdr, NAMED_H_SIZE);
905 msg_set_nametype(mhdr, type);
906 msg_set_nameinst(mhdr, inst);
907 msg_set_lookup_scope(mhdr, tipc_addr_scope(domain));
908 dport = tipc_nametbl_translate(type, inst, &dnode);
909 msg_set_destnode(mhdr, dnode);
910 msg_set_destport(mhdr, dport);
911 if (unlikely(!dport && !dnode)) {
912 rc = -EHOSTUNREACH;
913 goto exit;
914 }
915 } else if (dest->addrtype == TIPC_ADDR_ID) {
916 dnode = dest->addr.id.node;
917 msg_set_type(mhdr, TIPC_DIRECT_MSG);
918 msg_set_lookup_scope(mhdr, 0);
919 msg_set_destnode(mhdr, dnode);
920 msg_set_destport(mhdr, dest->addr.id.ref);
921 msg_set_hdr_sz(mhdr, BASIC_H_SIZE);
922 }
923
924new_mtu:
925 mtu = tipc_node_get_mtu(dnode, tsk->port.ref);
Jon Paul Maloy9fbfb8b2014-07-16 20:41:03 -0400926 rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf);
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500927 if (rc < 0)
928 goto exit;
929
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900930 do {
Jon Paul Maloy50100a52014-08-22 18:09:07 -0400931 TIPC_SKB_CB(buf)->wakeup_pending = tsk->link_cong;
Jon Paul Maloy9fbfb8b2014-07-16 20:41:03 -0400932 rc = tipc_link_xmit(buf, dnode, tsk->port.ref);
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500933 if (likely(rc >= 0)) {
934 if (sock->state != SS_READY)
Allan Stephens0c3141e2008-04-15 00:22:02 -0700935 sock->state = SS_CONNECTING;
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500936 rc = dsz;
Allan Stephens0c3141e2008-04-15 00:22:02 -0700937 break;
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900938 }
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500939 if (rc == -EMSGSIZE)
940 goto new_mtu;
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500941 if (rc != -ELINKCONG)
Allan Stephens0c3141e2008-04-15 00:22:02 -0700942 break;
Jon Paul Maloy50100a52014-08-22 18:09:07 -0400943 tsk->link_cong = 1;
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500944 rc = tipc_wait_for_sndmsg(sock, &timeo);
Erik Hugne70452dc2014-07-06 20:38:50 -0400945 if (rc)
946 kfree_skb_list(buf);
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500947 } while (!rc);
Allan Stephens0c3141e2008-04-15 00:22:02 -0700948exit:
949 if (iocb)
950 release_sock(sk);
Jon Paul Maloye2dafe82014-06-25 20:41:37 -0500951
952 return rc;
Per Lidenb97bf3f2006-01-02 19:04:38 +0100953}
954
Ying Xue391a6dd2014-01-17 09:50:06 +0800955static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p)
956{
957 struct sock *sk = sock->sk;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -0400958 struct tipc_sock *tsk = tipc_sk(sk);
Ying Xue391a6dd2014-01-17 09:50:06 +0800959 DEFINE_WAIT(wait);
960 int done;
961
962 do {
963 int err = sock_error(sk);
964 if (err)
965 return err;
966 if (sock->state == SS_DISCONNECTING)
967 return -EPIPE;
968 else if (sock->state != SS_CONNECTED)
969 return -ENOTCONN;
970 if (!*timeo_p)
971 return -EAGAIN;
972 if (signal_pending(current))
973 return sock_intr_errno(*timeo_p);
974
975 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
976 done = sk_wait_event(sk, timeo_p,
Jon Paul Maloy60120522014-06-25 20:41:42 -0500977 (!tsk->link_cong &&
978 !tipc_sk_conn_cong(tsk)) ||
979 !tsk->port.connected);
Ying Xue391a6dd2014-01-17 09:50:06 +0800980 finish_wait(sk_sleep(sk), &wait);
981 } while (!done);
982 return 0;
983}
984
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900985/**
Ying Xue247f0f32014-02-18 16:06:46 +0800986 * tipc_send_stream - send stream-oriented data
Per Lidenb97bf3f2006-01-02 19:04:38 +0100987 * @iocb: (unused)
988 * @sock: socket structure
989 * @m: data to send
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -0500990 * @dsz: total length of data to be transmitted
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900991 *
Per Lidenb97bf3f2006-01-02 19:04:38 +0100992 * Used for SOCK_STREAM data.
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +0900993 *
994 * Returns the number of bytes sent on success (or partial success),
Allan Stephens1303e8f2006-06-25 23:46:50 -0700995 * or errno if no data sent
Per Lidenb97bf3f2006-01-02 19:04:38 +0100996 */
Ying Xue247f0f32014-02-18 16:06:46 +0800997static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -0500998 struct msghdr *m, size_t dsz)
Per Lidenb97bf3f2006-01-02 19:04:38 +0100999{
Allan Stephens0c3141e2008-04-15 00:22:02 -07001000 struct sock *sk = sock->sk;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -04001001 struct tipc_sock *tsk = tipc_sk(sk);
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001002 struct tipc_port *port = &tsk->port;
1003 struct tipc_msg *mhdr = &port->phdr;
1004 struct sk_buff *buf;
1005 DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
1006 u32 ref = port->ref;
1007 int rc = -EINVAL;
1008 long timeo;
1009 u32 dnode;
1010 uint mtu, send, sent = 0;
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001011
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001012 /* Handle implied connection establishment */
1013 if (unlikely(dest)) {
1014 rc = tipc_sendmsg(iocb, sock, m, dsz);
1015 if (dsz && (dsz == rc))
Jon Paul Maloy60120522014-06-25 20:41:42 -05001016 tsk->sent_unacked = 1;
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001017 return rc;
1018 }
1019 if (dsz > (uint)INT_MAX)
1020 return -EMSGSIZE;
Allan Stephens0c3141e2008-04-15 00:22:02 -07001021
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001022 if (iocb)
1023 lock_sock(sk);
1024
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001025 if (unlikely(sock->state != SS_CONNECTED)) {
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001026 if (sock->state == SS_DISCONNECTING)
1027 rc = -EPIPE;
wangweidongb0555972013-12-27 10:09:39 +08001028 else
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001029 rc = -ENOTCONN;
wangweidong3b8401f2013-12-12 09:36:40 +08001030 goto exit;
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001031 }
Per Lidenb97bf3f2006-01-02 19:04:38 +01001032
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001033 timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04001034 dnode = tsk_peer_node(port);
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001035
1036next:
1037 mtu = port->max_pkt;
1038 send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE);
Jon Paul Maloy9fbfb8b2014-07-16 20:41:03 -04001039 rc = tipc_msg_build(mhdr, m->msg_iov, sent, send, mtu, &buf);
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001040 if (unlikely(rc < 0))
Allan Stephens0c3141e2008-04-15 00:22:02 -07001041 goto exit;
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001042 do {
Jon Paul Maloy60120522014-06-25 20:41:42 -05001043 if (likely(!tipc_sk_conn_cong(tsk))) {
Jon Paul Maloy9fbfb8b2014-07-16 20:41:03 -04001044 rc = tipc_link_xmit(buf, dnode, ref);
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001045 if (likely(!rc)) {
Jon Paul Maloy60120522014-06-25 20:41:42 -05001046 tsk->sent_unacked++;
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001047 sent += send;
1048 if (sent == dsz)
1049 break;
1050 goto next;
Allan Stephens1303e8f2006-06-25 23:46:50 -07001051 }
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001052 if (rc == -EMSGSIZE) {
1053 port->max_pkt = tipc_node_get_mtu(dnode, ref);
1054 goto next;
1055 }
1056 if (rc != -ELINKCONG)
1057 break;
Jon Paul Maloy50100a52014-08-22 18:09:07 -04001058 tsk->link_cong = 1;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001059 }
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001060 rc = tipc_wait_for_sndpkt(sock, &timeo);
Erik Hugne70452dc2014-07-06 20:38:50 -04001061 if (rc)
1062 kfree_skb_list(buf);
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001063 } while (!rc);
Allan Stephens0c3141e2008-04-15 00:22:02 -07001064exit:
Jon Paul Maloy4ccfe5e2014-06-25 20:41:38 -05001065 if (iocb)
1066 release_sock(sk);
1067 return sent ? sent : rc;
1068}
1069
1070/**
1071 * tipc_send_packet - send a connection-oriented message
1072 * @iocb: if NULL, indicates that socket lock is already held
1073 * @sock: socket structure
1074 * @m: message to send
1075 * @dsz: length of data to be transmitted
1076 *
1077 * Used for SOCK_SEQPACKET messages.
1078 *
1079 * Returns the number of bytes sent on success, or errno otherwise
1080 */
1081static int tipc_send_packet(struct kiocb *iocb, struct socket *sock,
1082 struct msghdr *m, size_t dsz)
1083{
1084 if (dsz > TIPC_MAX_USER_MSG_SIZE)
1085 return -EMSGSIZE;
1086
1087 return tipc_send_stream(iocb, sock, m, dsz);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001088}
1089
Jon Paul Maloydadebc02014-08-22 18:09:11 -04001090/* tipc_sk_finish_conn - complete the setup of a connection
Per Lidenb97bf3f2006-01-02 19:04:38 +01001091 */
Jon Paul Maloydadebc02014-08-22 18:09:11 -04001092static void tipc_sk_finish_conn(struct tipc_port *port, u32 peer_port,
1093 u32 peer_node)
Per Lidenb97bf3f2006-01-02 19:04:38 +01001094{
Jon Paul Maloydadebc02014-08-22 18:09:11 -04001095 struct tipc_msg *msg = &port->phdr;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001096
Jon Paul Maloydadebc02014-08-22 18:09:11 -04001097 msg_set_destnode(msg, peer_node);
1098 msg_set_destport(msg, peer_port);
1099 msg_set_type(msg, TIPC_CONN_MSG);
1100 msg_set_lookup_scope(msg, 0);
1101 msg_set_hdr_sz(msg, SHORT_H_SIZE);
Jon Paul Maloyf9fef182014-03-12 11:31:08 -04001102
Jon Paul Maloydadebc02014-08-22 18:09:11 -04001103 port->probing_interval = CONN_PROBING_INTERVAL;
1104 port->probing_state = TIPC_CONN_OK;
1105 port->connected = 1;
1106 k_start_timer(&port->timer, port->probing_interval);
1107 tipc_node_add_conn(peer_node, port->ref, peer_port);
1108 port->max_pkt = tipc_node_get_mtu(peer_node, port->ref);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001109}
1110
1111/**
1112 * set_orig_addr - capture sender's address for received message
1113 * @m: descriptor for message info
1114 * @msg: received message header
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001115 *
Per Lidenb97bf3f2006-01-02 19:04:38 +01001116 * Note: Address is not captured if not requested by receiver.
1117 */
Sam Ravnborg05790c62006-03-20 22:37:04 -08001118static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg)
Per Lidenb97bf3f2006-01-02 19:04:38 +01001119{
Steffen Hurrle342dfc32014-01-17 22:53:15 +01001120 DECLARE_SOCKADDR(struct sockaddr_tipc *, addr, m->msg_name);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001121
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001122 if (addr) {
Per Lidenb97bf3f2006-01-02 19:04:38 +01001123 addr->family = AF_TIPC;
1124 addr->addrtype = TIPC_ADDR_ID;
Mathias Krause60085c32013-04-07 01:52:00 +00001125 memset(&addr->addr, 0, sizeof(addr->addr));
Per Lidenb97bf3f2006-01-02 19:04:38 +01001126 addr->addr.id.ref = msg_origport(msg);
1127 addr->addr.id.node = msg_orignode(msg);
Allan Stephens0e659672010-12-31 18:59:32 +00001128 addr->addr.name.domain = 0; /* could leave uninitialized */
1129 addr->scope = 0; /* could leave uninitialized */
Per Lidenb97bf3f2006-01-02 19:04:38 +01001130 m->msg_namelen = sizeof(struct sockaddr_tipc);
1131 }
1132}
1133
1134/**
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001135 * anc_data_recv - optionally capture ancillary data for received message
Per Lidenb97bf3f2006-01-02 19:04:38 +01001136 * @m: descriptor for message info
1137 * @msg: received message header
1138 * @tport: TIPC port associated with message
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001139 *
Per Lidenb97bf3f2006-01-02 19:04:38 +01001140 * Note: Ancillary data is not captured if not requested by receiver.
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001141 *
Per Lidenb97bf3f2006-01-02 19:04:38 +01001142 * Returns 0 if successful, otherwise errno
1143 */
Sam Ravnborg05790c62006-03-20 22:37:04 -08001144static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
Paul Gortmakerae8509c2013-06-17 10:54:47 -04001145 struct tipc_port *tport)
Per Lidenb97bf3f2006-01-02 19:04:38 +01001146{
1147 u32 anc_data[3];
1148 u32 err;
1149 u32 dest_type;
Allan Stephens3546c752006-06-25 23:45:24 -07001150 int has_name;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001151 int res;
1152
1153 if (likely(m->msg_controllen == 0))
1154 return 0;
1155
1156 /* Optionally capture errored message object(s) */
Per Lidenb97bf3f2006-01-02 19:04:38 +01001157 err = msg ? msg_errcode(msg) : 0;
1158 if (unlikely(err)) {
1159 anc_data[0] = err;
1160 anc_data[1] = msg_data_sz(msg);
Allan Stephens2db99832010-12-31 18:59:33 +00001161 res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data);
1162 if (res)
Per Lidenb97bf3f2006-01-02 19:04:38 +01001163 return res;
Allan Stephens2db99832010-12-31 18:59:33 +00001164 if (anc_data[1]) {
1165 res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1],
1166 msg_data(msg));
1167 if (res)
1168 return res;
1169 }
Per Lidenb97bf3f2006-01-02 19:04:38 +01001170 }
1171
1172 /* Optionally capture message destination object */
Per Lidenb97bf3f2006-01-02 19:04:38 +01001173 dest_type = msg ? msg_type(msg) : TIPC_DIRECT_MSG;
1174 switch (dest_type) {
1175 case TIPC_NAMED_MSG:
Allan Stephens3546c752006-06-25 23:45:24 -07001176 has_name = 1;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001177 anc_data[0] = msg_nametype(msg);
1178 anc_data[1] = msg_namelower(msg);
1179 anc_data[2] = msg_namelower(msg);
1180 break;
1181 case TIPC_MCAST_MSG:
Allan Stephens3546c752006-06-25 23:45:24 -07001182 has_name = 1;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001183 anc_data[0] = msg_nametype(msg);
1184 anc_data[1] = msg_namelower(msg);
1185 anc_data[2] = msg_nameupper(msg);
1186 break;
1187 case TIPC_CONN_MSG:
Allan Stephens3546c752006-06-25 23:45:24 -07001188 has_name = (tport->conn_type != 0);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001189 anc_data[0] = tport->conn_type;
1190 anc_data[1] = tport->conn_instance;
1191 anc_data[2] = tport->conn_instance;
1192 break;
1193 default:
Allan Stephens3546c752006-06-25 23:45:24 -07001194 has_name = 0;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001195 }
Allan Stephens2db99832010-12-31 18:59:33 +00001196 if (has_name) {
1197 res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data);
1198 if (res)
1199 return res;
1200 }
Per Lidenb97bf3f2006-01-02 19:04:38 +01001201
1202 return 0;
1203}
1204
Jon Paul Maloy739f5e42014-08-22 18:09:12 -04001205static void tipc_sk_send_ack(struct tipc_port *port, uint ack)
1206{
1207 struct sk_buff *buf = NULL;
1208 struct tipc_msg *msg;
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04001209 u32 peer_port = tsk_peer_port(port);
1210 u32 dnode = tsk_peer_node(port);
Jon Paul Maloy739f5e42014-08-22 18:09:12 -04001211
1212 if (!port->connected)
1213 return;
1214 buf = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0, dnode,
1215 tipc_own_addr, peer_port, port->ref, TIPC_OK);
1216 if (!buf)
1217 return;
1218 msg = buf_msg(buf);
1219 msg_set_msgcnt(msg, ack);
1220 tipc_link_xmit(buf, dnode, msg_link_selector(msg));
1221}
1222
Arnaldo Carvalho de Melo85d3fc92014-05-23 15:55:12 -04001223static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
Ying Xue9bbb4ec2014-01-17 09:50:07 +08001224{
1225 struct sock *sk = sock->sk;
1226 DEFINE_WAIT(wait);
Arnaldo Carvalho de Melo85d3fc92014-05-23 15:55:12 -04001227 long timeo = *timeop;
Ying Xue9bbb4ec2014-01-17 09:50:07 +08001228 int err;
1229
1230 for (;;) {
1231 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
Ying Xuefe8e4642014-03-06 14:40:18 +01001232 if (timeo && skb_queue_empty(&sk->sk_receive_queue)) {
Ying Xue9bbb4ec2014-01-17 09:50:07 +08001233 if (sock->state == SS_DISCONNECTING) {
1234 err = -ENOTCONN;
1235 break;
1236 }
1237 release_sock(sk);
1238 timeo = schedule_timeout(timeo);
1239 lock_sock(sk);
1240 }
1241 err = 0;
1242 if (!skb_queue_empty(&sk->sk_receive_queue))
1243 break;
1244 err = sock_intr_errno(timeo);
1245 if (signal_pending(current))
1246 break;
1247 err = -EAGAIN;
1248 if (!timeo)
1249 break;
1250 }
1251 finish_wait(sk_sleep(sk), &wait);
Arnaldo Carvalho de Melo85d3fc92014-05-23 15:55:12 -04001252 *timeop = timeo;
Ying Xue9bbb4ec2014-01-17 09:50:07 +08001253 return err;
1254}
1255
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001256/**
Ying Xue247f0f32014-02-18 16:06:46 +08001257 * tipc_recvmsg - receive packet-oriented message
Per Lidenb97bf3f2006-01-02 19:04:38 +01001258 * @iocb: (unused)
1259 * @m: descriptor for message info
1260 * @buf_len: total size of user buffer area
1261 * @flags: receive flags
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001262 *
Per Lidenb97bf3f2006-01-02 19:04:38 +01001263 * Used for SOCK_DGRAM, SOCK_RDM, and SOCK_SEQPACKET messages.
1264 * If the complete message doesn't fit in user area, truncate it.
1265 *
1266 * Returns size of returned message data, errno otherwise
1267 */
Ying Xue247f0f32014-02-18 16:06:46 +08001268static int tipc_recvmsg(struct kiocb *iocb, struct socket *sock,
1269 struct msghdr *m, size_t buf_len, int flags)
Per Lidenb97bf3f2006-01-02 19:04:38 +01001270{
Allan Stephens0c3141e2008-04-15 00:22:02 -07001271 struct sock *sk = sock->sk;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -04001272 struct tipc_sock *tsk = tipc_sk(sk);
1273 struct tipc_port *port = &tsk->port;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001274 struct sk_buff *buf;
1275 struct tipc_msg *msg;
Ying Xue9bbb4ec2014-01-17 09:50:07 +08001276 long timeo;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001277 unsigned int sz;
1278 u32 err;
1279 int res;
1280
Allan Stephens0c3141e2008-04-15 00:22:02 -07001281 /* Catch invalid receive requests */
Per Lidenb97bf3f2006-01-02 19:04:38 +01001282 if (unlikely(!buf_len))
1283 return -EINVAL;
1284
Allan Stephens0c3141e2008-04-15 00:22:02 -07001285 lock_sock(sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001286
Allan Stephens0c3141e2008-04-15 00:22:02 -07001287 if (unlikely(sock->state == SS_UNCONNECTED)) {
Per Lidenb97bf3f2006-01-02 19:04:38 +01001288 res = -ENOTCONN;
1289 goto exit;
1290 }
1291
Ying Xue9bbb4ec2014-01-17 09:50:07 +08001292 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
Allan Stephens0c3141e2008-04-15 00:22:02 -07001293restart:
Per Lidenb97bf3f2006-01-02 19:04:38 +01001294
Allan Stephens0c3141e2008-04-15 00:22:02 -07001295 /* Look for a message in receive queue; wait if necessary */
Arnaldo Carvalho de Melo85d3fc92014-05-23 15:55:12 -04001296 res = tipc_wait_for_rcvmsg(sock, &timeo);
Ying Xue9bbb4ec2014-01-17 09:50:07 +08001297 if (res)
1298 goto exit;
Allan Stephens0c3141e2008-04-15 00:22:02 -07001299
1300 /* Look at first message in receive queue */
Allan Stephens0c3141e2008-04-15 00:22:02 -07001301 buf = skb_peek(&sk->sk_receive_queue);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001302 msg = buf_msg(buf);
1303 sz = msg_data_sz(msg);
1304 err = msg_errcode(msg);
1305
Per Lidenb97bf3f2006-01-02 19:04:38 +01001306 /* Discard an empty non-errored message & try again */
Per Lidenb97bf3f2006-01-02 19:04:38 +01001307 if ((!sz) && (!err)) {
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04001308 tsk_advance_rx_queue(sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001309 goto restart;
1310 }
1311
1312 /* Capture sender's address (optional) */
Per Lidenb97bf3f2006-01-02 19:04:38 +01001313 set_orig_addr(m, msg);
1314
1315 /* Capture ancillary data (optional) */
Jon Paul Maloy58ed9442014-03-12 11:31:12 -04001316 res = anc_data_recv(m, msg, port);
Allan Stephens0c3141e2008-04-15 00:22:02 -07001317 if (res)
Per Lidenb97bf3f2006-01-02 19:04:38 +01001318 goto exit;
1319
1320 /* Capture message data (if valid) & compute return value (always) */
Per Lidenb97bf3f2006-01-02 19:04:38 +01001321 if (!err) {
1322 if (unlikely(buf_len < sz)) {
1323 sz = buf_len;
1324 m->msg_flags |= MSG_TRUNC;
1325 }
Allan Stephens0232fd02011-02-21 09:45:40 -05001326 res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg),
1327 m->msg_iov, sz);
1328 if (res)
Per Lidenb97bf3f2006-01-02 19:04:38 +01001329 goto exit;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001330 res = sz;
1331 } else {
1332 if ((sock->state == SS_READY) ||
1333 ((err == TIPC_CONN_SHUTDOWN) || m->msg_control))
1334 res = 0;
1335 else
1336 res = -ECONNRESET;
1337 }
1338
1339 /* Consume received message (optional) */
Per Lidenb97bf3f2006-01-02 19:04:38 +01001340 if (likely(!(flags & MSG_PEEK))) {
Allan Stephens99009802008-04-15 00:06:12 -07001341 if ((sock->state != SS_READY) &&
Jon Paul Maloy60120522014-06-25 20:41:42 -05001342 (++tsk->rcv_unacked >= TIPC_CONNACK_INTV)) {
Jon Paul Maloy739f5e42014-08-22 18:09:12 -04001343 tipc_sk_send_ack(port, tsk->rcv_unacked);
Jon Paul Maloy60120522014-06-25 20:41:42 -05001344 tsk->rcv_unacked = 0;
1345 }
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04001346 tsk_advance_rx_queue(sk);
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001347 }
Per Lidenb97bf3f2006-01-02 19:04:38 +01001348exit:
Allan Stephens0c3141e2008-04-15 00:22:02 -07001349 release_sock(sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001350 return res;
1351}
1352
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001353/**
Ying Xue247f0f32014-02-18 16:06:46 +08001354 * tipc_recv_stream - receive stream-oriented data
Per Lidenb97bf3f2006-01-02 19:04:38 +01001355 * @iocb: (unused)
1356 * @m: descriptor for message info
1357 * @buf_len: total size of user buffer area
1358 * @flags: receive flags
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001359 *
1360 * Used for SOCK_STREAM messages only. If not enough data is available
Per Lidenb97bf3f2006-01-02 19:04:38 +01001361 * will optionally wait for more; never truncates data.
1362 *
1363 * Returns size of returned message data, errno otherwise
1364 */
Ying Xue247f0f32014-02-18 16:06:46 +08001365static int tipc_recv_stream(struct kiocb *iocb, struct socket *sock,
1366 struct msghdr *m, size_t buf_len, int flags)
Per Lidenb97bf3f2006-01-02 19:04:38 +01001367{
Allan Stephens0c3141e2008-04-15 00:22:02 -07001368 struct sock *sk = sock->sk;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -04001369 struct tipc_sock *tsk = tipc_sk(sk);
1370 struct tipc_port *port = &tsk->port;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001371 struct sk_buff *buf;
1372 struct tipc_msg *msg;
Ying Xue9bbb4ec2014-01-17 09:50:07 +08001373 long timeo;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001374 unsigned int sz;
Florian Westphal3720d402010-08-17 11:00:04 +00001375 int sz_to_copy, target, needed;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001376 int sz_copied = 0;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001377 u32 err;
Allan Stephens0c3141e2008-04-15 00:22:02 -07001378 int res = 0;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001379
1380 /* Catch invalid receive attempts */
Per Lidenb97bf3f2006-01-02 19:04:38 +01001381 if (unlikely(!buf_len))
1382 return -EINVAL;
1383
Allan Stephens0c3141e2008-04-15 00:22:02 -07001384 lock_sock(sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001385
Ying Xue9bbb4ec2014-01-17 09:50:07 +08001386 if (unlikely(sock->state == SS_UNCONNECTED)) {
Per Lidenb97bf3f2006-01-02 19:04:38 +01001387 res = -ENOTCONN;
1388 goto exit;
1389 }
1390
Florian Westphal3720d402010-08-17 11:00:04 +00001391 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
Ying Xue9bbb4ec2014-01-17 09:50:07 +08001392 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
Paul Gortmaker617d3c72012-04-30 15:29:02 -04001393
Allan Stephens0c3141e2008-04-15 00:22:02 -07001394restart:
Allan Stephens0c3141e2008-04-15 00:22:02 -07001395 /* Look for a message in receive queue; wait if necessary */
Arnaldo Carvalho de Melo85d3fc92014-05-23 15:55:12 -04001396 res = tipc_wait_for_rcvmsg(sock, &timeo);
Ying Xue9bbb4ec2014-01-17 09:50:07 +08001397 if (res)
1398 goto exit;
Allan Stephens0c3141e2008-04-15 00:22:02 -07001399
1400 /* Look at first message in receive queue */
Allan Stephens0c3141e2008-04-15 00:22:02 -07001401 buf = skb_peek(&sk->sk_receive_queue);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001402 msg = buf_msg(buf);
1403 sz = msg_data_sz(msg);
1404 err = msg_errcode(msg);
1405
1406 /* Discard an empty non-errored message & try again */
Per Lidenb97bf3f2006-01-02 19:04:38 +01001407 if ((!sz) && (!err)) {
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04001408 tsk_advance_rx_queue(sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001409 goto restart;
1410 }
1411
1412 /* Optionally capture sender's address & ancillary data of first msg */
Per Lidenb97bf3f2006-01-02 19:04:38 +01001413 if (sz_copied == 0) {
1414 set_orig_addr(m, msg);
Jon Paul Maloy58ed9442014-03-12 11:31:12 -04001415 res = anc_data_recv(m, msg, port);
Allan Stephens0c3141e2008-04-15 00:22:02 -07001416 if (res)
Per Lidenb97bf3f2006-01-02 19:04:38 +01001417 goto exit;
1418 }
1419
1420 /* Capture message data (if valid) & compute return value (always) */
Per Lidenb97bf3f2006-01-02 19:04:38 +01001421 if (!err) {
Allan Stephens0232fd02011-02-21 09:45:40 -05001422 u32 offset = (u32)(unsigned long)(TIPC_SKB_CB(buf)->handle);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001423
Allan Stephens0232fd02011-02-21 09:45:40 -05001424 sz -= offset;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001425 needed = (buf_len - sz_copied);
1426 sz_to_copy = (sz <= needed) ? sz : needed;
Allan Stephens0232fd02011-02-21 09:45:40 -05001427
1428 res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg) + offset,
1429 m->msg_iov, sz_to_copy);
1430 if (res)
Per Lidenb97bf3f2006-01-02 19:04:38 +01001431 goto exit;
Allan Stephens0232fd02011-02-21 09:45:40 -05001432
Per Lidenb97bf3f2006-01-02 19:04:38 +01001433 sz_copied += sz_to_copy;
1434
1435 if (sz_to_copy < sz) {
1436 if (!(flags & MSG_PEEK))
Allan Stephens0232fd02011-02-21 09:45:40 -05001437 TIPC_SKB_CB(buf)->handle =
1438 (void *)(unsigned long)(offset + sz_to_copy);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001439 goto exit;
1440 }
Per Lidenb97bf3f2006-01-02 19:04:38 +01001441 } else {
1442 if (sz_copied != 0)
1443 goto exit; /* can't add error msg to valid data */
1444
1445 if ((err == TIPC_CONN_SHUTDOWN) || m->msg_control)
1446 res = 0;
1447 else
1448 res = -ECONNRESET;
1449 }
1450
1451 /* Consume received message (optional) */
Per Lidenb97bf3f2006-01-02 19:04:38 +01001452 if (likely(!(flags & MSG_PEEK))) {
Jon Paul Maloy60120522014-06-25 20:41:42 -05001453 if (unlikely(++tsk->rcv_unacked >= TIPC_CONNACK_INTV)) {
Jon Paul Maloy739f5e42014-08-22 18:09:12 -04001454 tipc_sk_send_ack(port, tsk->rcv_unacked);
Jon Paul Maloy60120522014-06-25 20:41:42 -05001455 tsk->rcv_unacked = 0;
1456 }
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04001457 tsk_advance_rx_queue(sk);
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001458 }
Per Lidenb97bf3f2006-01-02 19:04:38 +01001459
1460 /* Loop around if more data is required */
Joe Perchesf64f9e72009-11-29 16:55:45 -08001461 if ((sz_copied < buf_len) && /* didn't get all requested data */
1462 (!skb_queue_empty(&sk->sk_receive_queue) ||
Florian Westphal3720d402010-08-17 11:00:04 +00001463 (sz_copied < target)) && /* and more is ready or required */
Joe Perchesf64f9e72009-11-29 16:55:45 -08001464 (!(flags & MSG_PEEK)) && /* and aren't just peeking at data */
1465 (!err)) /* and haven't reached a FIN */
Per Lidenb97bf3f2006-01-02 19:04:38 +01001466 goto restart;
1467
1468exit:
Allan Stephens0c3141e2008-04-15 00:22:02 -07001469 release_sock(sk);
Allan Stephensa3b0a5a2006-06-25 23:48:22 -07001470 return sz_copied ? sz_copied : res;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001471}
1472
1473/**
Ying Xuef288bef2012-08-21 11:16:57 +08001474 * tipc_write_space - wake up thread if port congestion is released
1475 * @sk: socket
1476 */
1477static void tipc_write_space(struct sock *sk)
1478{
1479 struct socket_wq *wq;
1480
1481 rcu_read_lock();
1482 wq = rcu_dereference(sk->sk_wq);
1483 if (wq_has_sleeper(wq))
1484 wake_up_interruptible_sync_poll(&wq->wait, POLLOUT |
1485 POLLWRNORM | POLLWRBAND);
1486 rcu_read_unlock();
1487}
1488
1489/**
1490 * tipc_data_ready - wake up threads to indicate messages have been received
1491 * @sk: socket
1492 * @len: the length of messages
1493 */
David S. Miller676d2362014-04-11 16:15:36 -04001494static void tipc_data_ready(struct sock *sk)
Ying Xuef288bef2012-08-21 11:16:57 +08001495{
1496 struct socket_wq *wq;
1497
1498 rcu_read_lock();
1499 wq = rcu_dereference(sk->sk_wq);
1500 if (wq_has_sleeper(wq))
1501 wake_up_interruptible_sync_poll(&wq->wait, POLLIN |
1502 POLLRDNORM | POLLRDBAND);
1503 rcu_read_unlock();
1504}
1505
1506/**
Ying Xue7e6c1312012-11-29 18:39:14 -05001507 * filter_connect - Handle all incoming messages for a connection-based socket
Jon Paul Maloy58ed9442014-03-12 11:31:12 -04001508 * @tsk: TIPC socket
Ying Xue7e6c1312012-11-29 18:39:14 -05001509 * @msg: message
1510 *
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001511 * Returns 0 (TIPC_OK) if everyting ok, -TIPC_ERR_NO_PORT otherwise
Ying Xue7e6c1312012-11-29 18:39:14 -05001512 */
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001513static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
Ying Xue7e6c1312012-11-29 18:39:14 -05001514{
Jon Paul Maloy58ed9442014-03-12 11:31:12 -04001515 struct sock *sk = &tsk->sk;
1516 struct tipc_port *port = &tsk->port;
Jon Paul Maloy8826cde2014-03-12 11:31:09 -04001517 struct socket *sock = sk->sk_socket;
Ying Xue7e6c1312012-11-29 18:39:14 -05001518 struct tipc_msg *msg = buf_msg(*buf);
Jon Paul Maloy8826cde2014-03-12 11:31:09 -04001519
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001520 int retval = -TIPC_ERR_NO_PORT;
Ying Xue7e6c1312012-11-29 18:39:14 -05001521
1522 if (msg_mcast(msg))
1523 return retval;
1524
1525 switch ((int)sock->state) {
1526 case SS_CONNECTED:
1527 /* Accept only connection-based messages sent by peer */
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04001528 if (tsk_peer_msg(tsk, msg)) {
Ying Xue7e6c1312012-11-29 18:39:14 -05001529 if (unlikely(msg_errcode(msg))) {
1530 sock->state = SS_DISCONNECTING;
Jon Paul Maloydadebc02014-08-22 18:09:11 -04001531 port->connected = 0;
1532 /* let timer expire on it's own */
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04001533 tipc_node_remove_conn(tsk_peer_node(port),
Jon Paul Maloydadebc02014-08-22 18:09:11 -04001534 port->ref);
Ying Xue7e6c1312012-11-29 18:39:14 -05001535 }
1536 retval = TIPC_OK;
1537 }
1538 break;
1539 case SS_CONNECTING:
1540 /* Accept only ACK or NACK message */
Jon Paul Maloydadebc02014-08-22 18:09:11 -04001541
1542 if (unlikely(!msg_connected(msg)))
1543 break;
1544
Ying Xue584d24b2012-11-29 18:51:19 -05001545 if (unlikely(msg_errcode(msg))) {
1546 sock->state = SS_DISCONNECTING;
Erik Hugne2c8d8512013-08-28 09:29:58 +02001547 sk->sk_err = ECONNREFUSED;
Ying Xue7e6c1312012-11-29 18:39:14 -05001548 retval = TIPC_OK;
Ying Xue584d24b2012-11-29 18:51:19 -05001549 break;
1550 }
1551
Jon Paul Maloydadebc02014-08-22 18:09:11 -04001552 if (unlikely(msg_importance(msg) > TIPC_CRITICAL_IMPORTANCE)) {
Ying Xue584d24b2012-11-29 18:51:19 -05001553 sock->state = SS_DISCONNECTING;
Jon Paul Maloydadebc02014-08-22 18:09:11 -04001554 sk->sk_err = EINVAL;
Ying Xue584d24b2012-11-29 18:51:19 -05001555 retval = TIPC_OK;
1556 break;
1557 }
1558
Jon Paul Maloydadebc02014-08-22 18:09:11 -04001559 tipc_sk_finish_conn(port, msg_origport(msg), msg_orignode(msg));
1560 msg_set_importance(&port->phdr, msg_importance(msg));
1561 sock->state = SS_CONNECTED;
1562
Ying Xue584d24b2012-11-29 18:51:19 -05001563 /* If an incoming message is an 'ACK-', it should be
1564 * discarded here because it doesn't contain useful
1565 * data. In addition, we should try to wake up
1566 * connect() routine if sleeping.
1567 */
1568 if (msg_data_sz(msg) == 0) {
1569 kfree_skb(*buf);
1570 *buf = NULL;
1571 if (waitqueue_active(sk_sleep(sk)))
1572 wake_up_interruptible(sk_sleep(sk));
1573 }
1574 retval = TIPC_OK;
Ying Xue7e6c1312012-11-29 18:39:14 -05001575 break;
1576 case SS_LISTENING:
1577 case SS_UNCONNECTED:
1578 /* Accept only SYN message */
1579 if (!msg_connected(msg) && !(msg_errcode(msg)))
1580 retval = TIPC_OK;
1581 break;
1582 case SS_DISCONNECTING:
1583 break;
1584 default:
1585 pr_err("Unknown socket state %u\n", sock->state);
1586 }
1587 return retval;
1588}
1589
1590/**
Ying Xueaba79f32013-01-20 23:30:09 +01001591 * rcvbuf_limit - get proper overload limit of socket receive queue
1592 * @sk: socket
1593 * @buf: message
1594 *
1595 * For all connection oriented messages, irrespective of importance,
1596 * the default overload value (i.e. 67MB) is set as limit.
1597 *
1598 * For all connectionless messages, by default new queue limits are
1599 * as belows:
1600 *
Ying Xuecc79dd12013-06-17 10:54:37 -04001601 * TIPC_LOW_IMPORTANCE (4 MB)
1602 * TIPC_MEDIUM_IMPORTANCE (8 MB)
1603 * TIPC_HIGH_IMPORTANCE (16 MB)
1604 * TIPC_CRITICAL_IMPORTANCE (32 MB)
Ying Xueaba79f32013-01-20 23:30:09 +01001605 *
1606 * Returns overload limit according to corresponding message importance
1607 */
1608static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *buf)
1609{
1610 struct tipc_msg *msg = buf_msg(buf);
Ying Xueaba79f32013-01-20 23:30:09 +01001611
1612 if (msg_connected(msg))
wangweidong0cee6bb2013-12-12 09:36:39 +08001613 return sysctl_tipc_rmem[2];
1614
1615 return sk->sk_rcvbuf >> TIPC_CRITICAL_IMPORTANCE <<
1616 msg_importance(msg);
Ying Xueaba79f32013-01-20 23:30:09 +01001617}
1618
1619/**
Allan Stephens0c3141e2008-04-15 00:22:02 -07001620 * filter_rcv - validate incoming message
1621 * @sk: socket
Per Lidenb97bf3f2006-01-02 19:04:38 +01001622 * @buf: message
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001623 *
Allan Stephens0c3141e2008-04-15 00:22:02 -07001624 * Enqueues message on receive queue if acceptable; optionally handles
1625 * disconnect indication for a connected socket.
1626 *
1627 * Called with socket lock already taken; port lock may also be taken.
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001628 *
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001629 * Returns 0 (TIPC_OK) if message was consumed, -TIPC error code if message
Jon Paul Maloyac0074e2014-06-25 20:41:41 -05001630 * to be rejected, 1 (TIPC_FWD_MSG) if (CONN_MANAGER) message to be forwarded
Per Lidenb97bf3f2006-01-02 19:04:38 +01001631 */
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001632static int filter_rcv(struct sock *sk, struct sk_buff *buf)
Per Lidenb97bf3f2006-01-02 19:04:38 +01001633{
Allan Stephens0c3141e2008-04-15 00:22:02 -07001634 struct socket *sock = sk->sk_socket;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -04001635 struct tipc_sock *tsk = tipc_sk(sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001636 struct tipc_msg *msg = buf_msg(buf);
Ying Xueaba79f32013-01-20 23:30:09 +01001637 unsigned int limit = rcvbuf_limit(sk, buf);
Jon Paul Maloyac0074e2014-06-25 20:41:41 -05001638 u32 onode;
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001639 int rc = TIPC_OK;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001640
Jon Paul Maloyac0074e2014-06-25 20:41:41 -05001641 if (unlikely(msg_user(msg) == CONN_MANAGER))
1642 return tipc_sk_proto_rcv(tsk, &onode, buf);
Jon Paul Maloyec8a2e52014-06-25 20:41:40 -05001643
Jon Paul Maloy50100a52014-08-22 18:09:07 -04001644 if (unlikely(msg_user(msg) == SOCK_WAKEUP)) {
1645 kfree_skb(buf);
1646 tsk->link_cong = 0;
1647 sk->sk_write_space(sk);
1648 return TIPC_OK;
1649 }
1650
Per Lidenb97bf3f2006-01-02 19:04:38 +01001651 /* Reject message if it is wrong sort of message for socket */
Allan Stephensaad58542012-04-26 18:13:08 -04001652 if (msg_type(msg) > TIPC_DIRECT_MSG)
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001653 return -TIPC_ERR_NO_PORT;
Allan Stephens0c3141e2008-04-15 00:22:02 -07001654
Per Lidenb97bf3f2006-01-02 19:04:38 +01001655 if (sock->state == SS_READY) {
Allan Stephensb29f1422010-12-31 18:59:25 +00001656 if (msg_connected(msg))
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001657 return -TIPC_ERR_NO_PORT;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001658 } else {
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001659 rc = filter_connect(tsk, &buf);
1660 if (rc != TIPC_OK || buf == NULL)
1661 return rc;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001662 }
1663
1664 /* Reject message if there isn't room to queue it */
Ying Xueaba79f32013-01-20 23:30:09 +01001665 if (sk_rmem_alloc_get(sk) + buf->truesize >= limit)
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001666 return -TIPC_ERR_OVERLOAD;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001667
Ying Xueaba79f32013-01-20 23:30:09 +01001668 /* Enqueue message */
Ying Xue40682432013-10-18 07:23:16 +02001669 TIPC_SKB_CB(buf)->handle = NULL;
Allan Stephens0c3141e2008-04-15 00:22:02 -07001670 __skb_queue_tail(&sk->sk_receive_queue, buf);
Ying Xueaba79f32013-01-20 23:30:09 +01001671 skb_set_owner_r(buf, sk);
Allan Stephens0c3141e2008-04-15 00:22:02 -07001672
David S. Miller676d2362014-04-11 16:15:36 -04001673 sk->sk_data_ready(sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001674 return TIPC_OK;
1675}
1676
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001677/**
Jon Paul Maloy4f4482d2014-05-14 05:39:09 -04001678 * tipc_backlog_rcv - handle incoming message from backlog queue
Allan Stephens0c3141e2008-04-15 00:22:02 -07001679 * @sk: socket
1680 * @buf: message
1681 *
1682 * Caller must hold socket lock, but not port lock.
1683 *
1684 * Returns 0
1685 */
Jon Paul Maloy4f4482d2014-05-14 05:39:09 -04001686static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf)
Allan Stephens0c3141e2008-04-15 00:22:02 -07001687{
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001688 int rc;
Jon Paul Maloy8db1bae2014-06-25 20:41:35 -05001689 u32 onode;
Jon Paul Maloy4f4482d2014-05-14 05:39:09 -04001690 struct tipc_sock *tsk = tipc_sk(sk);
Jon Paul Maloy02c00c22014-06-09 11:08:18 -05001691 uint truesize = buf->truesize;
Allan Stephens0c3141e2008-04-15 00:22:02 -07001692
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001693 rc = filter_rcv(sk, buf);
Jon Paul Maloy4f4482d2014-05-14 05:39:09 -04001694
Jon Paul Maloyac0074e2014-06-25 20:41:41 -05001695 if (likely(!rc)) {
1696 if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT)
1697 atomic_add(truesize, &tsk->dupl_rcvcnt);
1698 return 0;
1699 }
1700
1701 if ((rc < 0) && !tipc_msg_reverse(buf, &onode, -rc))
1702 return 0;
1703
Jon Paul Maloy9fbfb8b2014-07-16 20:41:03 -04001704 tipc_link_xmit(buf, onode, 0);
Jon Paul Maloy4f4482d2014-05-14 05:39:09 -04001705
Allan Stephens0c3141e2008-04-15 00:22:02 -07001706 return 0;
1707}
1708
1709/**
Jon Paul Maloy24be34b2014-03-12 11:31:10 -04001710 * tipc_sk_rcv - handle incoming message
Jon Paul Maloy9816f062014-05-14 05:39:15 -04001711 * @buf: buffer containing arriving message
1712 * Consumes buffer
1713 * Returns 0 if success, or errno: -EHOSTUNREACH
Allan Stephens0c3141e2008-04-15 00:22:02 -07001714 */
Jon Paul Maloy9816f062014-05-14 05:39:15 -04001715int tipc_sk_rcv(struct sk_buff *buf)
Allan Stephens0c3141e2008-04-15 00:22:02 -07001716{
Jon Paul Maloy9816f062014-05-14 05:39:15 -04001717 struct tipc_sock *tsk;
1718 struct tipc_port *port;
1719 struct sock *sk;
1720 u32 dport = msg_destport(buf_msg(buf));
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001721 int rc = TIPC_OK;
Jon Paul Maloy4f4482d2014-05-14 05:39:09 -04001722 uint limit;
Jon Paul Maloy8db1bae2014-06-25 20:41:35 -05001723 u32 dnode;
Jon Paul Maloy9816f062014-05-14 05:39:15 -04001724
Jon Paul Maloy5a379072014-06-25 20:41:36 -05001725 /* Validate destination and message */
Jon Paul Maloy6c9808c2014-08-22 18:09:16 -04001726 tsk = tipc_sk_get(dport);
Jon Paul Maloy9b50fd02014-08-22 18:09:15 -04001727 if (unlikely(!tsk)) {
Jon Paul Maloy5a379072014-06-25 20:41:36 -05001728 rc = tipc_msg_eval(buf, &dnode);
Jon Paul Maloy9816f062014-05-14 05:39:15 -04001729 goto exit;
1730 }
Jon Paul Maloy9b50fd02014-08-22 18:09:15 -04001731 port = &tsk->port;
Jon Paul Maloy9816f062014-05-14 05:39:15 -04001732 sk = &tsk->sk;
1733
1734 /* Queue message */
Allan Stephens0c3141e2008-04-15 00:22:02 -07001735 bh_lock_sock(sk);
Jon Paul Maloy9816f062014-05-14 05:39:15 -04001736
Allan Stephens0c3141e2008-04-15 00:22:02 -07001737 if (!sock_owned_by_user(sk)) {
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001738 rc = filter_rcv(sk, buf);
Allan Stephens0c3141e2008-04-15 00:22:02 -07001739 } else {
Jon Paul Maloy4f4482d2014-05-14 05:39:09 -04001740 if (sk->sk_backlog.len == 0)
1741 atomic_set(&tsk->dupl_rcvcnt, 0);
1742 limit = rcvbuf_limit(sk, buf) + atomic_read(&tsk->dupl_rcvcnt);
1743 if (sk_add_backlog(sk, buf, limit))
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001744 rc = -TIPC_ERR_OVERLOAD;
Allan Stephens0c3141e2008-04-15 00:22:02 -07001745 }
Jon Paul Maloy9816f062014-05-14 05:39:15 -04001746 bh_unlock_sock(sk);
Jon Paul Maloy6c9808c2014-08-22 18:09:16 -04001747 tipc_sk_put(tsk);
Jon Paul Maloye4de5fa2014-06-25 20:41:31 -05001748 if (likely(!rc))
Jon Paul Maloy9816f062014-05-14 05:39:15 -04001749 return 0;
1750exit:
Jon Paul Maloy5a379072014-06-25 20:41:36 -05001751 if ((rc < 0) && !tipc_msg_reverse(buf, &dnode, -rc))
Jon Paul Maloy8db1bae2014-06-25 20:41:35 -05001752 return -EHOSTUNREACH;
Jon Paul Maloy5a379072014-06-25 20:41:36 -05001753
Jon Paul Maloy9fbfb8b2014-07-16 20:41:03 -04001754 tipc_link_xmit(buf, dnode, 0);
Jon Paul Maloy5a379072014-06-25 20:41:36 -05001755 return (rc < 0) ? -EHOSTUNREACH : 0;
Allan Stephens0c3141e2008-04-15 00:22:02 -07001756}
1757
Ying Xue78eb3a52014-01-17 09:50:03 +08001758static int tipc_wait_for_connect(struct socket *sock, long *timeo_p)
1759{
1760 struct sock *sk = sock->sk;
1761 DEFINE_WAIT(wait);
1762 int done;
1763
1764 do {
1765 int err = sock_error(sk);
1766 if (err)
1767 return err;
1768 if (!*timeo_p)
1769 return -ETIMEDOUT;
1770 if (signal_pending(current))
1771 return sock_intr_errno(*timeo_p);
1772
1773 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1774 done = sk_wait_event(sk, timeo_p, sock->state != SS_CONNECTING);
1775 finish_wait(sk_sleep(sk), &wait);
1776 } while (!done);
1777 return 0;
1778}
1779
Per Lidenb97bf3f2006-01-02 19:04:38 +01001780/**
Ying Xue247f0f32014-02-18 16:06:46 +08001781 * tipc_connect - establish a connection to another TIPC port
Per Lidenb97bf3f2006-01-02 19:04:38 +01001782 * @sock: socket structure
1783 * @dest: socket address for destination port
1784 * @destlen: size of socket address data structure
Allan Stephens0c3141e2008-04-15 00:22:02 -07001785 * @flags: file-related flags associated with socket
Per Lidenb97bf3f2006-01-02 19:04:38 +01001786 *
1787 * Returns 0 on success, errno otherwise
1788 */
Ying Xue247f0f32014-02-18 16:06:46 +08001789static int tipc_connect(struct socket *sock, struct sockaddr *dest,
1790 int destlen, int flags)
Per Lidenb97bf3f2006-01-02 19:04:38 +01001791{
Allan Stephens0c3141e2008-04-15 00:22:02 -07001792 struct sock *sk = sock->sk;
Allan Stephensb89741a2008-04-15 00:20:37 -07001793 struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest;
1794 struct msghdr m = {NULL,};
Ying Xue78eb3a52014-01-17 09:50:03 +08001795 long timeout = (flags & O_NONBLOCK) ? 0 : tipc_sk(sk)->conn_timeout;
1796 socket_state previous;
Allan Stephensb89741a2008-04-15 00:20:37 -07001797 int res;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001798
Allan Stephens0c3141e2008-04-15 00:22:02 -07001799 lock_sock(sk);
1800
Allan Stephensb89741a2008-04-15 00:20:37 -07001801 /* For now, TIPC does not allow use of connect() with DGRAM/RDM types */
Allan Stephens0c3141e2008-04-15 00:22:02 -07001802 if (sock->state == SS_READY) {
1803 res = -EOPNOTSUPP;
1804 goto exit;
1805 }
Per Lidenb97bf3f2006-01-02 19:04:38 +01001806
Allan Stephensb89741a2008-04-15 00:20:37 -07001807 /*
1808 * Reject connection attempt using multicast address
1809 *
1810 * Note: send_msg() validates the rest of the address fields,
1811 * so there's no need to do it here
1812 */
Allan Stephens0c3141e2008-04-15 00:22:02 -07001813 if (dst->addrtype == TIPC_ADDR_MCAST) {
1814 res = -EINVAL;
1815 goto exit;
1816 }
1817
Ying Xue78eb3a52014-01-17 09:50:03 +08001818 previous = sock->state;
Ying Xue584d24b2012-11-29 18:51:19 -05001819 switch (sock->state) {
1820 case SS_UNCONNECTED:
1821 /* Send a 'SYN-' to destination */
1822 m.msg_name = dest;
1823 m.msg_namelen = destlen;
1824
1825 /* If connect is in non-blocking case, set MSG_DONTWAIT to
1826 * indicate send_msg() is never blocked.
1827 */
1828 if (!timeout)
1829 m.msg_flags = MSG_DONTWAIT;
1830
Ying Xue247f0f32014-02-18 16:06:46 +08001831 res = tipc_sendmsg(NULL, sock, &m, 0);
Ying Xue584d24b2012-11-29 18:51:19 -05001832 if ((res < 0) && (res != -EWOULDBLOCK))
1833 goto exit;
1834
1835 /* Just entered SS_CONNECTING state; the only
1836 * difference is that return value in non-blocking
1837 * case is EINPROGRESS, rather than EALREADY.
1838 */
1839 res = -EINPROGRESS;
Ying Xue584d24b2012-11-29 18:51:19 -05001840 case SS_CONNECTING:
Ying Xue78eb3a52014-01-17 09:50:03 +08001841 if (previous == SS_CONNECTING)
1842 res = -EALREADY;
1843 if (!timeout)
1844 goto exit;
1845 timeout = msecs_to_jiffies(timeout);
1846 /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */
1847 res = tipc_wait_for_connect(sock, &timeout);
Ying Xue584d24b2012-11-29 18:51:19 -05001848 break;
1849 case SS_CONNECTED:
1850 res = -EISCONN;
1851 break;
1852 default:
1853 res = -EINVAL;
Ying Xue78eb3a52014-01-17 09:50:03 +08001854 break;
Allan Stephensb89741a2008-04-15 00:20:37 -07001855 }
Allan Stephens0c3141e2008-04-15 00:22:02 -07001856exit:
1857 release_sock(sk);
Allan Stephensb89741a2008-04-15 00:20:37 -07001858 return res;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001859}
1860
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001861/**
Ying Xue247f0f32014-02-18 16:06:46 +08001862 * tipc_listen - allow socket to listen for incoming connections
Per Lidenb97bf3f2006-01-02 19:04:38 +01001863 * @sock: socket structure
1864 * @len: (unused)
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001865 *
Per Lidenb97bf3f2006-01-02 19:04:38 +01001866 * Returns 0 on success, errno otherwise
1867 */
Ying Xue247f0f32014-02-18 16:06:46 +08001868static int tipc_listen(struct socket *sock, int len)
Per Lidenb97bf3f2006-01-02 19:04:38 +01001869{
Allan Stephens0c3141e2008-04-15 00:22:02 -07001870 struct sock *sk = sock->sk;
1871 int res;
1872
1873 lock_sock(sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001874
Ying Xue245f3d32011-07-06 06:01:13 -04001875 if (sock->state != SS_UNCONNECTED)
Allan Stephens0c3141e2008-04-15 00:22:02 -07001876 res = -EINVAL;
1877 else {
1878 sock->state = SS_LISTENING;
1879 res = 0;
1880 }
1881
1882 release_sock(sk);
1883 return res;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001884}
1885
Ying Xue6398e232014-01-17 09:50:04 +08001886static int tipc_wait_for_accept(struct socket *sock, long timeo)
1887{
1888 struct sock *sk = sock->sk;
1889 DEFINE_WAIT(wait);
1890 int err;
1891
1892 /* True wake-one mechanism for incoming connections: only
1893 * one process gets woken up, not the 'whole herd'.
1894 * Since we do not 'race & poll' for established sockets
1895 * anymore, the common case will execute the loop only once.
1896 */
1897 for (;;) {
1898 prepare_to_wait_exclusive(sk_sleep(sk), &wait,
1899 TASK_INTERRUPTIBLE);
Ying Xuefe8e4642014-03-06 14:40:18 +01001900 if (timeo && skb_queue_empty(&sk->sk_receive_queue)) {
Ying Xue6398e232014-01-17 09:50:04 +08001901 release_sock(sk);
1902 timeo = schedule_timeout(timeo);
1903 lock_sock(sk);
1904 }
1905 err = 0;
1906 if (!skb_queue_empty(&sk->sk_receive_queue))
1907 break;
1908 err = -EINVAL;
1909 if (sock->state != SS_LISTENING)
1910 break;
1911 err = sock_intr_errno(timeo);
1912 if (signal_pending(current))
1913 break;
1914 err = -EAGAIN;
1915 if (!timeo)
1916 break;
1917 }
1918 finish_wait(sk_sleep(sk), &wait);
1919 return err;
1920}
1921
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001922/**
Ying Xue247f0f32014-02-18 16:06:46 +08001923 * tipc_accept - wait for connection request
Per Lidenb97bf3f2006-01-02 19:04:38 +01001924 * @sock: listening socket
1925 * @newsock: new socket that is to be connected
1926 * @flags: file-related flags associated with socket
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001927 *
Per Lidenb97bf3f2006-01-02 19:04:38 +01001928 * Returns 0 on success, errno otherwise
1929 */
Ying Xue247f0f32014-02-18 16:06:46 +08001930static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
Per Lidenb97bf3f2006-01-02 19:04:38 +01001931{
Paul Gortmaker0fef8f22012-12-04 11:01:55 -05001932 struct sock *new_sk, *sk = sock->sk;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001933 struct sk_buff *buf;
Jon Paul Maloy8826cde2014-03-12 11:31:09 -04001934 struct tipc_port *new_port;
Paul Gortmaker0fef8f22012-12-04 11:01:55 -05001935 struct tipc_msg *msg;
Ying Xue6398e232014-01-17 09:50:04 +08001936 long timeo;
Allan Stephens0c3141e2008-04-15 00:22:02 -07001937 int res;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001938
Allan Stephens0c3141e2008-04-15 00:22:02 -07001939 lock_sock(sk);
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09001940
Allan Stephens0c3141e2008-04-15 00:22:02 -07001941 if (sock->state != SS_LISTENING) {
1942 res = -EINVAL;
1943 goto exit;
1944 }
Ying Xue6398e232014-01-17 09:50:04 +08001945 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
1946 res = tipc_wait_for_accept(sock, timeo);
1947 if (res)
1948 goto exit;
Allan Stephens0c3141e2008-04-15 00:22:02 -07001949
1950 buf = skb_peek(&sk->sk_receive_queue);
1951
Ying Xuec5fa7b32013-06-17 10:54:39 -04001952 res = tipc_sk_create(sock_net(sock->sk), new_sock, 0, 1);
Paul Gortmaker0fef8f22012-12-04 11:01:55 -05001953 if (res)
1954 goto exit;
Allan Stephens0c3141e2008-04-15 00:22:02 -07001955
Paul Gortmaker0fef8f22012-12-04 11:01:55 -05001956 new_sk = new_sock->sk;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -04001957 new_port = &tipc_sk(new_sk)->port;
Paul Gortmaker0fef8f22012-12-04 11:01:55 -05001958 msg = buf_msg(buf);
Allan Stephens0c3141e2008-04-15 00:22:02 -07001959
Paul Gortmaker0fef8f22012-12-04 11:01:55 -05001960 /* we lock on new_sk; but lockdep sees the lock on sk */
1961 lock_sock_nested(new_sk, SINGLE_DEPTH_NESTING);
Allan Stephens0c3141e2008-04-15 00:22:02 -07001962
Paul Gortmaker0fef8f22012-12-04 11:01:55 -05001963 /*
1964 * Reject any stray messages received by new socket
1965 * before the socket lock was taken (very, very unlikely)
1966 */
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04001967 tsk_rej_rx_queue(new_sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001968
Paul Gortmaker0fef8f22012-12-04 11:01:55 -05001969 /* Connect new socket to it's peer */
Jon Paul Maloydadebc02014-08-22 18:09:11 -04001970 tipc_sk_finish_conn(new_port, msg_origport(msg), msg_orignode(msg));
Paul Gortmaker0fef8f22012-12-04 11:01:55 -05001971 new_sock->state = SS_CONNECTED;
Per Lidenb97bf3f2006-01-02 19:04:38 +01001972
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04001973 tsk_set_importance(new_port, msg_importance(msg));
Paul Gortmaker0fef8f22012-12-04 11:01:55 -05001974 if (msg_named(msg)) {
Jon Paul Maloy8826cde2014-03-12 11:31:09 -04001975 new_port->conn_type = msg_nametype(msg);
1976 new_port->conn_instance = msg_nameinst(msg);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001977 }
Paul Gortmaker0fef8f22012-12-04 11:01:55 -05001978
1979 /*
1980 * Respond to 'SYN-' by discarding it & returning 'ACK'-.
1981 * Respond to 'SYN+' by queuing it on new socket.
1982 */
1983 if (!msg_data_sz(msg)) {
1984 struct msghdr m = {NULL,};
1985
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04001986 tsk_advance_rx_queue(sk);
Ying Xue247f0f32014-02-18 16:06:46 +08001987 tipc_send_packet(NULL, new_sock, &m, 0);
Paul Gortmaker0fef8f22012-12-04 11:01:55 -05001988 } else {
1989 __skb_dequeue(&sk->sk_receive_queue);
1990 __skb_queue_head(&new_sk->sk_receive_queue, buf);
Ying Xueaba79f32013-01-20 23:30:09 +01001991 skb_set_owner_r(buf, new_sk);
Paul Gortmaker0fef8f22012-12-04 11:01:55 -05001992 }
1993 release_sock(new_sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001994exit:
Allan Stephens0c3141e2008-04-15 00:22:02 -07001995 release_sock(sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +01001996 return res;
1997}
1998
1999/**
Ying Xue247f0f32014-02-18 16:06:46 +08002000 * tipc_shutdown - shutdown socket connection
Per Lidenb97bf3f2006-01-02 19:04:38 +01002001 * @sock: socket structure
Allan Stephense247a8f2008-03-06 15:05:38 -08002002 * @how: direction to close (must be SHUT_RDWR)
Per Lidenb97bf3f2006-01-02 19:04:38 +01002003 *
2004 * Terminates connection (if necessary), then purges socket's receive queue.
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09002005 *
Per Lidenb97bf3f2006-01-02 19:04:38 +01002006 * Returns 0 on success, errno otherwise
2007 */
Ying Xue247f0f32014-02-18 16:06:46 +08002008static int tipc_shutdown(struct socket *sock, int how)
Per Lidenb97bf3f2006-01-02 19:04:38 +01002009{
Allan Stephens0c3141e2008-04-15 00:22:02 -07002010 struct sock *sk = sock->sk;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -04002011 struct tipc_sock *tsk = tipc_sk(sk);
2012 struct tipc_port *port = &tsk->port;
Per Lidenb97bf3f2006-01-02 19:04:38 +01002013 struct sk_buff *buf;
Jon Paul Maloy80e44c22014-08-22 18:09:10 -04002014 u32 dnode;
Per Lidenb97bf3f2006-01-02 19:04:38 +01002015 int res;
2016
Allan Stephense247a8f2008-03-06 15:05:38 -08002017 if (how != SHUT_RDWR)
2018 return -EINVAL;
Per Lidenb97bf3f2006-01-02 19:04:38 +01002019
Allan Stephens0c3141e2008-04-15 00:22:02 -07002020 lock_sock(sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +01002021
2022 switch (sock->state) {
Allan Stephens0c3141e2008-04-15 00:22:02 -07002023 case SS_CONNECTING:
Per Lidenb97bf3f2006-01-02 19:04:38 +01002024 case SS_CONNECTED:
2025
Per Lidenb97bf3f2006-01-02 19:04:38 +01002026restart:
Paul Gortmaker617d3c72012-04-30 15:29:02 -04002027 /* Disconnect and send a 'FIN+' or 'FIN-' message to peer */
Allan Stephens0c3141e2008-04-15 00:22:02 -07002028 buf = __skb_dequeue(&sk->sk_receive_queue);
2029 if (buf) {
Ying Xue40682432013-10-18 07:23:16 +02002030 if (TIPC_SKB_CB(buf)->handle != NULL) {
Allan Stephens5f6d9122011-11-04 13:24:29 -04002031 kfree_skb(buf);
Per Lidenb97bf3f2006-01-02 19:04:38 +01002032 goto restart;
2033 }
Jon Paul Maloy80e44c22014-08-22 18:09:10 -04002034 if (tipc_msg_reverse(buf, &dnode, TIPC_CONN_SHUTDOWN))
2035 tipc_link_xmit(buf, dnode, port->ref);
Jon Paul Maloydadebc02014-08-22 18:09:11 -04002036 tipc_node_remove_conn(dnode, port->ref);
Allan Stephens0c3141e2008-04-15 00:22:02 -07002037 } else {
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04002038 dnode = tsk_peer_node(port);
Jon Paul Maloy80e44c22014-08-22 18:09:10 -04002039 buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
2040 TIPC_CONN_MSG, SHORT_H_SIZE,
2041 0, dnode, tipc_own_addr,
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04002042 tsk_peer_port(port),
Jon Paul Maloy80e44c22014-08-22 18:09:10 -04002043 port->ref, TIPC_CONN_SHUTDOWN);
2044 tipc_link_xmit(buf, dnode, port->ref);
Per Lidenb97bf3f2006-01-02 19:04:38 +01002045 }
Jon Paul Maloydadebc02014-08-22 18:09:11 -04002046 port->connected = 0;
Allan Stephens0c3141e2008-04-15 00:22:02 -07002047 sock->state = SS_DISCONNECTING;
Jon Paul Maloydadebc02014-08-22 18:09:11 -04002048 tipc_node_remove_conn(dnode, port->ref);
Per Lidenb97bf3f2006-01-02 19:04:38 +01002049 /* fall through */
2050
2051 case SS_DISCONNECTING:
2052
Ying Xue75031152012-10-29 09:38:15 -04002053 /* Discard any unreceived messages */
Ying Xue57467e52013-01-20 23:30:08 +01002054 __skb_queue_purge(&sk->sk_receive_queue);
Ying Xue75031152012-10-29 09:38:15 -04002055
2056 /* Wake up anyone sleeping in poll */
2057 sk->sk_state_change(sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +01002058 res = 0;
2059 break;
2060
2061 default:
2062 res = -ENOTCONN;
2063 }
2064
Allan Stephens0c3141e2008-04-15 00:22:02 -07002065 release_sock(sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +01002066 return res;
2067}
2068
Jon Paul Maloy57289012014-08-22 18:09:09 -04002069static void tipc_sk_timeout(unsigned long ref)
2070{
Jon Paul Maloy6c9808c2014-08-22 18:09:16 -04002071 struct tipc_sock *tsk;
Jon Paul Maloy9b50fd02014-08-22 18:09:15 -04002072 struct tipc_port *port;
Jon Paul Maloy57289012014-08-22 18:09:09 -04002073 struct sock *sk;
2074 struct sk_buff *buf = NULL;
Jon Paul Maloy57289012014-08-22 18:09:09 -04002075 u32 peer_port, peer_node;
2076
Jon Paul Maloy6c9808c2014-08-22 18:09:16 -04002077 tsk = tipc_sk_get(ref);
Jon Paul Maloy9b50fd02014-08-22 18:09:15 -04002078 if (!tsk)
Jon Paul Maloy6c9808c2014-08-22 18:09:16 -04002079 goto exit;
Jon Paul Maloy57289012014-08-22 18:09:09 -04002080 sk = &tsk->sk;
Jon Paul Maloy6c9808c2014-08-22 18:09:16 -04002081 port = &tsk->port;
2082
Jon Paul Maloy57289012014-08-22 18:09:09 -04002083 bh_lock_sock(sk);
Jon Paul Maloy6c9808c2014-08-22 18:09:16 -04002084 if (!port->connected) {
2085 bh_unlock_sock(sk);
2086 goto exit;
2087 }
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04002088 peer_port = tsk_peer_port(port);
2089 peer_node = tsk_peer_node(port);
Jon Paul Maloy57289012014-08-22 18:09:09 -04002090
2091 if (port->probing_state == TIPC_CONN_PROBING) {
2092 /* Previous probe not answered -> self abort */
2093 buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
2094 SHORT_H_SIZE, 0, tipc_own_addr,
2095 peer_node, ref, peer_port,
2096 TIPC_ERR_NO_PORT);
2097 } else {
2098 buf = tipc_msg_create(CONN_MANAGER, CONN_PROBE, INT_H_SIZE,
2099 0, peer_node, tipc_own_addr,
2100 peer_port, ref, TIPC_OK);
2101 port->probing_state = TIPC_CONN_PROBING;
2102 k_start_timer(&port->timer, port->probing_interval);
2103 }
2104 bh_unlock_sock(sk);
Jon Paul Maloy6c9808c2014-08-22 18:09:16 -04002105 if (buf)
2106 tipc_link_xmit(buf, peer_node, ref);
2107exit:
2108 tipc_sk_put(tsk);
Jon Paul Maloy57289012014-08-22 18:09:09 -04002109}
2110
Jon Paul Maloy0fc87aa2014-08-22 18:09:17 -04002111static int tipc_sk_publish(struct tipc_port *port, uint scope,
2112 struct tipc_name_seq const *seq)
2113{
2114 struct publication *publ;
2115 u32 key;
2116
2117 if (port->connected)
2118 return -EINVAL;
2119 key = port->ref + port->pub_count + 1;
2120 if (key == port->ref)
2121 return -EADDRINUSE;
2122
2123 publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
2124 scope, port->ref, key);
2125 if (unlikely(!publ))
2126 return -EINVAL;
2127
2128 list_add(&publ->pport_list, &port->publications);
2129 port->pub_count++;
2130 port->published = 1;
2131 return 0;
2132}
2133
2134static int tipc_sk_withdraw(struct tipc_port *port, uint scope,
2135 struct tipc_name_seq const *seq)
2136{
2137 struct publication *publ;
2138 struct publication *safe;
2139 int rc = -EINVAL;
2140
2141 list_for_each_entry_safe(publ, safe, &port->publications, pport_list) {
2142 if (seq) {
2143 if (publ->scope != scope)
2144 continue;
2145 if (publ->type != seq->type)
2146 continue;
2147 if (publ->lower != seq->lower)
2148 continue;
2149 if (publ->upper != seq->upper)
2150 break;
2151 tipc_nametbl_withdraw(publ->type, publ->lower,
2152 publ->ref, publ->key);
2153 rc = 0;
2154 break;
2155 }
2156 tipc_nametbl_withdraw(publ->type, publ->lower,
2157 publ->ref, publ->key);
2158 rc = 0;
2159 }
2160 if (list_empty(&port->publications))
2161 port->published = 0;
2162 return rc;
2163}
2164
Jon Paul Maloy5a9ee0be2014-08-22 18:09:14 -04002165static int tipc_sk_show(struct tipc_port *port, char *buf,
2166 int len, int full_id)
2167{
2168 struct publication *publ;
2169 int ret;
2170
2171 if (full_id)
2172 ret = tipc_snprintf(buf, len, "<%u.%u.%u:%u>:",
2173 tipc_zone(tipc_own_addr),
2174 tipc_cluster(tipc_own_addr),
2175 tipc_node(tipc_own_addr), port->ref);
2176 else
2177 ret = tipc_snprintf(buf, len, "%-10u:", port->ref);
2178
2179 if (port->connected) {
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04002180 u32 dport = tsk_peer_port(port);
2181 u32 destnode = tsk_peer_node(port);
Jon Paul Maloy5a9ee0be2014-08-22 18:09:14 -04002182
2183 ret += tipc_snprintf(buf + ret, len - ret,
2184 " connected to <%u.%u.%u:%u>",
2185 tipc_zone(destnode),
2186 tipc_cluster(destnode),
2187 tipc_node(destnode), dport);
2188 if (port->conn_type != 0)
2189 ret += tipc_snprintf(buf + ret, len - ret,
2190 " via {%u,%u}", port->conn_type,
2191 port->conn_instance);
2192 } else if (port->published) {
2193 ret += tipc_snprintf(buf + ret, len - ret, " bound to");
2194 list_for_each_entry(publ, &port->publications, pport_list) {
2195 if (publ->lower == publ->upper)
2196 ret += tipc_snprintf(buf + ret, len - ret,
2197 " {%u,%u}", publ->type,
2198 publ->lower);
2199 else
2200 ret += tipc_snprintf(buf + ret, len - ret,
2201 " {%u,%u,%u}", publ->type,
2202 publ->lower, publ->upper);
2203 }
2204 }
2205 ret += tipc_snprintf(buf + ret, len - ret, "\n");
2206 return ret;
2207}
2208
2209struct sk_buff *tipc_sk_socks_show(void)
2210{
2211 struct sk_buff *buf;
2212 struct tlv_desc *rep_tlv;
2213 char *pb;
2214 int pb_len;
2215 struct tipc_sock *tsk;
2216 int str_len = 0;
2217 u32 ref = 0;
2218
2219 buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN));
2220 if (!buf)
2221 return NULL;
2222 rep_tlv = (struct tlv_desc *)buf->data;
2223 pb = TLV_DATA(rep_tlv);
2224 pb_len = ULTRA_STRING_MAX_LEN;
2225
Jon Paul Maloy6c9808c2014-08-22 18:09:16 -04002226 tsk = tipc_sk_get_next(&ref);
2227 for (; tsk; tsk = tipc_sk_get_next(&ref)) {
2228 lock_sock(&tsk->sk);
Jon Paul Maloy5a9ee0be2014-08-22 18:09:14 -04002229 str_len += tipc_sk_show(&tsk->port, pb + str_len,
2230 pb_len - str_len, 0);
Jon Paul Maloy6c9808c2014-08-22 18:09:16 -04002231 release_sock(&tsk->sk);
2232 tipc_sk_put(tsk);
Jon Paul Maloy5a9ee0be2014-08-22 18:09:14 -04002233 }
2234 str_len += 1; /* for "\0" */
2235 skb_put(buf, TLV_SPACE(str_len));
2236 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
2237
2238 return buf;
2239}
2240
2241/* tipc_sk_reinit: set non-zero address in all existing sockets
2242 * when we go from standalone to network mode.
2243 */
2244void tipc_sk_reinit(void)
2245{
2246 struct tipc_msg *msg;
2247 u32 ref = 0;
Jon Paul Maloy6c9808c2014-08-22 18:09:16 -04002248 struct tipc_sock *tsk = tipc_sk_get_next(&ref);
Jon Paul Maloy5a9ee0be2014-08-22 18:09:14 -04002249
Jon Paul Maloy6c9808c2014-08-22 18:09:16 -04002250 for (; tsk; tsk = tipc_sk_get_next(&ref)) {
2251 lock_sock(&tsk->sk);
Jon Paul Maloy5a9ee0be2014-08-22 18:09:14 -04002252 msg = &tsk->port.phdr;
2253 msg_set_prevnode(msg, tipc_own_addr);
2254 msg_set_orignode(msg, tipc_own_addr);
Jon Paul Maloy6c9808c2014-08-22 18:09:16 -04002255 release_sock(&tsk->sk);
2256 tipc_sk_put(tsk);
Jon Paul Maloy5a9ee0be2014-08-22 18:09:14 -04002257 }
2258}
2259
Per Lidenb97bf3f2006-01-02 19:04:38 +01002260/**
Jon Paul Maloy808d90f2014-08-22 18:09:19 -04002261 * struct reference - TIPC socket reference entry
2262 * @tsk: pointer to socket associated with reference entry
2263 * @ref: reference value for socket (combines instance & array index info)
2264 */
2265struct reference {
2266 struct tipc_sock *tsk;
2267 u32 ref;
2268};
2269
2270/**
2271 * struct tipc_ref_table - table of TIPC socket reference entries
2272 * @entries: pointer to array of reference entries
2273 * @capacity: array index of first unusable entry
2274 * @init_point: array index of first uninitialized entry
2275 * @first_free: array index of first unused socket reference entry
2276 * @last_free: array index of last unused socket reference entry
2277 * @index_mask: bitmask for array index portion of reference values
2278 * @start_mask: initial value for instance value portion of reference values
2279 */
2280struct ref_table {
2281 struct reference *entries;
2282 u32 capacity;
2283 u32 init_point;
2284 u32 first_free;
2285 u32 last_free;
2286 u32 index_mask;
2287 u32 start_mask;
2288};
2289
2290/* Socket reference table consists of 2**N entries.
2291 *
2292 * State Socket ptr Reference
2293 * ----- ---------- ---------
2294 * In use non-NULL XXXX|own index
2295 * (XXXX changes each time entry is acquired)
2296 * Free NULL YYYY|next free index
2297 * (YYYY is one more than last used XXXX)
2298 * Uninitialized NULL 0
2299 *
2300 * Entry 0 is not used; this allows index 0 to denote the end of the free list.
2301 *
2302 * Note that a reference value of 0 does not necessarily indicate that an
2303 * entry is uninitialized, since the last entry in the free list could also
2304 * have a reference value of 0 (although this is unlikely).
2305 */
2306
2307static struct ref_table tipc_ref_table;
2308
2309static DEFINE_RWLOCK(ref_table_lock);
2310
2311/**
2312 * tipc_ref_table_init - create reference table for sockets
2313 */
2314int tipc_sk_ref_table_init(u32 req_sz, u32 start)
2315{
2316 struct reference *table;
2317 u32 actual_sz;
2318
2319 /* account for unused entry, then round up size to a power of 2 */
2320
2321 req_sz++;
2322 for (actual_sz = 16; actual_sz < req_sz; actual_sz <<= 1) {
2323 /* do nothing */
2324 };
2325
2326 /* allocate table & mark all entries as uninitialized */
2327 table = vzalloc(actual_sz * sizeof(struct reference));
2328 if (table == NULL)
2329 return -ENOMEM;
2330
2331 tipc_ref_table.entries = table;
2332 tipc_ref_table.capacity = req_sz;
2333 tipc_ref_table.init_point = 1;
2334 tipc_ref_table.first_free = 0;
2335 tipc_ref_table.last_free = 0;
2336 tipc_ref_table.index_mask = actual_sz - 1;
2337 tipc_ref_table.start_mask = start & ~tipc_ref_table.index_mask;
2338
2339 return 0;
2340}
2341
2342/**
2343 * tipc_ref_table_stop - destroy reference table for sockets
2344 */
2345void tipc_sk_ref_table_stop(void)
2346{
2347 if (!tipc_ref_table.entries)
2348 return;
2349 vfree(tipc_ref_table.entries);
2350 tipc_ref_table.entries = NULL;
2351}
2352
2353/* tipc_ref_acquire - create reference to a socket
2354 *
2355 * Register an socket pointer in the reference table.
2356 * Returns a unique reference value that is used from then on to retrieve the
2357 * socket pointer, or to determine if the socket has been deregistered.
2358 */
2359u32 tipc_sk_ref_acquire(struct tipc_sock *tsk)
2360{
2361 u32 index;
2362 u32 index_mask;
2363 u32 next_plus_upper;
2364 u32 ref = 0;
2365 struct reference *entry;
2366
2367 if (unlikely(!tsk)) {
2368 pr_err("Attempt to acquire ref. to non-existent obj\n");
2369 return 0;
2370 }
2371 if (unlikely(!tipc_ref_table.entries)) {
2372 pr_err("Ref. table not found in acquisition attempt\n");
2373 return 0;
2374 }
2375
2376 /* Take a free entry, if available; otherwise initialize a new one */
2377 write_lock_bh(&ref_table_lock);
2378 index = tipc_ref_table.first_free;
2379 entry = &tipc_ref_table.entries[index];
2380
2381 if (likely(index)) {
2382 index = tipc_ref_table.first_free;
2383 entry = &tipc_ref_table.entries[index];
2384 index_mask = tipc_ref_table.index_mask;
2385 next_plus_upper = entry->ref;
2386 tipc_ref_table.first_free = next_plus_upper & index_mask;
2387 ref = (next_plus_upper & ~index_mask) + index;
2388 entry->tsk = tsk;
2389 } else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
2390 index = tipc_ref_table.init_point++;
2391 entry = &tipc_ref_table.entries[index];
2392 ref = tipc_ref_table.start_mask + index;
2393 }
2394
2395 if (ref) {
2396 entry->ref = ref;
2397 entry->tsk = tsk;
2398 }
2399 write_unlock_bh(&ref_table_lock);
2400 return ref;
2401}
2402
2403/* tipc_sk_ref_discard - invalidate reference to an socket
2404 *
2405 * Disallow future references to an socket and free up the entry for re-use.
2406 */
2407void tipc_sk_ref_discard(u32 ref)
2408{
2409 struct reference *entry;
2410 u32 index;
2411 u32 index_mask;
2412
2413 if (unlikely(!tipc_ref_table.entries)) {
2414 pr_err("Ref. table not found during discard attempt\n");
2415 return;
2416 }
2417
2418 index_mask = tipc_ref_table.index_mask;
2419 index = ref & index_mask;
2420 entry = &tipc_ref_table.entries[index];
2421
2422 write_lock_bh(&ref_table_lock);
2423
2424 if (unlikely(!entry->tsk)) {
2425 pr_err("Attempt to discard ref. to non-existent socket\n");
2426 goto exit;
2427 }
2428 if (unlikely(entry->ref != ref)) {
2429 pr_err("Attempt to discard non-existent reference\n");
2430 goto exit;
2431 }
2432
2433 /* Mark entry as unused; increment instance part of entry's
2434 * reference to invalidate any subsequent references
2435 */
2436
2437 entry->tsk = NULL;
2438 entry->ref = (ref & ~index_mask) + (index_mask + 1);
2439
2440 /* Append entry to free entry list */
2441 if (unlikely(tipc_ref_table.first_free == 0))
2442 tipc_ref_table.first_free = index;
2443 else
2444 tipc_ref_table.entries[tipc_ref_table.last_free].ref |= index;
2445 tipc_ref_table.last_free = index;
2446exit:
2447 write_unlock_bh(&ref_table_lock);
2448}
2449
2450/* tipc_sk_get - find referenced socket and return pointer to it
2451 */
2452struct tipc_sock *tipc_sk_get(u32 ref)
2453{
2454 struct reference *entry;
2455 struct tipc_sock *tsk;
2456
2457 if (unlikely(!tipc_ref_table.entries))
2458 return NULL;
2459 read_lock_bh(&ref_table_lock);
2460 entry = &tipc_ref_table.entries[ref & tipc_ref_table.index_mask];
2461 tsk = entry->tsk;
2462 if (likely(tsk && (entry->ref == ref)))
2463 sock_hold(&tsk->sk);
2464 else
2465 tsk = NULL;
2466 read_unlock_bh(&ref_table_lock);
2467 return tsk;
2468}
2469
2470/* tipc_sk_get_next - lock & return next socket after referenced one
2471*/
2472struct tipc_sock *tipc_sk_get_next(u32 *ref)
2473{
2474 struct reference *entry;
2475 struct tipc_sock *tsk = NULL;
2476 uint index = *ref & tipc_ref_table.index_mask;
2477
2478 read_lock_bh(&ref_table_lock);
2479 while (++index < tipc_ref_table.capacity) {
2480 entry = &tipc_ref_table.entries[index];
2481 if (!entry->tsk)
2482 continue;
2483 tsk = entry->tsk;
2484 sock_hold(&tsk->sk);
2485 *ref = entry->ref;
2486 break;
2487 }
2488 read_unlock_bh(&ref_table_lock);
2489 return tsk;
2490}
2491
2492static void tipc_sk_put(struct tipc_sock *tsk)
2493{
2494 sock_put(&tsk->sk);
2495}
2496
2497/**
Ying Xue247f0f32014-02-18 16:06:46 +08002498 * tipc_setsockopt - set socket option
Per Lidenb97bf3f2006-01-02 19:04:38 +01002499 * @sock: socket structure
2500 * @lvl: option level
2501 * @opt: option identifier
2502 * @ov: pointer to new option value
2503 * @ol: length of option value
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09002504 *
2505 * For stream sockets only, accepts and ignores all IPPROTO_TCP options
Per Lidenb97bf3f2006-01-02 19:04:38 +01002506 * (to ease compatibility).
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09002507 *
Per Lidenb97bf3f2006-01-02 19:04:38 +01002508 * Returns 0 on success, errno otherwise
2509 */
Ying Xue247f0f32014-02-18 16:06:46 +08002510static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
2511 char __user *ov, unsigned int ol)
Per Lidenb97bf3f2006-01-02 19:04:38 +01002512{
Allan Stephens0c3141e2008-04-15 00:22:02 -07002513 struct sock *sk = sock->sk;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -04002514 struct tipc_sock *tsk = tipc_sk(sk);
2515 struct tipc_port *port = &tsk->port;
Per Lidenb97bf3f2006-01-02 19:04:38 +01002516 u32 value;
2517 int res;
2518
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09002519 if ((lvl == IPPROTO_TCP) && (sock->type == SOCK_STREAM))
2520 return 0;
Per Lidenb97bf3f2006-01-02 19:04:38 +01002521 if (lvl != SOL_TIPC)
2522 return -ENOPROTOOPT;
2523 if (ol < sizeof(value))
2524 return -EINVAL;
Allan Stephens2db99832010-12-31 18:59:33 +00002525 res = get_user(value, (u32 __user *)ov);
2526 if (res)
Per Lidenb97bf3f2006-01-02 19:04:38 +01002527 return res;
2528
Allan Stephens0c3141e2008-04-15 00:22:02 -07002529 lock_sock(sk);
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09002530
Per Lidenb97bf3f2006-01-02 19:04:38 +01002531 switch (opt) {
2532 case TIPC_IMPORTANCE:
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04002533 res = tsk_set_importance(port, value);
Per Lidenb97bf3f2006-01-02 19:04:38 +01002534 break;
2535 case TIPC_SRC_DROPPABLE:
2536 if (sock->type != SOCK_STREAM)
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04002537 tsk_set_unreliable(port, value);
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09002538 else
Per Lidenb97bf3f2006-01-02 19:04:38 +01002539 res = -ENOPROTOOPT;
2540 break;
2541 case TIPC_DEST_DROPPABLE:
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04002542 tsk_set_unreturnable(port, value);
Per Lidenb97bf3f2006-01-02 19:04:38 +01002543 break;
2544 case TIPC_CONN_TIMEOUT:
Allan Stephensa0f40f02011-05-26 13:44:34 -04002545 tipc_sk(sk)->conn_timeout = value;
Allan Stephens0c3141e2008-04-15 00:22:02 -07002546 /* no need to set "res", since already 0 at this point */
Per Lidenb97bf3f2006-01-02 19:04:38 +01002547 break;
2548 default:
2549 res = -EINVAL;
2550 }
2551
Allan Stephens0c3141e2008-04-15 00:22:02 -07002552 release_sock(sk);
2553
Per Lidenb97bf3f2006-01-02 19:04:38 +01002554 return res;
2555}
2556
2557/**
Ying Xue247f0f32014-02-18 16:06:46 +08002558 * tipc_getsockopt - get socket option
Per Lidenb97bf3f2006-01-02 19:04:38 +01002559 * @sock: socket structure
2560 * @lvl: option level
2561 * @opt: option identifier
2562 * @ov: receptacle for option value
2563 * @ol: receptacle for length of option value
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09002564 *
2565 * For stream sockets only, returns 0 length result for all IPPROTO_TCP options
Per Lidenb97bf3f2006-01-02 19:04:38 +01002566 * (to ease compatibility).
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09002567 *
Per Lidenb97bf3f2006-01-02 19:04:38 +01002568 * Returns 0 on success, errno otherwise
2569 */
Ying Xue247f0f32014-02-18 16:06:46 +08002570static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
2571 char __user *ov, int __user *ol)
Per Lidenb97bf3f2006-01-02 19:04:38 +01002572{
Allan Stephens0c3141e2008-04-15 00:22:02 -07002573 struct sock *sk = sock->sk;
Jon Paul Maloy58ed9442014-03-12 11:31:12 -04002574 struct tipc_sock *tsk = tipc_sk(sk);
2575 struct tipc_port *port = &tsk->port;
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09002576 int len;
Per Lidenb97bf3f2006-01-02 19:04:38 +01002577 u32 value;
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09002578 int res;
Per Lidenb97bf3f2006-01-02 19:04:38 +01002579
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09002580 if ((lvl == IPPROTO_TCP) && (sock->type == SOCK_STREAM))
2581 return put_user(0, ol);
Per Lidenb97bf3f2006-01-02 19:04:38 +01002582 if (lvl != SOL_TIPC)
2583 return -ENOPROTOOPT;
Allan Stephens2db99832010-12-31 18:59:33 +00002584 res = get_user(len, ol);
2585 if (res)
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09002586 return res;
Per Lidenb97bf3f2006-01-02 19:04:38 +01002587
Allan Stephens0c3141e2008-04-15 00:22:02 -07002588 lock_sock(sk);
Per Lidenb97bf3f2006-01-02 19:04:38 +01002589
2590 switch (opt) {
2591 case TIPC_IMPORTANCE:
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04002592 value = tsk_importance(port);
Per Lidenb97bf3f2006-01-02 19:04:38 +01002593 break;
2594 case TIPC_SRC_DROPPABLE:
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04002595 value = tsk_unreliable(port);
Per Lidenb97bf3f2006-01-02 19:04:38 +01002596 break;
2597 case TIPC_DEST_DROPPABLE:
Jon Paul Maloy2e84c602014-08-22 18:09:18 -04002598 value = tsk_unreturnable(port);
Per Lidenb97bf3f2006-01-02 19:04:38 +01002599 break;
2600 case TIPC_CONN_TIMEOUT:
Allan Stephensa0f40f02011-05-26 13:44:34 -04002601 value = tipc_sk(sk)->conn_timeout;
Allan Stephens0c3141e2008-04-15 00:22:02 -07002602 /* no need to set "res", since already 0 at this point */
Per Lidenb97bf3f2006-01-02 19:04:38 +01002603 break;
Allan Stephens0e659672010-12-31 18:59:32 +00002604 case TIPC_NODE_RECVQ_DEPTH:
Ying Xue9da3d472012-11-27 06:15:27 -05002605 value = 0; /* was tipc_queue_size, now obsolete */
oscar.medina@motorola.com66506132009-06-30 03:25:39 +00002606 break;
Allan Stephens0e659672010-12-31 18:59:32 +00002607 case TIPC_SOCK_RECVQ_DEPTH:
oscar.medina@motorola.com66506132009-06-30 03:25:39 +00002608 value = skb_queue_len(&sk->sk_receive_queue);
2609 break;
Per Lidenb97bf3f2006-01-02 19:04:38 +01002610 default:
2611 res = -EINVAL;
2612 }
2613
Allan Stephens0c3141e2008-04-15 00:22:02 -07002614 release_sock(sk);
2615
Paul Gortmaker25860c32010-12-31 18:59:31 +00002616 if (res)
2617 return res; /* "get" failed */
Per Lidenb97bf3f2006-01-02 19:04:38 +01002618
Paul Gortmaker25860c32010-12-31 18:59:31 +00002619 if (len < sizeof(value))
2620 return -EINVAL;
2621
2622 if (copy_to_user(ov, &value, sizeof(value)))
2623 return -EFAULT;
2624
2625 return put_user(sizeof(value), ol);
Per Lidenb97bf3f2006-01-02 19:04:38 +01002626}
2627
Wei Yongjun52f50ce2014-07-20 13:14:28 +08002628static int tipc_ioctl(struct socket *sk, unsigned int cmd, unsigned long arg)
Erik Hugne78acb1f2014-04-24 16:26:47 +02002629{
2630 struct tipc_sioc_ln_req lnr;
2631 void __user *argp = (void __user *)arg;
2632
2633 switch (cmd) {
2634 case SIOCGETLINKNAME:
2635 if (copy_from_user(&lnr, argp, sizeof(lnr)))
2636 return -EFAULT;
2637 if (!tipc_node_get_linkname(lnr.bearer_id, lnr.peer,
2638 lnr.linkname, TIPC_MAX_LINK_NAME)) {
2639 if (copy_to_user(argp, &lnr, sizeof(lnr)))
2640 return -EFAULT;
2641 return 0;
2642 }
2643 return -EADDRNOTAVAIL;
Erik Hugne78acb1f2014-04-24 16:26:47 +02002644 default:
2645 return -ENOIOCTLCMD;
2646 }
2647}
2648
Ben Hutchingsae86b9e2012-07-10 10:55:35 +00002649/* Protocol switches for the various types of TIPC sockets */
2650
Florian Westphalbca65ea2008-02-07 18:18:01 -08002651static const struct proto_ops msg_ops = {
Allan Stephens0e659672010-12-31 18:59:32 +00002652 .owner = THIS_MODULE,
Per Lidenb97bf3f2006-01-02 19:04:38 +01002653 .family = AF_TIPC,
Ying Xue247f0f32014-02-18 16:06:46 +08002654 .release = tipc_release,
2655 .bind = tipc_bind,
2656 .connect = tipc_connect,
Allan Stephens5eee6a62007-06-10 17:24:55 -07002657 .socketpair = sock_no_socketpair,
Ying Xue245f3d32011-07-06 06:01:13 -04002658 .accept = sock_no_accept,
Ying Xue247f0f32014-02-18 16:06:46 +08002659 .getname = tipc_getname,
2660 .poll = tipc_poll,
Erik Hugne78acb1f2014-04-24 16:26:47 +02002661 .ioctl = tipc_ioctl,
Ying Xue245f3d32011-07-06 06:01:13 -04002662 .listen = sock_no_listen,
Ying Xue247f0f32014-02-18 16:06:46 +08002663 .shutdown = tipc_shutdown,
2664 .setsockopt = tipc_setsockopt,
2665 .getsockopt = tipc_getsockopt,
2666 .sendmsg = tipc_sendmsg,
2667 .recvmsg = tipc_recvmsg,
YOSHIFUJI Hideaki82387452007-07-19 10:44:56 +09002668 .mmap = sock_no_mmap,
2669 .sendpage = sock_no_sendpage
Per Lidenb97bf3f2006-01-02 19:04:38 +01002670};
2671
Florian Westphalbca65ea2008-02-07 18:18:01 -08002672static const struct proto_ops packet_ops = {
Allan Stephens0e659672010-12-31 18:59:32 +00002673 .owner = THIS_MODULE,
Per Lidenb97bf3f2006-01-02 19:04:38 +01002674 .family = AF_TIPC,
Ying Xue247f0f32014-02-18 16:06:46 +08002675 .release = tipc_release,
2676 .bind = tipc_bind,
2677 .connect = tipc_connect,
Allan Stephens5eee6a62007-06-10 17:24:55 -07002678 .socketpair = sock_no_socketpair,
Ying Xue247f0f32014-02-18 16:06:46 +08002679 .accept = tipc_accept,
2680 .getname = tipc_getname,
2681 .poll = tipc_poll,
Erik Hugne78acb1f2014-04-24 16:26:47 +02002682 .ioctl = tipc_ioctl,
Ying Xue247f0f32014-02-18 16:06:46 +08002683 .listen = tipc_listen,
2684 .shutdown = tipc_shutdown,
2685 .setsockopt = tipc_setsockopt,
2686 .getsockopt = tipc_getsockopt,
2687 .sendmsg = tipc_send_packet,
2688 .recvmsg = tipc_recvmsg,
YOSHIFUJI Hideaki82387452007-07-19 10:44:56 +09002689 .mmap = sock_no_mmap,
2690 .sendpage = sock_no_sendpage
Per Lidenb97bf3f2006-01-02 19:04:38 +01002691};
2692
Florian Westphalbca65ea2008-02-07 18:18:01 -08002693static const struct proto_ops stream_ops = {
Allan Stephens0e659672010-12-31 18:59:32 +00002694 .owner = THIS_MODULE,
Per Lidenb97bf3f2006-01-02 19:04:38 +01002695 .family = AF_TIPC,
Ying Xue247f0f32014-02-18 16:06:46 +08002696 .release = tipc_release,
2697 .bind = tipc_bind,
2698 .connect = tipc_connect,
Allan Stephens5eee6a62007-06-10 17:24:55 -07002699 .socketpair = sock_no_socketpair,
Ying Xue247f0f32014-02-18 16:06:46 +08002700 .accept = tipc_accept,
2701 .getname = tipc_getname,
2702 .poll = tipc_poll,
Erik Hugne78acb1f2014-04-24 16:26:47 +02002703 .ioctl = tipc_ioctl,
Ying Xue247f0f32014-02-18 16:06:46 +08002704 .listen = tipc_listen,
2705 .shutdown = tipc_shutdown,
2706 .setsockopt = tipc_setsockopt,
2707 .getsockopt = tipc_getsockopt,
2708 .sendmsg = tipc_send_stream,
2709 .recvmsg = tipc_recv_stream,
YOSHIFUJI Hideaki82387452007-07-19 10:44:56 +09002710 .mmap = sock_no_mmap,
2711 .sendpage = sock_no_sendpage
Per Lidenb97bf3f2006-01-02 19:04:38 +01002712};
2713
Florian Westphalbca65ea2008-02-07 18:18:01 -08002714static const struct net_proto_family tipc_family_ops = {
Allan Stephens0e659672010-12-31 18:59:32 +00002715 .owner = THIS_MODULE,
Per Lidenb97bf3f2006-01-02 19:04:38 +01002716 .family = AF_TIPC,
Ying Xuec5fa7b32013-06-17 10:54:39 -04002717 .create = tipc_sk_create
Per Lidenb97bf3f2006-01-02 19:04:38 +01002718};
2719
2720static struct proto tipc_proto = {
2721 .name = "TIPC",
2722 .owner = THIS_MODULE,
Ying Xuecc79dd12013-06-17 10:54:37 -04002723 .obj_size = sizeof(struct tipc_sock),
2724 .sysctl_rmem = sysctl_tipc_rmem
Per Lidenb97bf3f2006-01-02 19:04:38 +01002725};
2726
Ying Xuec5fa7b32013-06-17 10:54:39 -04002727static struct proto tipc_proto_kern = {
2728 .name = "TIPC",
2729 .obj_size = sizeof(struct tipc_sock),
2730 .sysctl_rmem = sysctl_tipc_rmem
2731};
2732
Per Lidenb97bf3f2006-01-02 19:04:38 +01002733/**
Per Liden4323add2006-01-18 00:38:21 +01002734 * tipc_socket_init - initialize TIPC socket interface
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09002735 *
Per Lidenb97bf3f2006-01-02 19:04:38 +01002736 * Returns 0 on success, errno otherwise
2737 */
Per Liden4323add2006-01-18 00:38:21 +01002738int tipc_socket_init(void)
Per Lidenb97bf3f2006-01-02 19:04:38 +01002739{
2740 int res;
2741
YOSHIFUJI Hideakic4307282007-02-09 23:25:21 +09002742 res = proto_register(&tipc_proto, 1);
Per Lidenb97bf3f2006-01-02 19:04:38 +01002743 if (res) {
Erik Hugne2cf8aa12012-06-29 00:16:37 -04002744 pr_err("Failed to register TIPC protocol type\n");
Per Lidenb97bf3f2006-01-02 19:04:38 +01002745 goto out;
2746 }
2747
2748 res = sock_register(&tipc_family_ops);
2749 if (res) {
Erik Hugne2cf8aa12012-06-29 00:16:37 -04002750 pr_err("Failed to register TIPC socket type\n");
Per Lidenb97bf3f2006-01-02 19:04:38 +01002751 proto_unregister(&tipc_proto);
2752 goto out;
2753 }
Per Lidenb97bf3f2006-01-02 19:04:38 +01002754 out:
2755 return res;
2756}
2757
2758/**
Per Liden4323add2006-01-18 00:38:21 +01002759 * tipc_socket_stop - stop TIPC socket interface
Per Lidenb97bf3f2006-01-02 19:04:38 +01002760 */
Per Liden4323add2006-01-18 00:38:21 +01002761void tipc_socket_stop(void)
Per Lidenb97bf3f2006-01-02 19:04:38 +01002762{
Per Lidenb97bf3f2006-01-02 19:04:38 +01002763 sock_unregister(tipc_family_ops.family);
2764 proto_unregister(&tipc_proto);
2765}