This source file includes following definitions.
- sock_setsockopt
- sock_getsockopt
- sock_wmalloc
- sock_rmalloc
- sock_rspace
- sock_wspace
- sock_wfree
- sock_rfree
- sock_alloc_send_skb
- __release_sock
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 #include <linux/config.h>
82 #include <linux/errno.h>
83 #include <linux/types.h>
84 #include <linux/socket.h>
85 #include <linux/in.h>
86 #include <linux/kernel.h>
87 #include <linux/major.h>
88 #include <linux/sched.h>
89 #include <linux/timer.h>
90 #include <linux/string.h>
91 #include <linux/sockios.h>
92 #include <linux/net.h>
93 #include <linux/fcntl.h>
94 #include <linux/mm.h>
95 #include <linux/interrupt.h>
96
97 #include <asm/segment.h>
98 #include <asm/system.h>
99
100 #include <linux/inet.h>
101 #include <linux/netdevice.h>
102 #include <net/ip.h>
103 #include <net/protocol.h>
104 #include <net/arp.h>
105 #include <net/rarp.h>
106 #include <net/route.h>
107 #include <net/tcp.h>
108 #include <net/udp.h>
109 #include <linux/skbuff.h>
110 #include <net/sock.h>
111 #include <net/raw.h>
112 #include <net/icmp.h>
113
114 #define min(a,b) ((a)<(b)?(a):(b))
115
116
117
118
119
120
121 int sock_setsockopt(struct sock *sk, int level, int optname,
122 char *optval, int optlen)
123 {
124 int val;
125 int valbool;
126 int err;
127 struct linger ling;
128
129
130
131
132
133 #ifdef SO_DONTLINGER
134 switch(optname)
135 {
136 case SO_DONTLINGER:
137 sk->linger=0;
138 return 0;
139 }
140 #endif
141
142 if (optval == NULL)
143 return(-EINVAL);
144
145 err=verify_area(VERIFY_READ, optval, sizeof(int));
146 if(err)
147 return err;
148
149 val = get_user((int *)optval);
150 valbool = val?1:0;
151
152 switch(optname)
153 {
154 case SO_DEBUG:
155 if(val && !suser())
156 return(-EPERM);
157 sk->debug=valbool;
158 return 0;
159 case SO_REUSEADDR:
160 sk->reuse = valbool;
161 return(0);
162 case SO_TYPE:
163 case SO_ERROR:
164 return(-ENOPROTOOPT);
165 case SO_DONTROUTE:
166 sk->localroute=valbool;
167 return 0;
168 case SO_BROADCAST:
169 sk->broadcast=valbool;
170 return 0;
171 case SO_SNDBUF:
172 if(val > SK_WMEM_MAX*2)
173 val = SK_WMEM_MAX*2;
174 if(val < 256)
175 val = 256;
176 sk->sndbuf = val;
177 return 0;
178
179 case SO_RCVBUF:
180 if(val > SK_RMEM_MAX*2)
181 val = SK_RMEM_MAX*2;
182 if(val < 256)
183 val = 256;
184 sk->rcvbuf = val;
185 return(0);
186
187 case SO_KEEPALIVE:
188 sk->keepopen = valbool;
189 return(0);
190
191 case SO_OOBINLINE:
192 sk->urginline = valbool;
193 return(0);
194
195 case SO_NO_CHECK:
196 sk->no_check = valbool;
197 return(0);
198
199 case SO_PRIORITY:
200 if (val >= 0 && val < DEV_NUMBUFFS)
201 {
202 sk->priority = val;
203 }
204 else
205 {
206 return(-EINVAL);
207 }
208 return(0);
209
210
211 case SO_LINGER:
212 err=verify_area(VERIFY_READ,optval,sizeof(ling));
213 if(err)
214 return err;
215 memcpy_fromfs(&ling,optval,sizeof(ling));
216 if(ling.l_onoff==0)
217 sk->linger=0;
218 else
219 {
220 sk->lingertime=ling.l_linger;
221 sk->linger=1;
222 }
223 return 0;
224
225 case SO_BSDCOMPAT:
226 sk->bsdism = valbool;
227 return 0;
228
229 default:
230 return(-ENOPROTOOPT);
231 }
232 }
233
234
235 int sock_getsockopt(struct sock *sk, int level, int optname,
236 char *optval, int *optlen)
237 {
238 int val;
239 int err;
240 struct linger ling;
241
242 switch(optname)
243 {
244 case SO_DEBUG:
245 val = sk->debug;
246 break;
247
248 case SO_DONTROUTE:
249 val = sk->localroute;
250 break;
251
252 case SO_BROADCAST:
253 val= sk->broadcast;
254 break;
255
256 case SO_SNDBUF:
257 val=sk->sndbuf;
258 break;
259
260 case SO_RCVBUF:
261 val =sk->rcvbuf;
262 break;
263
264 case SO_REUSEADDR:
265 val = sk->reuse;
266 break;
267
268 case SO_KEEPALIVE:
269 val = sk->keepopen;
270 break;
271
272 case SO_TYPE:
273 val = sk->type;
274 break;
275
276 case SO_ERROR:
277 val = sock_error(sk);
278 if(val==0)
279 val=xchg(&sk->err_soft,0);
280 break;
281
282 case SO_OOBINLINE:
283 val = sk->urginline;
284 break;
285
286 case SO_NO_CHECK:
287 val = sk->no_check;
288 break;
289
290 case SO_PRIORITY:
291 val = sk->priority;
292 break;
293
294 case SO_LINGER:
295 err=verify_area(VERIFY_WRITE,optval,sizeof(ling));
296 if(err)
297 return err;
298 err=verify_area(VERIFY_WRITE,optlen,sizeof(int));
299 if(err)
300 return err;
301 put_fs_long(sizeof(ling),(unsigned long *)optlen);
302 ling.l_onoff=sk->linger;
303 ling.l_linger=sk->lingertime;
304 memcpy_tofs(optval,&ling,sizeof(ling));
305 return 0;
306
307 case SO_BSDCOMPAT:
308 val = sk->bsdism;
309 break;
310
311 default:
312 return(-ENOPROTOOPT);
313 }
314 err=verify_area(VERIFY_WRITE, optlen, sizeof(int));
315 if(err)
316 return err;
317 put_fs_long(sizeof(int),(unsigned long *) optlen);
318
319 err=verify_area(VERIFY_WRITE, optval, sizeof(int));
320 if(err)
321 return err;
322 put_fs_long(val,(unsigned long *)optval);
323
324 return(0);
325 }
326
327 struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, int priority)
328 {
329 if (sk) {
330 if (force || sk->wmem_alloc + size < sk->sndbuf) {
331 struct sk_buff * skb = alloc_skb(size, priority);
332 if (skb)
333 atomic_add(skb->truesize, &sk->wmem_alloc);
334 return skb;
335 }
336 return NULL;
337 }
338 return alloc_skb(size, priority);
339 }
340
341 struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force, int priority)
342 {
343 if (sk) {
344 if (force || sk->rmem_alloc + size < sk->rcvbuf) {
345 struct sk_buff *skb = alloc_skb(size, priority);
346 if (skb)
347 atomic_add(skb->truesize, &sk->rmem_alloc);
348 return skb;
349 }
350 return NULL;
351 }
352 return alloc_skb(size, priority);
353 }
354
355
356 unsigned long sock_rspace(struct sock *sk)
357 {
358 int amt;
359
360 if (sk != NULL)
361 {
362 if (sk->rmem_alloc >= sk->rcvbuf-2*MIN_WINDOW)
363 return(0);
364 amt = min((sk->rcvbuf-sk->rmem_alloc)/2-MIN_WINDOW, MAX_WINDOW);
365 if (amt < 0)
366 return(0);
367 return(amt);
368 }
369 return(0);
370 }
371
372
373 unsigned long sock_wspace(struct sock *sk)
374 {
375 if (sk != NULL)
376 {
377 if (sk->shutdown & SEND_SHUTDOWN)
378 return(0);
379 if (sk->wmem_alloc >= sk->sndbuf)
380 return(0);
381 return sk->sndbuf - sk->wmem_alloc;
382 }
383 return(0);
384 }
385
386
387 void sock_wfree(struct sock *sk, struct sk_buff *skb)
388 {
389 int s=skb->truesize;
390 #if CONFIG_SKB_CHECK
391 IS_SKB(skb);
392 #endif
393 kfree_skbmem(skb);
394 if (sk)
395 {
396 atomic_sub(s, &sk->wmem_alloc);
397
398 sk->write_space(sk);
399 }
400 }
401
402
403 void sock_rfree(struct sock *sk, struct sk_buff *skb)
404 {
405 int s=skb->truesize;
406 #if CONFIG_SKB_CHECK
407 IS_SKB(skb);
408 #endif
409 kfree_skbmem(skb);
410 if (sk)
411 {
412 atomic_sub(s, &sk->rmem_alloc);
413 }
414 }
415
416
417
418
419
420 struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, unsigned long fallback, int noblock, int *errcode)
421 {
422 struct sk_buff *skb;
423 int err;
424
425 do
426 {
427 if(sk->err!=0)
428 {
429 cli();
430 err= -sk->err;
431 sk->err=0;
432 sti();
433 *errcode=err;
434 return NULL;
435 }
436
437 if(sk->shutdown&SEND_SHUTDOWN)
438 {
439 *errcode=-EPIPE;
440 return NULL;
441 }
442
443 if(!fallback)
444 skb = sock_wmalloc(sk, size, 0, sk->allocation);
445 else
446 {
447
448
449 skb = sock_wmalloc(sk, size, 0 , GFP_BUFFER);
450 if(!skb)
451 skb=sock_wmalloc(sk, fallback, 0, GFP_KERNEL);
452 }
453
454
455
456
457
458 if(skb==NULL)
459 {
460 unsigned long tmp;
461
462 sk->socket->flags |= SO_NOSPACE;
463 if(noblock)
464 {
465 *errcode=-EAGAIN;
466 return NULL;
467 }
468 if(sk->shutdown&SEND_SHUTDOWN)
469 {
470 *errcode=-EPIPE;
471 return NULL;
472 }
473 tmp = sk->wmem_alloc;
474 cli();
475 if(sk->shutdown&SEND_SHUTDOWN)
476 {
477 sti();
478 *errcode=-EPIPE;
479 return NULL;
480 }
481
482 #if 1
483 if( tmp <= sk->wmem_alloc)
484 #else
485
486
487
488
489
490
491
492
493 if (sk->wmem_alloc + size >= sk->sndbuf)
494 #endif
495 {
496 sk->socket->flags &= ~SO_NOSPACE;
497 interruptible_sleep_on(sk->sleep);
498 if (current->signal & ~current->blocked)
499 {
500 sti();
501 *errcode = -ERESTARTSYS;
502 return NULL;
503 }
504 }
505 sti();
506 }
507 }
508 while(skb==NULL);
509
510 return skb;
511 }
512
513
514 void __release_sock(struct sock *sk)
515 {
516 #ifdef CONFIG_INET
517 if (!sk->prot || !sk->prot->rcv)
518 return;
519
520
521 start_bh_atomic();
522 while (!skb_queue_empty(&sk->back_log)) {
523 struct sk_buff * skb = sk->back_log.next;
524 __skb_unlink(skb, &sk->back_log);
525 sk->prot->rcv(skb, skb->dev, (struct options*)skb->proto_priv,
526 skb->saddr, skb->len, skb->daddr, 1,
527
528 (struct inet_protocol *)sk->pair);
529 }
530 end_bh_atomic();
531 #endif
532 }