1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include <linux/module.h>
37#include <linux/types.h>
38#include <linux/kernel.h>
39#include <asm/uaccess.h>
40#include <asm/system.h>
41#include <linux/mm.h>
42#include <linux/interrupt.h>
43#include <linux/errno.h>
44#include <linux/sched.h>
45#include <linux/inet.h>
46#include <linux/netdevice.h>
47#include <linux/rtnetlink.h>
48#include <linux/poll.h>
49#include <linux/highmem.h>
50#include <linux/spinlock.h>
51
52#include <net/protocol.h>
53#include <linux/skbuff.h>
54
55#include <net/checksum.h>
56#include <net/sock.h>
57#include <net/tcp_states.h>
58
59
60
61
62static inline int connection_based(struct sock *sk)
63{
64 return sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM;
65}
66
67static int receiver_wake_function(wait_queue_t *wait, unsigned mode, int sync,
68 void *key)
69{
70 unsigned long bits = (unsigned long)key;
71
72
73
74
75 if (bits && !(bits & (POLLIN | POLLERR)))
76 return 0;
77 return autoremove_wake_function(wait, mode, sync, key);
78}
79
80
81
82static int wait_for_packet(struct sock *sk, int *err, long *timeo_p)
83{
84 int error;
85 DEFINE_WAIT_FUNC(wait, receiver_wake_function);
86
87 prepare_to_wait_exclusive(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
88
89
90 error = sock_error(sk);
91 if (error)
92 goto out_err;
93
94 if (!skb_queue_empty(&sk->sk_receive_queue))
95 goto out;
96
97
98 if (sk->sk_shutdown & RCV_SHUTDOWN)
99 goto out_noerr;
100
101
102
103
104 error = -ENOTCONN;
105 if (connection_based(sk) &&
106 !(sk->sk_state == TCP_ESTABLISHED || sk->sk_state == TCP_LISTEN))
107 goto out_err;
108
109
110 if (signal_pending(current))
111 goto interrupted;
112
113 error = 0;
114 *timeo_p = schedule_timeout(*timeo_p);
115out:
116 finish_wait(sk->sk_sleep, &wait);
117 return error;
118interrupted:
119 error = sock_intr_errno(*timeo_p);
120out_err:
121 *err = error;
122 goto out;
123out_noerr:
124 *err = 0;
125 error = 1;
126 goto out;
127}
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags,
159 int *peeked, int *err)
160{
161 struct sk_buff *skb;
162 long timeo;
163
164
165
166 int error = sock_error(sk);
167
168 if (error)
169 goto no_packet;
170
171 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
172
173 do {
174
175
176
177
178
179
180 unsigned long cpu_flags;
181
182 spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags);
183 skb = skb_peek(&sk->sk_receive_queue);
184 if (skb) {
185 *peeked = skb->peeked;
186 if (flags & MSG_PEEK) {
187 skb->peeked = 1;
188 atomic_inc(&skb->users);
189 } else
190 __skb_unlink(skb, &sk->sk_receive_queue);
191 }
192 spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags);
193
194 if (skb)
195 return skb;
196
197
198 error = -EAGAIN;
199 if (!timeo)
200 goto no_packet;
201
202 } while (!wait_for_packet(sk, err, &timeo));
203
204 return NULL;
205
206no_packet:
207 *err = error;
208 return NULL;
209}
210EXPORT_SYMBOL(__skb_recv_datagram);
211
212struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
213 int noblock, int *err)
214{
215 int peeked;
216
217 return __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
218 &peeked, err);
219}
220
221void skb_free_datagram(struct sock *sk, struct sk_buff *skb)
222{
223 consume_skb(skb);
224 sk_mem_reclaim_partial(sk);
225}
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags)
249{
250 int err = 0;
251
252 if (flags & MSG_PEEK) {
253 err = -ENOENT;
254 spin_lock_bh(&sk->sk_receive_queue.lock);
255 if (skb == skb_peek(&sk->sk_receive_queue)) {
256 __skb_unlink(skb, &sk->sk_receive_queue);
257 atomic_dec(&skb->users);
258 err = 0;
259 }
260 spin_unlock_bh(&sk->sk_receive_queue.lock);
261 }
262
263 skb_free_datagram(sk, skb);
264 return err;
265}
266
267EXPORT_SYMBOL(skb_kill_datagram);
268
269
270
271
272
273
274
275
276
277
278int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset,
279 struct iovec *to, int len)
280{
281 int start = skb_headlen(skb);
282 int i, copy = start - offset;
283
284
285 if (copy > 0) {
286 if (copy > len)
287 copy = len;
288 if (memcpy_toiovec(to, skb->data + offset, copy))
289 goto fault;
290 if ((len -= copy) == 0)
291 return 0;
292 offset += copy;
293 }
294
295
296 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
297 int end;
298
299 WARN_ON(start > offset + len);
300
301 end = start + skb_shinfo(skb)->frags[i].size;
302 if ((copy = end - offset) > 0) {
303 int err;
304 u8 *vaddr;
305 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
306 struct page *page = frag->page;
307
308 if (copy > len)
309 copy = len;
310 vaddr = kmap(page);
311 err = memcpy_toiovec(to, vaddr + frag->page_offset +
312 offset - start, copy);
313 kunmap(page);
314 if (err)
315 goto fault;
316 if (!(len -= copy))
317 return 0;
318 offset += copy;
319 }
320 start = end;
321 }
322
323 if (skb_shinfo(skb)->frag_list) {
324 struct sk_buff *list = skb_shinfo(skb)->frag_list;
325
326 for (; list; list = list->next) {
327 int end;
328
329 WARN_ON(start > offset + len);
330
331 end = start + list->len;
332 if ((copy = end - offset) > 0) {
333 if (copy > len)
334 copy = len;
335 if (skb_copy_datagram_iovec(list,
336 offset - start,
337 to, copy))
338 goto fault;
339 if ((len -= copy) == 0)
340 return 0;
341 offset += copy;
342 }
343 start = end;
344 }
345 }
346 if (!len)
347 return 0;
348
349fault:
350 return -EFAULT;
351}
352
353
354
355
356
357
358
359
360
361
362
363int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
364 struct iovec *from, int len)
365{
366 int start = skb_headlen(skb);
367 int i, copy = start - offset;
368
369
370 if (copy > 0) {
371 if (copy > len)
372 copy = len;
373 if (memcpy_fromiovec(skb->data + offset, from, copy))
374 goto fault;
375 if ((len -= copy) == 0)
376 return 0;
377 offset += copy;
378 }
379
380
381 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
382 int end;
383
384 WARN_ON(start > offset + len);
385
386 end = start + skb_shinfo(skb)->frags[i].size;
387 if ((copy = end - offset) > 0) {
388 int err;
389 u8 *vaddr;
390 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
391 struct page *page = frag->page;
392
393 if (copy > len)
394 copy = len;
395 vaddr = kmap(page);
396 err = memcpy_fromiovec(vaddr + frag->page_offset +
397 offset - start, from, copy);
398 kunmap(page);
399 if (err)
400 goto fault;
401
402 if (!(len -= copy))
403 return 0;
404 offset += copy;
405 }
406 start = end;
407 }
408
409 if (skb_shinfo(skb)->frag_list) {
410 struct sk_buff *list = skb_shinfo(skb)->frag_list;
411
412 for (; list; list = list->next) {
413 int end;
414
415 WARN_ON(start > offset + len);
416
417 end = start + list->len;
418 if ((copy = end - offset) > 0) {
419 if (copy > len)
420 copy = len;
421 if (skb_copy_datagram_from_iovec(list,
422 offset - start,
423 from, copy))
424 goto fault;
425 if ((len -= copy) == 0)
426 return 0;
427 offset += copy;
428 }
429 start = end;
430 }
431 }
432 if (!len)
433 return 0;
434
435fault:
436 return -EFAULT;
437}
438EXPORT_SYMBOL(skb_copy_datagram_from_iovec);
439
440static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
441 u8 __user *to, int len,
442 __wsum *csump)
443{
444 int start = skb_headlen(skb);
445 int pos = 0;
446 int i, copy = start - offset;
447
448
449 if (copy > 0) {
450 int err = 0;
451 if (copy > len)
452 copy = len;
453 *csump = csum_and_copy_to_user(skb->data + offset, to, copy,
454 *csump, &err);
455 if (err)
456 goto fault;
457 if ((len -= copy) == 0)
458 return 0;
459 offset += copy;
460 to += copy;
461 pos = copy;
462 }
463
464 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
465 int end;
466
467 WARN_ON(start > offset + len);
468
469 end = start + skb_shinfo(skb)->frags[i].size;
470 if ((copy = end - offset) > 0) {
471 __wsum csum2;
472 int err = 0;
473 u8 *vaddr;
474 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
475 struct page *page = frag->page;
476
477 if (copy > len)
478 copy = len;
479 vaddr = kmap(page);
480 csum2 = csum_and_copy_to_user(vaddr +
481 frag->page_offset +
482 offset - start,
483 to, copy, 0, &err);
484 kunmap(page);
485 if (err)
486 goto fault;
487 *csump = csum_block_add(*csump, csum2, pos);
488 if (!(len -= copy))
489 return 0;
490 offset += copy;
491 to += copy;
492 pos += copy;
493 }
494 start = end;
495 }
496
497 if (skb_shinfo(skb)->frag_list) {
498 struct sk_buff *list = skb_shinfo(skb)->frag_list;
499
500 for (; list; list=list->next) {
501 int end;
502
503 WARN_ON(start > offset + len);
504
505 end = start + list->len;
506 if ((copy = end - offset) > 0) {
507 __wsum csum2 = 0;
508 if (copy > len)
509 copy = len;
510 if (skb_copy_and_csum_datagram(list,
511 offset - start,
512 to, copy,
513 &csum2))
514 goto fault;
515 *csump = csum_block_add(*csump, csum2, pos);
516 if ((len -= copy) == 0)
517 return 0;
518 offset += copy;
519 to += copy;
520 pos += copy;
521 }
522 start = end;
523 }
524 }
525 if (!len)
526 return 0;
527
528fault:
529 return -EFAULT;
530}
531
532__sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len)
533{
534 __sum16 sum;
535
536 sum = csum_fold(skb_checksum(skb, 0, len, skb->csum));
537 if (likely(!sum)) {
538 if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE))
539 netdev_rx_csum_fault(skb->dev);
540 skb->ip_summed = CHECKSUM_UNNECESSARY;
541 }
542 return sum;
543}
544EXPORT_SYMBOL(__skb_checksum_complete_head);
545
546__sum16 __skb_checksum_complete(struct sk_buff *skb)
547{
548 return __skb_checksum_complete_head(skb, skb->len);
549}
550EXPORT_SYMBOL(__skb_checksum_complete);
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
566 int hlen, struct iovec *iov)
567{
568 __wsum csum;
569 int chunk = skb->len - hlen;
570
571 if (!chunk)
572 return 0;
573
574
575
576
577 while (!iov->iov_len)
578 iov++;
579
580 if (iov->iov_len < chunk) {
581 if (__skb_checksum_complete(skb))
582 goto csum_error;
583 if (skb_copy_datagram_iovec(skb, hlen, iov, chunk))
584 goto fault;
585 } else {
586 csum = csum_partial(skb->data, hlen, skb->csum);
587 if (skb_copy_and_csum_datagram(skb, hlen, iov->iov_base,
588 chunk, &csum))
589 goto fault;
590 if (csum_fold(csum))
591 goto csum_error;
592 if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE))
593 netdev_rx_csum_fault(skb->dev);
594 iov->iov_len -= chunk;
595 iov->iov_base += chunk;
596 }
597 return 0;
598csum_error:
599 return -EINVAL;
600fault:
601 return -EFAULT;
602}
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618unsigned int datagram_poll(struct file *file, struct socket *sock,
619 poll_table *wait)
620{
621 struct sock *sk = sock->sk;
622 unsigned int mask;
623
624 poll_wait(file, sk->sk_sleep, wait);
625 mask = 0;
626
627
628 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
629 mask |= POLLERR;
630 if (sk->sk_shutdown & RCV_SHUTDOWN)
631 mask |= POLLRDHUP;
632 if (sk->sk_shutdown == SHUTDOWN_MASK)
633 mask |= POLLHUP;
634
635
636 if (!skb_queue_empty(&sk->sk_receive_queue) ||
637 (sk->sk_shutdown & RCV_SHUTDOWN))
638 mask |= POLLIN | POLLRDNORM;
639
640
641 if (connection_based(sk)) {
642 if (sk->sk_state == TCP_CLOSE)
643 mask |= POLLHUP;
644
645 if (sk->sk_state == TCP_SYN_SENT)
646 return mask;
647 }
648
649
650 if (sock_writeable(sk))
651 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
652 else
653 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
654
655 return mask;
656}
657
658EXPORT_SYMBOL(datagram_poll);
659EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec);
660EXPORT_SYMBOL(skb_copy_datagram_iovec);
661EXPORT_SYMBOL(skb_free_datagram);
662EXPORT_SYMBOL(skb_recv_datagram);
663