Phonet: don't bother with transaction IDs (especially for indications)
[deliverable/linux.git] / net / phonet / pep.c
CommitLineData
9641458d
RDC
1/*
2 * File: pep.c
3 *
4 * Phonet pipe protocol end point socket
5 *
6 * Copyright (C) 2008 Nokia Corporation.
7 *
8 * Author: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 */
24
25#include <linux/kernel.h>
5a0e3ad6 26#include <linux/slab.h>
9641458d
RDC
27#include <linux/socket.h>
28#include <net/sock.h>
29#include <net/tcp_states.h>
30#include <asm/ioctls.h>
31
32#include <linux/phonet.h>
33#include <net/phonet/phonet.h>
34#include <net/phonet/pep.h>
02a47617 35#include <net/phonet/gprs.h>
9641458d
RDC
36
37/* sk_state values:
38 * TCP_CLOSE sock not in use yet
39 * TCP_CLOSE_WAIT disconnected pipe
40 * TCP_LISTEN listening pipe endpoint
41 * TCP_SYN_RECV connected pipe in disabled state
42 * TCP_ESTABLISHED connected pipe in enabled state
43 *
44 * pep_sock locking:
45 * - sk_state, ackq, hlist: sock lock needed
46 * - listener: read only
47 * - pipe_handle: read only
48 */
49
50#define CREDITS_MAX 10
51#define CREDITS_THR 7
52
9641458d
RDC
53#define pep_sb_size(s) (((s) + 5) & ~3) /* 2-bytes head, 32-bits aligned */
54
55/* Get the next TLV sub-block. */
56static unsigned char *pep_get_sb(struct sk_buff *skb, u8 *ptype, u8 *plen,
57 void *buf)
58{
59 void *data = NULL;
60 struct {
61 u8 sb_type;
62 u8 sb_len;
63 } *ph, h;
64 int buflen = *plen;
65
66 ph = skb_header_pointer(skb, 0, 2, &h);
67 if (ph == NULL || ph->sb_len < 2 || !pskb_may_pull(skb, ph->sb_len))
68 return NULL;
69 ph->sb_len -= 2;
70 *ptype = ph->sb_type;
71 *plen = ph->sb_len;
72
73 if (buflen > ph->sb_len)
74 buflen = ph->sb_len;
75 data = skb_header_pointer(skb, 2, buflen, buf);
76 __skb_pull(skb, 2 + ph->sb_len);
77 return data;
78}
79
80static int pep_reply(struct sock *sk, struct sk_buff *oskb,
81 u8 code, const void *data, int len, gfp_t priority)
82{
83 const struct pnpipehdr *oph = pnp_hdr(oskb);
84 struct pnpipehdr *ph;
85 struct sk_buff *skb;
14ba8fae 86 struct sockaddr_pn peer;
9641458d
RDC
87
88 skb = alloc_skb(MAX_PNPIPE_HEADER + len, priority);
89 if (!skb)
90 return -ENOMEM;
91 skb_set_owner_w(skb, sk);
92
93 skb_reserve(skb, MAX_PNPIPE_HEADER);
94 __skb_put(skb, len);
95 skb_copy_to_linear_data(skb, data, len);
96 __skb_push(skb, sizeof(*ph));
97 skb_reset_transport_header(skb);
98 ph = pnp_hdr(skb);
99 ph->utid = oph->utid;
100 ph->message_id = oph->message_id + 1; /* REQ -> RESP */
101 ph->pipe_handle = oph->pipe_handle;
102 ph->error_code = code;
103
14ba8fae
RDC
104 pn_skb_get_src_sockaddr(oskb, &peer);
105 return pn_skb_send(sk, skb, &peer);
9641458d
RDC
106}
107
108#define PAD 0x00
8d98efa8
KS
109
110#ifdef CONFIG_PHONET_PIPECTRLR
111static u8 pipe_negotiate_fc(u8 *host_fc, u8 *remote_fc, int len)
112{
113 int i, j;
114 u8 base_fc, final_fc;
115
116 for (i = 0; i < len; i++) {
117 base_fc = host_fc[i];
118 for (j = 0; j < len; j++) {
119 if (remote_fc[j] == base_fc) {
120 final_fc = base_fc;
121 goto done;
122 }
123 }
124 }
125 return -EINVAL;
126
127done:
128 return final_fc;
129
130}
131
132static int pipe_get_flow_info(struct sock *sk, struct sk_buff *skb,
133 u8 *pref_rx_fc, u8 *req_tx_fc)
134{
135 struct pnpipehdr *hdr;
136 u8 n_sb;
137
138 if (!pskb_may_pull(skb, sizeof(*hdr) + 4))
139 return -EINVAL;
140
141 hdr = pnp_hdr(skb);
142 n_sb = hdr->data[4];
143
144 __skb_pull(skb, sizeof(*hdr) + 4);
145 while (n_sb > 0) {
146 u8 type, buf[3], len = sizeof(buf);
147 u8 *data = pep_get_sb(skb, &type, &len, buf);
148
149 if (data == NULL)
150 return -EINVAL;
151
152 switch (type) {
153 case PN_PIPE_SB_REQUIRED_FC_TX:
154 if (len < 3 || (data[2] | data[3] | data[4]) > 3)
155 break;
156 req_tx_fc[0] = data[2];
157 req_tx_fc[1] = data[3];
158 req_tx_fc[2] = data[4];
159 break;
160
161 case PN_PIPE_SB_PREFERRED_FC_RX:
162 if (len < 3 || (data[2] | data[3] | data[4]) > 3)
163 break;
164 pref_rx_fc[0] = data[2];
165 pref_rx_fc[1] = data[3];
166 pref_rx_fc[2] = data[4];
167 break;
168
169 }
170 n_sb--;
171 }
172 return 0;
173}
174
0165d69b 175static int pipe_handler_send_req(struct sock *sk, u8 msg_id, gfp_t priority)
8d98efa8
KS
176{
177 int len;
178 struct pnpipehdr *ph;
179 struct sk_buff *skb;
b3d62553 180 struct pep_sock *pn = pep_sk(sk);
8d98efa8
KS
181
182 static const u8 data[4] = {
183 PAD, PAD, PAD, PAD,
184 };
185
186 switch (msg_id) {
187 case PNS_PEP_CONNECT_REQ:
188 len = sizeof(data);
189 break;
190
191 case PNS_PEP_DISCONNECT_REQ:
192 case PNS_PEP_ENABLE_REQ:
193 case PNS_PEP_DISABLE_REQ:
194 len = 0;
195 break;
196
197 default:
198 return -EINVAL;
199 }
200
201 skb = alloc_skb(MAX_PNPIPE_HEADER + len, priority);
202 if (!skb)
203 return -ENOMEM;
204 skb_set_owner_w(skb, sk);
205
206 skb_reserve(skb, MAX_PNPIPE_HEADER);
207 if (len) {
208 __skb_put(skb, len);
209 skb_copy_to_linear_data(skb, data, len);
210 }
211 __skb_push(skb, sizeof(*ph));
212 skb_reset_transport_header(skb);
213 ph = pnp_hdr(skb);
0165d69b 214 ph->utid = msg_id; /* whatever */
8d98efa8 215 ph->message_id = msg_id;
b3d62553 216 ph->pipe_handle = pn->pipe_handle;
8d98efa8
KS
217 ph->error_code = PN_PIPE_NO_ERROR;
218
14ba8fae 219 return pn_skb_send(sk, skb, NULL);
8d98efa8
KS
220}
221
0165d69b 222static int pipe_handler_send_created_ind(struct sock *sk, u8 msg_id)
8d98efa8
KS
223{
224 int err_code;
225 struct pnpipehdr *ph;
226 struct sk_buff *skb;
8d98efa8 227
b3d62553 228 struct pep_sock *pn = pep_sk(sk);
8d98efa8
KS
229 static u8 data[4] = {
230 0x03, 0x04,
231 };
b3d62553
KS
232 data[2] = pn->tx_fc;
233 data[3] = pn->rx_fc;
8d98efa8
KS
234
235 /*
236 * actually, below is number of sub-blocks and not error code.
237 * Pipe_created_ind message format does not have any
238 * error code field. However, the Phonet stack will always send
239 * an error code as part of pnpipehdr. So, use that err_code to
240 * specify the number of sub-blocks.
241 */
242 err_code = 0x01;
243
244 skb = alloc_skb(MAX_PNPIPE_HEADER + sizeof(data), GFP_ATOMIC);
245 if (!skb)
246 return -ENOMEM;
247 skb_set_owner_w(skb, sk);
248
249 skb_reserve(skb, MAX_PNPIPE_HEADER);
250 __skb_put(skb, sizeof(data));
251 skb_copy_to_linear_data(skb, data, sizeof(data));
252 __skb_push(skb, sizeof(*ph));
253 skb_reset_transport_header(skb);
254 ph = pnp_hdr(skb);
0165d69b 255 ph->utid = 0;
8d98efa8 256 ph->message_id = msg_id;
b3d62553 257 ph->pipe_handle = pn->pipe_handle;
8d98efa8
KS
258 ph->error_code = err_code;
259
14ba8fae 260 return pn_skb_send(sk, skb, NULL);
8d98efa8
KS
261}
262
0165d69b 263static int pipe_handler_send_ind(struct sock *sk, u8 msg_id)
8d98efa8
KS
264{
265 int err_code;
266 struct pnpipehdr *ph;
267 struct sk_buff *skb;
b3d62553 268 struct pep_sock *pn = pep_sk(sk);
8d98efa8
KS
269
270 /*
271 * actually, below is a filler.
272 * Pipe_enabled/disabled_ind message format does not have any
273 * error code field. However, the Phonet stack will always send
274 * an error code as part of pnpipehdr. So, use that err_code to
275 * specify the filler value.
276 */
277 err_code = 0x0;
278
279 skb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC);
280 if (!skb)
281 return -ENOMEM;
282 skb_set_owner_w(skb, sk);
283
284 skb_reserve(skb, MAX_PNPIPE_HEADER);
285 __skb_push(skb, sizeof(*ph));
286 skb_reset_transport_header(skb);
287 ph = pnp_hdr(skb);
0165d69b 288 ph->utid = 0;
8d98efa8 289 ph->message_id = msg_id;
b3d62553 290 ph->pipe_handle = pn->pipe_handle;
8d98efa8
KS
291 ph->error_code = err_code;
292
14ba8fae 293 return pn_skb_send(sk, skb, NULL);
8d98efa8
KS
294}
295
03789f26 296static int pipe_handler_enable_pipe(struct sock *sk, int enable)
8d98efa8 297{
0165d69b
RDC
298 u8 id = enable ? PNS_PEP_ENABLE_REQ : PNS_PEP_DISABLE_REQ;
299
300 return pipe_handler_send_req(sk, id, GFP_KERNEL);
8d98efa8
KS
301}
302#endif
303
9641458d
RDC
304static int pep_accept_conn(struct sock *sk, struct sk_buff *skb)
305{
306 static const u8 data[20] = {
307 PAD, PAD, PAD, 2 /* sub-blocks */,
308 PN_PIPE_SB_REQUIRED_FC_TX, pep_sb_size(5), 3, PAD,
309 PN_MULTI_CREDIT_FLOW_CONTROL,
310 PN_ONE_CREDIT_FLOW_CONTROL,
311 PN_LEGACY_FLOW_CONTROL,
312 PAD,
313 PN_PIPE_SB_PREFERRED_FC_RX, pep_sb_size(5), 3, PAD,
314 PN_MULTI_CREDIT_FLOW_CONTROL,
315 PN_ONE_CREDIT_FLOW_CONTROL,
316 PN_LEGACY_FLOW_CONTROL,
317 PAD,
318 };
319
320 might_sleep();
321 return pep_reply(sk, skb, PN_PIPE_NO_ERROR, data, sizeof(data),
322 GFP_KERNEL);
323}
324
325static int pep_reject_conn(struct sock *sk, struct sk_buff *skb, u8 code)
326{
327 static const u8 data[4] = { PAD, PAD, PAD, 0 /* sub-blocks */ };
328 WARN_ON(code == PN_PIPE_NO_ERROR);
329 return pep_reply(sk, skb, code, data, sizeof(data), GFP_ATOMIC);
330}
331
332/* Control requests are not sent by the pipe service and have a specific
333 * message format. */
c41bd97f
RDC
334static int pep_ctrlreq_error(struct sock *sk, struct sk_buff *oskb, u8 code,
335 gfp_t priority)
9641458d
RDC
336{
337 const struct pnpipehdr *oph = pnp_hdr(oskb);
338 struct sk_buff *skb;
339 struct pnpipehdr *ph;
340 struct sockaddr_pn dst;
341
c41bd97f 342 skb = alloc_skb(MAX_PNPIPE_HEADER + 4, priority);
9641458d
RDC
343 if (!skb)
344 return -ENOMEM;
345 skb_set_owner_w(skb, sk);
346
347 skb_reserve(skb, MAX_PHONET_HEADER);
348 ph = (struct pnpipehdr *)skb_put(skb, sizeof(*ph) + 4);
349
350 ph->utid = oph->utid;
351 ph->message_id = PNS_PEP_CTRL_RESP;
352 ph->pipe_handle = oph->pipe_handle;
353 ph->data[0] = oph->data[1]; /* CTRL id */
354 ph->data[1] = oph->data[0]; /* PEP type */
355 ph->data[2] = code; /* error code, at an usual offset */
356 ph->data[3] = PAD;
357 ph->data[4] = PAD;
358
359 pn_skb_get_src_sockaddr(oskb, &dst);
360 return pn_skb_send(sk, skb, &dst);
361}
362
363static int pipe_snd_status(struct sock *sk, u8 type, u8 status, gfp_t priority)
364{
365 struct pep_sock *pn = pep_sk(sk);
366 struct pnpipehdr *ph;
367 struct sk_buff *skb;
368
369 skb = alloc_skb(MAX_PNPIPE_HEADER + 4, priority);
370 if (!skb)
371 return -ENOMEM;
372 skb_set_owner_w(skb, sk);
373
374 skb_reserve(skb, MAX_PNPIPE_HEADER + 4);
375 __skb_push(skb, sizeof(*ph) + 4);
376 skb_reset_transport_header(skb);
377 ph = pnp_hdr(skb);
378 ph->utid = 0;
379 ph->message_id = PNS_PEP_STATUS_IND;
380 ph->pipe_handle = pn->pipe_handle;
381 ph->pep_type = PN_PEP_TYPE_COMMON;
382 ph->data[1] = type;
383 ph->data[2] = PAD;
384 ph->data[3] = PAD;
385 ph->data[4] = status;
386
14ba8fae 387 return pn_skb_send(sk, skb, NULL);
9641458d
RDC
388}
389
390/* Send our RX flow control information to the sender.
391 * Socket must be locked. */
392static void pipe_grant_credits(struct sock *sk)
393{
394 struct pep_sock *pn = pep_sk(sk);
395
396 BUG_ON(sk->sk_state != TCP_ESTABLISHED);
397
398 switch (pn->rx_fc) {
399 case PN_LEGACY_FLOW_CONTROL: /* TODO */
400 break;
401 case PN_ONE_CREDIT_FLOW_CONTROL:
402 pipe_snd_status(sk, PN_PEP_IND_FLOW_CONTROL,
403 PEP_IND_READY, GFP_ATOMIC);
404 pn->rx_credits = 1;
405 break;
406 case PN_MULTI_CREDIT_FLOW_CONTROL:
407 if ((pn->rx_credits + CREDITS_THR) > CREDITS_MAX)
408 break;
409 if (pipe_snd_status(sk, PN_PEP_IND_ID_MCFC_GRANT_CREDITS,
410 CREDITS_MAX - pn->rx_credits,
411 GFP_ATOMIC) == 0)
412 pn->rx_credits = CREDITS_MAX;
413 break;
414 }
415}
416
417static int pipe_rcv_status(struct sock *sk, struct sk_buff *skb)
418{
419 struct pep_sock *pn = pep_sk(sk);
a91e7d47 420 struct pnpipehdr *hdr;
be677730 421 int wake = 0;
9641458d
RDC
422
423 if (!pskb_may_pull(skb, sizeof(*hdr) + 4))
424 return -EINVAL;
425
a91e7d47 426 hdr = pnp_hdr(skb);
9641458d
RDC
427 if (hdr->data[0] != PN_PEP_TYPE_COMMON) {
428 LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP type: %u\n",
429 (unsigned)hdr->data[0]);
430 return -EOPNOTSUPP;
431 }
432
433 switch (hdr->data[1]) {
434 case PN_PEP_IND_FLOW_CONTROL:
435 switch (pn->tx_fc) {
436 case PN_LEGACY_FLOW_CONTROL:
437 switch (hdr->data[4]) {
438 case PEP_IND_BUSY:
be677730 439 atomic_set(&pn->tx_credits, 0);
9641458d
RDC
440 break;
441 case PEP_IND_READY:
be677730 442 atomic_set(&pn->tx_credits, wake = 1);
9641458d
RDC
443 break;
444 }
445 break;
446 case PN_ONE_CREDIT_FLOW_CONTROL:
447 if (hdr->data[4] == PEP_IND_READY)
be677730 448 atomic_set(&pn->tx_credits, wake = 1);
9641458d
RDC
449 break;
450 }
451 break;
452
453 case PN_PEP_IND_ID_MCFC_GRANT_CREDITS:
454 if (pn->tx_fc != PN_MULTI_CREDIT_FLOW_CONTROL)
455 break;
be677730 456 atomic_add(wake = hdr->data[4], &pn->tx_credits);
9641458d
RDC
457 break;
458
459 default:
460 LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP indication: %u\n",
461 (unsigned)hdr->data[1]);
462 return -EOPNOTSUPP;
463 }
be677730 464 if (wake)
9641458d
RDC
465 sk->sk_write_space(sk);
466 return 0;
467}
468
469static int pipe_rcv_created(struct sock *sk, struct sk_buff *skb)
470{
471 struct pep_sock *pn = pep_sk(sk);
472 struct pnpipehdr *hdr = pnp_hdr(skb);
473 u8 n_sb = hdr->data[0];
474
475 pn->rx_fc = pn->tx_fc = PN_LEGACY_FLOW_CONTROL;
476 __skb_pull(skb, sizeof(*hdr));
477 while (n_sb > 0) {
478 u8 type, buf[2], len = sizeof(buf);
479 u8 *data = pep_get_sb(skb, &type, &len, buf);
480
481 if (data == NULL)
482 return -EINVAL;
483 switch (type) {
484 case PN_PIPE_SB_NEGOTIATED_FC:
485 if (len < 2 || (data[0] | data[1]) > 3)
486 break;
487 pn->tx_fc = data[0] & 3;
488 pn->rx_fc = data[1] & 3;
489 break;
490 }
491 n_sb--;
492 }
493 return 0;
494}
495
496/* Queue an skb to a connected sock.
497 * Socket lock must be held. */
498static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb)
499{
500 struct pep_sock *pn = pep_sk(sk);
501 struct pnpipehdr *hdr = pnp_hdr(skb);
c41bd97f 502 struct sk_buff_head *queue;
9641458d
RDC
503 int err = 0;
504
505 BUG_ON(sk->sk_state == TCP_CLOSE_WAIT);
506
507 switch (hdr->message_id) {
508 case PNS_PEP_CONNECT_REQ:
509 pep_reject_conn(sk, skb, PN_PIPE_ERR_PEP_IN_USE);
510 break;
511
512 case PNS_PEP_DISCONNECT_REQ:
513 pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC);
514 sk->sk_state = TCP_CLOSE_WAIT;
515 if (!sock_flag(sk, SOCK_DEAD))
516 sk->sk_state_change(sk);
517 break;
518
8d98efa8
KS
519#ifdef CONFIG_PHONET_PIPECTRLR
520 case PNS_PEP_DISCONNECT_RESP:
b3d62553 521 sk->sk_state = TCP_CLOSE;
8d98efa8
KS
522 break;
523#endif
524
9641458d
RDC
525 case PNS_PEP_ENABLE_REQ:
526 /* Wait for PNS_PIPE_(ENABLED|REDIRECTED)_IND */
527 pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC);
528 break;
529
8d98efa8
KS
530#ifdef CONFIG_PHONET_PIPECTRLR
531 case PNS_PEP_ENABLE_RESP:
0165d69b 532 pipe_handler_send_ind(sk, PNS_PIPE_ENABLED_IND);
8d98efa8 533
b3d62553
KS
534 if (!pn_flow_safe(pn->tx_fc)) {
535 atomic_set(&pn->tx_credits, 1);
536 sk->sk_write_space(sk);
537 }
538 if (sk->sk_state == TCP_ESTABLISHED)
539 break; /* Nothing to do */
540 sk->sk_state = TCP_ESTABLISHED;
541 pipe_grant_credits(sk);
8d98efa8
KS
542 break;
543#endif
544
9641458d
RDC
545 case PNS_PEP_RESET_REQ:
546 switch (hdr->state_after_reset) {
547 case PN_PIPE_DISABLE:
548 pn->init_enable = 0;
549 break;
550 case PN_PIPE_ENABLE:
551 pn->init_enable = 1;
552 break;
553 default: /* not allowed to send an error here!? */
554 err = -EINVAL;
555 goto out;
556 }
557 /* fall through */
558 case PNS_PEP_DISABLE_REQ:
be677730 559 atomic_set(&pn->tx_credits, 0);
9641458d
RDC
560 pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC);
561 break;
562
8d98efa8
KS
563#ifdef CONFIG_PHONET_PIPECTRLR
564 case PNS_PEP_DISABLE_RESP:
b3d62553 565 atomic_set(&pn->tx_credits, 0);
0165d69b 566 pipe_handler_send_ind(sk, PNS_PIPE_DISABLED_IND);
b3d62553
KS
567 sk->sk_state = TCP_SYN_RECV;
568 pn->rx_credits = 0;
8d98efa8
KS
569 break;
570#endif
571
9641458d 572 case PNS_PEP_CTRL_REQ:
2e2fb4b3
RDC
573 if (skb_queue_len(&pn->ctrlreq_queue) >= PNPIPE_CTRLREQ_MAX) {
574 atomic_inc(&sk->sk_drops);
c41bd97f 575 break;
2e2fb4b3 576 }
c41bd97f
RDC
577 __skb_pull(skb, 4);
578 queue = &pn->ctrlreq_queue;
579 goto queue;
9641458d 580
fc6a1107
RDC
581 case PNS_PIPE_ALIGNED_DATA:
582 __skb_pull(skb, 1);
583 /* fall through */
9641458d
RDC
584 case PNS_PIPE_DATA:
585 __skb_pull(skb, 3); /* Pipe data header */
586 if (!pn_flow_safe(pn->rx_fc)) {
587 err = sock_queue_rcv_skb(sk, skb);
588 if (!err)
589 return 0;
590 break;
591 }
592
593 if (pn->rx_credits == 0) {
2e2fb4b3 594 atomic_inc(&sk->sk_drops);
9641458d
RDC
595 err = -ENOBUFS;
596 break;
597 }
598 pn->rx_credits--;
c41bd97f
RDC
599 queue = &sk->sk_receive_queue;
600 goto queue;
9641458d
RDC
601
602 case PNS_PEP_STATUS_IND:
603 pipe_rcv_status(sk, skb);
604 break;
605
606 case PNS_PIPE_REDIRECTED_IND:
607 err = pipe_rcv_created(sk, skb);
608 break;
609
610 case PNS_PIPE_CREATED_IND:
611 err = pipe_rcv_created(sk, skb);
612 if (err)
613 break;
614 /* fall through */
615 case PNS_PIPE_RESET_IND:
616 if (!pn->init_enable)
617 break;
618 /* fall through */
619 case PNS_PIPE_ENABLED_IND:
620 if (!pn_flow_safe(pn->tx_fc)) {
be677730 621 atomic_set(&pn->tx_credits, 1);
9641458d
RDC
622 sk->sk_write_space(sk);
623 }
624 if (sk->sk_state == TCP_ESTABLISHED)
625 break; /* Nothing to do */
626 sk->sk_state = TCP_ESTABLISHED;
627 pipe_grant_credits(sk);
628 break;
629
630 case PNS_PIPE_DISABLED_IND:
631 sk->sk_state = TCP_SYN_RECV;
632 pn->rx_credits = 0;
633 break;
634
635 default:
636 LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP message: %u\n",
637 hdr->message_id);
638 err = -EINVAL;
639 }
640out:
641 kfree_skb(skb);
642 return err;
c41bd97f
RDC
643
644queue:
645 skb->dev = NULL;
646 skb_set_owner_r(skb, sk);
647 err = skb->len;
648 skb_queue_tail(queue, skb);
649 if (!sock_flag(sk, SOCK_DEAD))
650 sk->sk_data_ready(sk, err);
651 return 0;
9641458d
RDC
652}
653
654/* Destroy connected sock. */
655static void pipe_destruct(struct sock *sk)
656{
c41bd97f
RDC
657 struct pep_sock *pn = pep_sk(sk);
658
9641458d 659 skb_queue_purge(&sk->sk_receive_queue);
c41bd97f 660 skb_queue_purge(&pn->ctrlreq_queue);
9641458d
RDC
661}
662
b3d62553
KS
663#ifdef CONFIG_PHONET_PIPECTRLR
664static int pep_connresp_rcv(struct sock *sk, struct sk_buff *skb)
665{
666 struct pep_sock *pn = pep_sk(sk);
667 u8 host_pref_rx_fc[3] = {3, 2, 1}, host_req_tx_fc[3] = {3, 2, 1};
668 u8 remote_pref_rx_fc[3], remote_req_tx_fc[3];
669 u8 negotiated_rx_fc, negotiated_tx_fc;
b3d62553
KS
670
671 pipe_get_flow_info(sk, skb, remote_pref_rx_fc,
672 remote_req_tx_fc);
673 negotiated_tx_fc = pipe_negotiate_fc(remote_req_tx_fc,
674 host_pref_rx_fc,
675 sizeof(host_pref_rx_fc));
676 negotiated_rx_fc = pipe_negotiate_fc(host_req_tx_fc,
677 remote_pref_rx_fc,
678 sizeof(host_pref_rx_fc));
679
b3d62553
KS
680 sk->sk_state = TCP_SYN_RECV;
681 sk->sk_backlog_rcv = pipe_do_rcv;
682 sk->sk_destruct = pipe_destruct;
683 pn->rx_credits = 0;
684 pn->rx_fc = negotiated_rx_fc;
685 pn->tx_fc = negotiated_tx_fc;
686 sk->sk_state_change(sk);
687
0165d69b 688 return pipe_handler_send_created_ind(sk, PNS_PIPE_CREATED_IND);
b3d62553
KS
689}
690#endif
691
9641458d
RDC
692static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb)
693{
694 struct sock *newsk;
695 struct pep_sock *newpn, *pn = pep_sk(sk);
696 struct pnpipehdr *hdr;
14ba8fae 697 struct sockaddr_pn dst, src;
9641458d
RDC
698 u16 peer_type;
699 u8 pipe_handle, enabled, n_sb;
fea93ece 700 u8 aligned = 0;
9641458d
RDC
701
702 if (!pskb_pull(skb, sizeof(*hdr) + 4))
703 return -EINVAL;
704
705 hdr = pnp_hdr(skb);
706 pipe_handle = hdr->pipe_handle;
707 switch (hdr->state_after_connect) {
708 case PN_PIPE_DISABLE:
709 enabled = 0;
710 break;
711 case PN_PIPE_ENABLE:
712 enabled = 1;
713 break;
714 default:
715 pep_reject_conn(sk, skb, PN_PIPE_ERR_INVALID_PARAM);
716 return -EINVAL;
717 }
718 peer_type = hdr->other_pep_type << 8;
719
720 if (unlikely(sk->sk_state != TCP_LISTEN) || sk_acceptq_is_full(sk)) {
721 pep_reject_conn(sk, skb, PN_PIPE_ERR_PEP_IN_USE);
722 return -ENOBUFS;
723 }
724
725 /* Parse sub-blocks (options) */
726 n_sb = hdr->data[4];
727 while (n_sb > 0) {
728 u8 type, buf[1], len = sizeof(buf);
729 const u8 *data = pep_get_sb(skb, &type, &len, buf);
730
731 if (data == NULL)
732 return -EINVAL;
733 switch (type) {
734 case PN_PIPE_SB_CONNECT_REQ_PEP_SUB_TYPE:
735 if (len < 1)
736 return -EINVAL;
737 peer_type = (peer_type & 0xff00) | data[0];
738 break;
fea93ece
RDC
739 case PN_PIPE_SB_ALIGNED_DATA:
740 aligned = data[0] != 0;
741 break;
9641458d
RDC
742 }
743 n_sb--;
744 }
745
746 skb = skb_clone(skb, GFP_ATOMIC);
747 if (!skb)
748 return -ENOMEM;
749
750 /* Create a new to-be-accepted sock */
751 newsk = sk_alloc(sock_net(sk), PF_PHONET, GFP_ATOMIC, sk->sk_prot);
752 if (!newsk) {
753 kfree_skb(skb);
754 return -ENOMEM;
755 }
756 sock_init_data(NULL, newsk);
757 newsk->sk_state = TCP_SYN_RECV;
758 newsk->sk_backlog_rcv = pipe_do_rcv;
759 newsk->sk_protocol = sk->sk_protocol;
760 newsk->sk_destruct = pipe_destruct;
761
762 newpn = pep_sk(newsk);
763 pn_skb_get_dst_sockaddr(skb, &dst);
14ba8fae 764 pn_skb_get_src_sockaddr(skb, &src);
9641458d 765 newpn->pn_sk.sobject = pn_sockaddr_get_object(&dst);
14ba8fae
RDC
766 newpn->pn_sk.dobject = pn_sockaddr_get_object(&src);
767 newpn->pn_sk.resource = pn_sockaddr_get_resource(&dst);
c41bd97f 768 skb_queue_head_init(&newpn->ctrlreq_queue);
9641458d 769 newpn->pipe_handle = pipe_handle;
be677730 770 atomic_set(&newpn->tx_credits, 0);
9641458d 771 newpn->peer_type = peer_type;
be677730 772 newpn->rx_credits = 0;
9641458d
RDC
773 newpn->rx_fc = newpn->tx_fc = PN_LEGACY_FLOW_CONTROL;
774 newpn->init_enable = enabled;
fea93ece 775 newpn->aligned = aligned;
9641458d
RDC
776
777 BUG_ON(!skb_queue_empty(&newsk->sk_receive_queue));
778 skb_queue_head(&newsk->sk_receive_queue, skb);
779 if (!sock_flag(sk, SOCK_DEAD))
780 sk->sk_data_ready(sk, 0);
781
782 sk_acceptq_added(sk);
783 sk_add_node(newsk, &pn->ackq);
784 return 0;
785}
786
787/* Listening sock must be locked */
788static struct sock *pep_find_pipe(const struct hlist_head *hlist,
789 const struct sockaddr_pn *dst,
790 u8 pipe_handle)
791{
792 struct hlist_node *node;
793 struct sock *sknode;
794 u16 dobj = pn_sockaddr_get_object(dst);
795
796 sk_for_each(sknode, node, hlist) {
797 struct pep_sock *pnnode = pep_sk(sknode);
798
799 /* Ports match, but addresses might not: */
800 if (pnnode->pn_sk.sobject != dobj)
801 continue;
802 if (pnnode->pipe_handle != pipe_handle)
803 continue;
804 if (sknode->sk_state == TCP_CLOSE_WAIT)
805 continue;
806
807 sock_hold(sknode);
808 return sknode;
809 }
810 return NULL;
811}
812
813/*
814 * Deliver an skb to a listening sock.
815 * Socket lock must be held.
816 * We then queue the skb to the right connected sock (if any).
817 */
818static int pep_do_rcv(struct sock *sk, struct sk_buff *skb)
819{
820 struct pep_sock *pn = pep_sk(sk);
821 struct sock *sknode;
2ddc1ac1 822 struct pnpipehdr *hdr;
9641458d
RDC
823 struct sockaddr_pn dst;
824 int err = NET_RX_SUCCESS;
825 u8 pipe_handle;
826
827 if (!pskb_may_pull(skb, sizeof(*hdr)))
828 goto drop;
829
830 hdr = pnp_hdr(skb);
831 pipe_handle = hdr->pipe_handle;
832 if (pipe_handle == PN_PIPE_INVALID_HANDLE)
833 goto drop;
834
835 pn_skb_get_dst_sockaddr(skb, &dst);
836
837 /* Look for an existing pipe handle */
838 sknode = pep_find_pipe(&pn->hlist, &dst, pipe_handle);
839 if (sknode)
840 return sk_receive_skb(sknode, skb, 1);
841
842 /* Look for a pipe handle pending accept */
843 sknode = pep_find_pipe(&pn->ackq, &dst, pipe_handle);
844 if (sknode) {
845 sock_put(sknode);
846 if (net_ratelimit())
847 printk(KERN_WARNING"Phonet unconnected PEP ignored");
848 err = NET_RX_DROP;
849 goto drop;
850 }
851
852 switch (hdr->message_id) {
853 case PNS_PEP_CONNECT_REQ:
854 err = pep_connreq_rcv(sk, skb);
855 break;
856
b3d62553
KS
857#ifdef CONFIG_PHONET_PIPECTRLR
858 case PNS_PEP_CONNECT_RESP:
859 err = pep_connresp_rcv(sk, skb);
860 break;
861#endif
862
9641458d
RDC
863 case PNS_PEP_DISCONNECT_REQ:
864 pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC);
865 break;
866
867 case PNS_PEP_CTRL_REQ:
c41bd97f 868 pep_ctrlreq_error(sk, skb, PN_PIPE_INVALID_HANDLE, GFP_ATOMIC);
9641458d
RDC
869 break;
870
871 case PNS_PEP_RESET_REQ:
872 case PNS_PEP_ENABLE_REQ:
873 case PNS_PEP_DISABLE_REQ:
874 /* invalid handle is not even allowed here! */
875 default:
876 err = NET_RX_DROP;
877 }
878drop:
879 kfree_skb(skb);
880 return err;
881}
882
6482f554
RDC
883static int pipe_do_remove(struct sock *sk)
884{
885 struct pep_sock *pn = pep_sk(sk);
886 struct pnpipehdr *ph;
887 struct sk_buff *skb;
888
889 skb = alloc_skb(MAX_PNPIPE_HEADER, GFP_KERNEL);
890 if (!skb)
891 return -ENOMEM;
892
893 skb_reserve(skb, MAX_PNPIPE_HEADER);
894 __skb_push(skb, sizeof(*ph));
895 skb_reset_transport_header(skb);
896 ph = pnp_hdr(skb);
897 ph->utid = 0;
898 ph->message_id = PNS_PIPE_REMOVE_REQ;
899 ph->pipe_handle = pn->pipe_handle;
900 ph->data[0] = PAD;
901
14ba8fae 902 return pn_skb_send(sk, skb, NULL);
6482f554
RDC
903}
904
9641458d
RDC
905/* associated socket ceases to exist */
906static void pep_sock_close(struct sock *sk, long timeout)
907{
908 struct pep_sock *pn = pep_sk(sk);
02a47617 909 int ifindex = 0;
9641458d 910
e513480e 911 sock_hold(sk); /* keep a reference after sk_common_release() */
9641458d
RDC
912 sk_common_release(sk);
913
914 lock_sock(sk);
915 if (sk->sk_state == TCP_LISTEN) {
916 /* Destroy the listen queue */
917 struct sock *sknode;
918 struct hlist_node *p, *n;
919
920 sk_for_each_safe(sknode, p, n, &pn->ackq)
921 sk_del_node_init(sknode);
922 sk->sk_state = TCP_CLOSE;
2feb6181
RDC
923 } else if ((1 << sk->sk_state) & (TCPF_SYN_RECV|TCPF_ESTABLISHED)) {
924#ifndef CONFIG_PHONET_PIPECTRLR
6482f554
RDC
925 /* Forcefully remove dangling Phonet pipe */
926 pipe_do_remove(sk);
2feb6181 927#else
b3d62553 928 /* send pep disconnect request */
0165d69b 929 pipe_handler_send_req(sk, PNS_PEP_DISCONNECT_REQ, GFP_KERNEL);
b3d62553 930 sk->sk_state = TCP_CLOSE;
b3d62553 931#endif
2feb6181 932 }
b3d62553 933
02a47617
RDC
934 ifindex = pn->ifindex;
935 pn->ifindex = 0;
9641458d 936 release_sock(sk);
02a47617
RDC
937
938 if (ifindex)
939 gprs_detach(sk);
e513480e 940 sock_put(sk);
9641458d
RDC
941}
942
943static int pep_wait_connreq(struct sock *sk, int noblock)
944{
945 struct task_struct *tsk = current;
946 struct pep_sock *pn = pep_sk(sk);
947 long timeo = sock_rcvtimeo(sk, noblock);
948
949 for (;;) {
950 DEFINE_WAIT(wait);
951
952 if (sk->sk_state != TCP_LISTEN)
953 return -EINVAL;
954 if (!hlist_empty(&pn->ackq))
955 break;
956 if (!timeo)
957 return -EWOULDBLOCK;
958 if (signal_pending(tsk))
959 return sock_intr_errno(timeo);
960
43815482 961 prepare_to_wait_exclusive(sk_sleep(sk), &wait,
9641458d
RDC
962 TASK_INTERRUPTIBLE);
963 release_sock(sk);
964 timeo = schedule_timeout(timeo);
965 lock_sock(sk);
43815482 966 finish_wait(sk_sleep(sk), &wait);
9641458d
RDC
967 }
968
969 return 0;
970}
971
972static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp)
973{
974 struct pep_sock *pn = pep_sk(sk);
975 struct sock *newsk = NULL;
976 struct sk_buff *oskb;
977 int err;
978
979 lock_sock(sk);
980 err = pep_wait_connreq(sk, flags & O_NONBLOCK);
981 if (err)
982 goto out;
983
984 newsk = __sk_head(&pn->ackq);
985
986 oskb = skb_dequeue(&newsk->sk_receive_queue);
987 err = pep_accept_conn(newsk, oskb);
988 if (err) {
989 skb_queue_head(&newsk->sk_receive_queue, oskb);
990 newsk = NULL;
991 goto out;
992 }
635f0815 993 kfree_skb(oskb);
9641458d
RDC
994
995 sock_hold(sk);
996 pep_sk(newsk)->listener = sk;
997
998 sock_hold(newsk);
999 sk_del_node_init(newsk);
1000 sk_acceptq_removed(sk);
1001 sk_add_node(newsk, &pn->hlist);
1002 __sock_put(newsk);
1003
1004out:
1005 release_sock(sk);
1006 *errp = err;
1007 return newsk;
1008}
1009
b3d62553
KS
1010#ifdef CONFIG_PHONET_PIPECTRLR
1011static int pep_sock_connect(struct sock *sk, struct sockaddr *addr, int len)
1012{
1013 struct pep_sock *pn = pep_sk(sk);
14ba8fae 1014 const struct sockaddr_pn *spn = (struct sockaddr_pn *)addr;
b3d62553 1015
14ba8fae
RDC
1016 pn->pn_sk.dobject = pn_sockaddr_get_object(spn);
1017 pn->pn_sk.resource = pn_sockaddr_get_resource(spn);
0165d69b 1018 return pipe_handler_send_req(sk, PNS_PEP_CONNECT_REQ, GFP_KERNEL);
b3d62553
KS
1019}
1020#endif
1021
9641458d
RDC
1022static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg)
1023{
c41bd97f 1024 struct pep_sock *pn = pep_sk(sk);
9641458d
RDC
1025 int answ;
1026
1027 switch (cmd) {
1028 case SIOCINQ:
1029 if (sk->sk_state == TCP_LISTEN)
1030 return -EINVAL;
1031
1032 lock_sock(sk);
f64f9e71
JP
1033 if (sock_flag(sk, SOCK_URGINLINE) &&
1034 !skb_queue_empty(&pn->ctrlreq_queue))
c41bd97f
RDC
1035 answ = skb_peek(&pn->ctrlreq_queue)->len;
1036 else if (!skb_queue_empty(&sk->sk_receive_queue))
9641458d
RDC
1037 answ = skb_peek(&sk->sk_receive_queue)->len;
1038 else
1039 answ = 0;
1040 release_sock(sk);
1041 return put_user(answ, (int __user *)arg);
1042 }
1043
1044 return -ENOIOCTLCMD;
1045}
1046
1047static int pep_init(struct sock *sk)
1048{
1049 struct pep_sock *pn = pep_sk(sk);
1050
1051 INIT_HLIST_HEAD(&pn->ackq);
1052 INIT_HLIST_HEAD(&pn->hlist);
c41bd97f 1053 skb_queue_head_init(&pn->ctrlreq_queue);
9641458d
RDC
1054 pn->pipe_handle = PN_PIPE_INVALID_HANDLE;
1055 return 0;
1056}
1057
02a47617 1058static int pep_setsockopt(struct sock *sk, int level, int optname,
b7058842 1059 char __user *optval, unsigned int optlen)
02a47617
RDC
1060{
1061 struct pep_sock *pn = pep_sk(sk);
1062 int val = 0, err = 0;
1063
1064 if (level != SOL_PNPIPE)
1065 return -ENOPROTOOPT;
1066 if (optlen >= sizeof(int)) {
1067 if (get_user(val, (int __user *) optval))
1068 return -EFAULT;
1069 }
1070
1071 lock_sock(sk);
1072 switch (optname) {
8d98efa8 1073#ifdef CONFIG_PHONET_PIPECTRLR
b3d62553 1074 case PNPIPE_PIPE_HANDLE:
8d98efa8 1075 if (val) {
b3d62553 1076 pn->pipe_handle = val;
8d98efa8
KS
1077 break;
1078 }
8d98efa8
KS
1079#endif
1080
02a47617
RDC
1081 case PNPIPE_ENCAP:
1082 if (val && val != PNPIPE_ENCAP_IP) {
1083 err = -EINVAL;
1084 break;
1085 }
1086 if (!pn->ifindex == !val)
1087 break; /* Nothing to do! */
1088 if (!capable(CAP_NET_ADMIN)) {
1089 err = -EPERM;
1090 break;
1091 }
1092 if (val) {
1093 release_sock(sk);
1094 err = gprs_attach(sk);
1095 if (err > 0) {
1096 pn->ifindex = err;
1097 err = 0;
1098 }
1099 } else {
1100 pn->ifindex = 0;
1101 release_sock(sk);
1102 gprs_detach(sk);
1103 err = 0;
1104 }
1105 goto out_norel;
03789f26
RDC
1106
1107#ifdef CONFIG_PHONET_PIPECTRLR
1108 case PNPIPE_ENABLE:
2feb6181 1109 if ((1 << sk->sk_state) & ~(TCPF_SYN_RECV|TCPF_ESTABLISHED)) {
03789f26
RDC
1110 err = -ENOTCONN;
1111 break;
1112 }
1113 err = pipe_handler_enable_pipe(sk, val);
1114 break;
1115#endif
1116
02a47617
RDC
1117 default:
1118 err = -ENOPROTOOPT;
1119 }
1120 release_sock(sk);
1121
1122out_norel:
1123 return err;
1124}
1125
1126static int pep_getsockopt(struct sock *sk, int level, int optname,
1127 char __user *optval, int __user *optlen)
1128{
1129 struct pep_sock *pn = pep_sk(sk);
1130 int len, val;
1131
1132 if (level != SOL_PNPIPE)
1133 return -ENOPROTOOPT;
1134 if (get_user(len, optlen))
1135 return -EFAULT;
1136
1137 switch (optname) {
1138 case PNPIPE_ENCAP:
1139 val = pn->ifindex ? PNPIPE_ENCAP_IP : PNPIPE_ENCAP_NONE;
1140 break;
8d98efa8 1141
03789f26
RDC
1142 case PNPIPE_IFINDEX:
1143 val = pn->ifindex;
1144 break;
1145
8d98efa8 1146#ifdef CONFIG_PHONET_PIPECTRLR
03789f26 1147 case PNPIPE_ENABLE:
2feb6181 1148 val = sk->sk_state == TCP_ESTABLISHED;
8d98efa8
KS
1149 break;
1150#endif
1151
02a47617
RDC
1152 default:
1153 return -ENOPROTOOPT;
1154 }
1155
1156 len = min_t(unsigned int, sizeof(int), len);
1157 if (put_user(len, optlen))
1158 return -EFAULT;
1159 if (put_user(val, (int __user *) optval))
1160 return -EFAULT;
1161 return 0;
1162}
1163
1164static int pipe_skb_send(struct sock *sk, struct sk_buff *skb)
1165{
1166 struct pep_sock *pn = pep_sk(sk);
1167 struct pnpipehdr *ph;
e1a5964f 1168 int err;
02a47617 1169
be677730
RDC
1170 if (pn_flow_safe(pn->tx_fc) &&
1171 !atomic_add_unless(&pn->tx_credits, -1, 0)) {
1172 kfree_skb(skb);
1173 return -ENOBUFS;
1174 }
1175
fea93ece 1176 skb_push(skb, 3 + pn->aligned);
02a47617
RDC
1177 skb_reset_transport_header(skb);
1178 ph = pnp_hdr(skb);
1179 ph->utid = 0;
fea93ece
RDC
1180 if (pn->aligned) {
1181 ph->message_id = PNS_PIPE_ALIGNED_DATA;
1182 ph->data[0] = 0; /* padding */
1183 } else
1184 ph->message_id = PNS_PIPE_DATA;
02a47617 1185 ph->pipe_handle = pn->pipe_handle;
14ba8fae 1186 err = pn_skb_send(sk, skb, NULL);
e1a5964f
RDC
1187
1188 if (err && pn_flow_safe(pn->tx_fc))
1189 atomic_inc(&pn->tx_credits);
1190 return err;
1191
02a47617
RDC
1192}
1193
9641458d
RDC
1194static int pep_sendmsg(struct kiocb *iocb, struct sock *sk,
1195 struct msghdr *msg, size_t len)
1196{
1197 struct pep_sock *pn = pep_sk(sk);
b1704374 1198 struct sk_buff *skb;
9641458d
RDC
1199 long timeo;
1200 int flags = msg->msg_flags;
1201 int err, done;
1202
82ecbcb9
RDC
1203 if ((msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|
1204 MSG_CMSG_COMPAT)) ||
1205 !(msg->msg_flags & MSG_EOR))
9641458d
RDC
1206 return -EOPNOTSUPP;
1207
b1704374
RDC
1208 skb = sock_alloc_send_skb(sk, MAX_PNPIPE_HEADER + len,
1209 flags & MSG_DONTWAIT, &err);
1210 if (!skb)
02ac3268 1211 return err;
b1704374
RDC
1212
1213 skb_reserve(skb, MAX_PHONET_HEADER + 3);
1214 err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
1215 if (err < 0)
1216 goto outfree;
1217
9641458d
RDC
1218 lock_sock(sk);
1219 timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
1220 if ((1 << sk->sk_state) & (TCPF_LISTEN|TCPF_CLOSE)) {
1221 err = -ENOTCONN;
1222 goto out;
1223 }
1224 if (sk->sk_state != TCP_ESTABLISHED) {
1225 /* Wait until the pipe gets to enabled state */
1226disabled:
1227 err = sk_stream_wait_connect(sk, &timeo);
1228 if (err)
1229 goto out;
1230
1231 if (sk->sk_state == TCP_CLOSE_WAIT) {
1232 err = -ECONNRESET;
1233 goto out;
1234 }
1235 }
1236 BUG_ON(sk->sk_state != TCP_ESTABLISHED);
1237
1238 /* Wait until flow control allows TX */
be677730 1239 done = atomic_read(&pn->tx_credits);
9641458d
RDC
1240 while (!done) {
1241 DEFINE_WAIT(wait);
1242
1243 if (!timeo) {
1244 err = -EAGAIN;
1245 goto out;
1246 }
1247 if (signal_pending(current)) {
1248 err = sock_intr_errno(timeo);
1249 goto out;
1250 }
1251
43815482 1252 prepare_to_wait(sk_sleep(sk), &wait,
9641458d 1253 TASK_INTERRUPTIBLE);
be677730 1254 done = sk_wait_event(sk, &timeo, atomic_read(&pn->tx_credits));
43815482 1255 finish_wait(sk_sleep(sk), &wait);
9641458d
RDC
1256
1257 if (sk->sk_state != TCP_ESTABLISHED)
1258 goto disabled;
1259 }
1260
02a47617 1261 err = pipe_skb_send(sk, skb);
9641458d
RDC
1262 if (err >= 0)
1263 err = len; /* success! */
1264 skb = NULL;
1265out:
1266 release_sock(sk);
b1704374 1267outfree:
9641458d
RDC
1268 kfree_skb(skb);
1269 return err;
1270}
1271
02a47617
RDC
1272int pep_writeable(struct sock *sk)
1273{
1274 struct pep_sock *pn = pep_sk(sk);
1275
be677730 1276 return atomic_read(&pn->tx_credits);
02a47617
RDC
1277}
1278
1279int pep_write(struct sock *sk, struct sk_buff *skb)
1280{
1281 struct sk_buff *rskb, *fs;
1282 int flen = 0;
1283
fea93ece
RDC
1284 if (pep_sk(sk)->aligned)
1285 return pipe_skb_send(sk, skb);
1286
02a47617
RDC
1287 rskb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC);
1288 if (!rskb) {
1289 kfree_skb(skb);
1290 return -ENOMEM;
1291 }
1292 skb_shinfo(rskb)->frag_list = skb;
1293 rskb->len += skb->len;
1294 rskb->data_len += rskb->len;
1295 rskb->truesize += rskb->len;
1296
1297 /* Avoid nested fragments */
5c313e9a 1298 skb_walk_frags(skb, fs)
02a47617
RDC
1299 flen += fs->len;
1300 skb->next = skb_shinfo(skb)->frag_list;
5c313e9a 1301 skb_frag_list_init(skb);
02a47617
RDC
1302 skb->len -= flen;
1303 skb->data_len -= flen;
1304 skb->truesize -= flen;
1305
1306 skb_reserve(rskb, MAX_PHONET_HEADER + 3);
1307 return pipe_skb_send(sk, rskb);
1308}
1309
1310struct sk_buff *pep_read(struct sock *sk)
1311{
1312 struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue);
1313
1314 if (sk->sk_state == TCP_ESTABLISHED)
1315 pipe_grant_credits(sk);
1316 return skb;
1317}
1318
9641458d
RDC
1319static int pep_recvmsg(struct kiocb *iocb, struct sock *sk,
1320 struct msghdr *msg, size_t len, int noblock,
1321 int flags, int *addr_len)
1322{
1323 struct sk_buff *skb;
1324 int err;
1325
82ecbcb9
RDC
1326 if (flags & ~(MSG_OOB|MSG_PEEK|MSG_TRUNC|MSG_DONTWAIT|MSG_WAITALL|
1327 MSG_NOSIGNAL|MSG_CMSG_COMPAT))
1328 return -EOPNOTSUPP;
1329
9641458d
RDC
1330 if (unlikely(1 << sk->sk_state & (TCPF_LISTEN | TCPF_CLOSE)))
1331 return -ENOTCONN;
1332
c41bd97f
RDC
1333 if ((flags & MSG_OOB) || sock_flag(sk, SOCK_URGINLINE)) {
1334 /* Dequeue and acknowledge control request */
1335 struct pep_sock *pn = pep_sk(sk);
1336
82ecbcb9
RDC
1337 if (flags & MSG_PEEK)
1338 return -EOPNOTSUPP;
c41bd97f
RDC
1339 skb = skb_dequeue(&pn->ctrlreq_queue);
1340 if (skb) {
1341 pep_ctrlreq_error(sk, skb, PN_PIPE_NO_ERROR,
1342 GFP_KERNEL);
1343 msg->msg_flags |= MSG_OOB;
1344 goto copy;
1345 }
1346 if (flags & MSG_OOB)
1347 return -EINVAL;
1348 }
1349
9641458d
RDC
1350 skb = skb_recv_datagram(sk, flags, noblock, &err);
1351 lock_sock(sk);
1352 if (skb == NULL) {
1353 if (err == -ENOTCONN && sk->sk_state == TCP_CLOSE_WAIT)
1354 err = -ECONNRESET;
1355 release_sock(sk);
1356 return err;
1357 }
1358
1359 if (sk->sk_state == TCP_ESTABLISHED)
1360 pipe_grant_credits(sk);
1361 release_sock(sk);
c41bd97f 1362copy:
9641458d 1363 msg->msg_flags |= MSG_EOR;
9641458d
RDC
1364 if (skb->len > len)
1365 msg->msg_flags |= MSG_TRUNC;
1366 else
1367 len = skb->len;
1368
1369 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len);
1370 if (!err)
1371 err = (flags & MSG_TRUNC) ? skb->len : len;
1372
1373 skb_free_datagram(sk, skb);
1374 return err;
1375}
1376
1377static void pep_sock_unhash(struct sock *sk)
1378{
1379 struct pep_sock *pn = pep_sk(sk);
1380 struct sock *skparent = NULL;
1381
1382 lock_sock(sk);
b3d62553
KS
1383
1384#ifndef CONFIG_PHONET_PIPECTRLR
9641458d
RDC
1385 if ((1 << sk->sk_state) & ~(TCPF_CLOSE|TCPF_LISTEN)) {
1386 skparent = pn->listener;
9641458d
RDC
1387 release_sock(sk);
1388
9641458d 1389 pn = pep_sk(skparent);
7dfde179
RDC
1390 lock_sock(skparent);
1391 sk_del_node_init(sk);
1392 sk = skparent;
9641458d 1393 }
b3d62553 1394#endif
9641458d
RDC
1395 /* Unhash a listening sock only when it is closed
1396 * and all of its active connected pipes are closed. */
1397 if (hlist_empty(&pn->hlist))
1398 pn_sock_unhash(&pn->pn_sk.sk);
1399 release_sock(sk);
1400
1401 if (skparent)
1402 sock_put(skparent);
1403}
1404
1405static struct proto pep_proto = {
1406 .close = pep_sock_close,
1407 .accept = pep_sock_accept,
b3d62553
KS
1408#ifdef CONFIG_PHONET_PIPECTRLR
1409 .connect = pep_sock_connect,
1410#endif
9641458d
RDC
1411 .ioctl = pep_ioctl,
1412 .init = pep_init,
02a47617
RDC
1413 .setsockopt = pep_setsockopt,
1414 .getsockopt = pep_getsockopt,
9641458d
RDC
1415 .sendmsg = pep_sendmsg,
1416 .recvmsg = pep_recvmsg,
1417 .backlog_rcv = pep_do_rcv,
1418 .hash = pn_sock_hash,
1419 .unhash = pep_sock_unhash,
1420 .get_port = pn_sock_get_port,
1421 .obj_size = sizeof(struct pep_sock),
1422 .owner = THIS_MODULE,
1423 .name = "PNPIPE",
1424};
1425
1426static struct phonet_protocol pep_pn_proto = {
1427 .ops = &phonet_stream_ops,
1428 .prot = &pep_proto,
1429 .sock_type = SOCK_SEQPACKET,
1430};
1431
1432static int __init pep_register(void)
1433{
1434 return phonet_proto_register(PN_PROTO_PIPE, &pep_pn_proto);
1435}
1436
1437static void __exit pep_unregister(void)
1438{
1439 phonet_proto_unregister(PN_PROTO_PIPE, &pep_pn_proto);
1440}
1441
1442module_init(pep_register);
1443module_exit(pep_unregister);
1444MODULE_AUTHOR("Remi Denis-Courmont, Nokia");
1445MODULE_DESCRIPTION("Phonet pipe protocol");
1446MODULE_LICENSE("GPL");
1447MODULE_ALIAS_NET_PF_PROTO(PF_PHONET, PN_PROTO_PIPE);
This page took 0.314502 seconds and 5 git commands to generate.