]> git.ipfire.org Git - people/ms/strongswan.git/blob - linux/net/ipsec/pfkey_v2.c
- import of strongswan-2.7.0
[people/ms/strongswan.git] / linux / net / ipsec / pfkey_v2.c
1 /*
2 * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F
3 * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 *
15 * RCSID $Id: pfkey_v2.c,v 1.4 2004/09/29 22:27:41 as Exp $
16 */
17
18 /*
19 * Template from /usr/src/linux-2.0.36/net/unix/af_unix.c.
20 * Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c.
21 */
22
23 #define __NO_VERSION__
24 #include <linux/module.h>
25 #include <linux/version.h>
26 #include <linux/config.h>
27 #include <linux/kernel.h>
28
29 #include "freeswan/ipsec_param.h"
30
31 #include <linux/major.h>
32 #include <linux/signal.h>
33 #include <linux/sched.h>
34 #include <linux/errno.h>
35 #include <linux/string.h>
36 #include <linux/stat.h>
37 #include <linux/socket.h>
38 #include <linux/un.h>
39 #include <linux/fcntl.h>
40 #include <linux/termios.h>
41 #include <linux/socket.h>
42 #include <linux/sockios.h>
43 #include <linux/net.h> /* struct socket */
44 #include <linux/in.h>
45 #include <linux/fs.h>
46 #ifdef MALLOC_SLAB
47 # include <linux/slab.h> /* kmalloc() */
48 #else /* MALLOC_SLAB */
49 # include <linux/malloc.h> /* kmalloc() */
50 #endif /* MALLOC_SLAB */
51 #include <asm/segment.h>
52 #include <linux/skbuff.h>
53 #include <linux/netdevice.h>
54 #include <net/sock.h> /* struct sock */
55 /* #include <net/tcp.h> */
56 #include <net/af_unix.h>
57 #ifdef CONFIG_PROC_FS
58 # include <linux/proc_fs.h>
59 #endif /* CONFIG_PROC_FS */
60
61 #include <linux/types.h>
62
63 #include <freeswan.h>
64 #ifdef NET_21
65 # include <asm/uaccess.h>
66 # include <linux/in6.h>
67 #endif /* NET_21 */
68
69 #include "freeswan/radij.h"
70 #include "freeswan/ipsec_encap.h"
71 #include "freeswan/ipsec_sa.h"
72
73 #include <pfkeyv2.h>
74 #include <pfkey.h>
75
76 #include "freeswan/ipsec_proto.h"
77
78 #ifdef CONFIG_IPSEC_DEBUG
79 int debug_pfkey = 0;
80 extern int sysctl_ipsec_debug_verbose;
81 #endif /* CONFIG_IPSEC_DEBUG */
82
83 #define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
84
85 #ifndef SOCKOPS_WRAPPED
86 #define SOCKOPS_WRAPPED(name) name
87 #endif /* SOCKOPS_WRAPPED */
88
89 extern struct proto_ops pfkey_ops;
90 struct sock *pfkey_sock_list = NULL;
91 struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
92
93 struct socket_list *pfkey_open_sockets = NULL;
94 struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
95
96 int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **);
97
98 int
99 pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets)
100 {
101 struct socket_list *socket_listp,*prev;
102
103 if(!socketp) {
104 KLIPS_PRINT(debug_pfkey,
105 "klips_debug:pfkey_list_remove_socket: "
106 "NULL socketp handed in, failed.\n");
107 return -EINVAL;
108 }
109
110 if(!sockets) {
111 KLIPS_PRINT(debug_pfkey,
112 "klips_debug:pfkey_list_remove_socket: "
113 "NULL sockets list handed in, failed.\n");
114 return -EINVAL;
115 }
116
117 socket_listp = *sockets;
118 prev = NULL;
119
120 KLIPS_PRINT(debug_pfkey,
121 "klips_debug:pfkey_list_remove_socket: "
122 "removing sock=0p%p\n",
123 socketp);
124
125 while(socket_listp != NULL) {
126 if(socket_listp->socketp == socketp) {
127 if(prev != NULL) {
128 prev->next = socket_listp->next;
129 } else {
130 *sockets = socket_listp->next;
131 }
132
133 kfree((void*)socket_listp);
134
135 break;
136 }
137 prev = socket_listp;
138 socket_listp = socket_listp->next;
139 }
140
141 return 0;
142 }
143
144 int
145 pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets)
146 {
147 struct socket_list *socket_listp;
148
149 if(!socketp) {
150 KLIPS_PRINT(debug_pfkey,
151 "klips_debug:pfkey_list_insert_socket: "
152 "NULL socketp handed in, failed.\n");
153 return -EINVAL;
154 }
155
156 if(!sockets) {
157 KLIPS_PRINT(debug_pfkey,
158 "klips_debug:pfkey_list_insert_socket: "
159 "NULL sockets list handed in, failed.\n");
160 return -EINVAL;
161 }
162
163 KLIPS_PRINT(debug_pfkey,
164 "klips_debug:pfkey_list_insert_socket: "
165 "allocating %lu bytes for socketp=0p%p\n",
166 (unsigned long) sizeof(struct socket_list),
167 socketp);
168
169 if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) {
170 KLIPS_PRINT(debug_pfkey,
171 "klips_debug:pfkey_list_insert_socket: "
172 "memory allocation error.\n");
173 return -ENOMEM;
174 }
175
176 socket_listp->socketp = socketp;
177 socket_listp->next = *sockets;
178 *sockets = socket_listp;
179
180 return 0;
181 }
182
183 int
184 pfkey_list_remove_supported(struct supported *supported, struct supported_list **supported_list)
185 {
186 struct supported_list *supported_listp = *supported_list, *prev = NULL;
187
188 if(!supported) {
189 KLIPS_PRINT(debug_pfkey,
190 "klips_debug:pfkey_list_remove_supported: "
191 "NULL supported handed in, failed.\n");
192 return -EINVAL;
193 }
194
195 if(!supported_list) {
196 KLIPS_PRINT(debug_pfkey,
197 "klips_debug:pfkey_list_remove_supported: "
198 "NULL supported_list handed in, failed.\n");
199 return -EINVAL;
200 }
201
202 KLIPS_PRINT(debug_pfkey,
203 "klips_debug:pfkey_list_remove_supported: "
204 "removing supported=0p%p\n",
205 supported);
206
207 while(supported_listp != NULL) {
208 if(supported_listp->supportedp == supported) {
209 if(prev != NULL) {
210 prev->next = supported_listp->next;
211 } else {
212 *supported_list = supported_listp->next;
213 }
214
215 kfree((void*)supported_listp);
216
217 break;
218 }
219 prev = supported_listp;
220 supported_listp = supported_listp->next;
221 }
222
223 return 0;
224 }
225
226 int
227 pfkey_list_insert_supported(struct supported *supported, struct supported_list **supported_list)
228 {
229 struct supported_list *supported_listp;
230
231 if(!supported) {
232 KLIPS_PRINT(debug_pfkey,
233 "klips_debug:pfkey_list_insert_supported: "
234 "NULL supported handed in, failed.\n");
235 return -EINVAL;
236 }
237
238 if(!supported_list) {
239 KLIPS_PRINT(debug_pfkey,
240 "klips_debug:pfkey_list_insert_supported: "
241 "NULL supported_list handed in, failed.\n");
242 return -EINVAL;
243 }
244
245 KLIPS_PRINT(debug_pfkey,
246 "klips_debug:pfkey_list_insert_supported: "
247 "allocating %lu bytes for incoming, supported=0p%p, supported_list=0p%p\n",
248 (unsigned long) sizeof(struct supported_list),
249 supported,
250 supported_list);
251
252 supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL);
253 if(supported_listp == NULL) {
254 KLIPS_PRINT(debug_pfkey,
255 "klips_debug:pfkey_list_insert_supported: "
256 "memory allocation error.\n");
257 return -ENOMEM;
258 }
259
260 supported_listp->supportedp = supported;
261 supported_listp->next = *supported_list;
262 *supported_list = supported_listp;
263 KLIPS_PRINT(debug_pfkey,
264 "klips_debug:pfkey_list_insert_supported: "
265 "outgoing, supported=0p%p, supported_list=0p%p\n",
266 supported,
267 supported_list);
268
269 return 0;
270 }
271
272 #ifndef NET_21
273 DEBUG_NO_STATIC void
274 pfkey_state_change(struct sock *sk)
275 {
276 KLIPS_PRINT(debug_pfkey,
277 "klips_debug:pfkey_state_change: .\n");
278 if(!sk->dead) {
279 wake_up_interruptible(sk->sleep);
280 }
281 }
282 #endif /* !NET_21 */
283
284 #ifndef NET_21
285 DEBUG_NO_STATIC void
286 pfkey_data_ready(struct sock *sk, int len)
287 {
288 KLIPS_PRINT(debug_pfkey,
289 "klips_debug:pfkey_data_ready: "
290 "sk=0p%p len=%d\n",
291 sk,
292 len);
293 if(!sk->dead) {
294 wake_up_interruptible(sk->sleep);
295 sock_wake_async(sk->socket, 1);
296 }
297 }
298
299 DEBUG_NO_STATIC void
300 pfkey_write_space(struct sock *sk)
301 {
302 KLIPS_PRINT(debug_pfkey,
303 "klips_debug:pfkey_write_space: .\n");
304 if(!sk->dead) {
305 wake_up_interruptible(sk->sleep);
306 sock_wake_async(sk->socket, 2);
307 }
308 }
309 #endif /* !NET_21 */
310
311 DEBUG_NO_STATIC void
312 pfkey_insert_socket(struct sock *sk)
313 {
314 KLIPS_PRINT(debug_pfkey,
315 "klips_debug:pfkey_insert_socket: "
316 "sk=0p%p\n",
317 sk);
318 cli();
319 sk->next=pfkey_sock_list;
320 pfkey_sock_list=sk;
321 sti();
322 }
323
324 DEBUG_NO_STATIC void
325 pfkey_remove_socket(struct sock *sk)
326 {
327 struct sock **s;
328
329 KLIPS_PRINT(debug_pfkey,
330 "klips_debug:pfkey_remove_socket: .\n");
331 cli();
332 s=&pfkey_sock_list;
333
334 while(*s!=NULL) {
335 if(*s==sk) {
336 *s=sk->next;
337 sk->next=NULL;
338 sti();
339 KLIPS_PRINT(debug_pfkey,
340 "klips_debug:pfkey_remove_socket: "
341 "succeeded.\n");
342 return;
343 }
344 s=&((*s)->next);
345 }
346 sti();
347 KLIPS_PRINT(debug_pfkey,
348 "klips_debug:pfkey_remove_socket: "
349 "not found.\n");
350 return;
351 }
352
353 DEBUG_NO_STATIC void
354 pfkey_destroy_socket(struct sock *sk)
355 {
356 struct sk_buff *skb;
357
358 KLIPS_PRINT(debug_pfkey,
359 "klips_debug:pfkey_destroy_socket: .\n");
360 pfkey_remove_socket(sk);
361 KLIPS_PRINT(debug_pfkey,
362 "klips_debug:pfkey_destroy_socket: "
363 "pfkey_remove_socket called.\n");
364
365 KLIPS_PRINT(debug_pfkey,
366 "klips_debug:pfkey_destroy_socket: "
367 "sk(0p%p)->(&0p%p)receive_queue.{next=0p%p,prev=0p%p}.\n",
368 sk,
369 &(sk->receive_queue),
370 sk->receive_queue.next,
371 sk->receive_queue.prev);
372 while(sk && ((skb=skb_dequeue(&(sk->receive_queue)))!=NULL)) {
373 #ifdef NET_21
374 #ifdef CONFIG_IPSEC_DEBUG
375 if(debug_pfkey && sysctl_ipsec_debug_verbose) {
376 KLIPS_PRINT(debug_pfkey,
377 "klips_debug:pfkey_destroy_socket: "
378 "skb=0p%p dequeued.\n", skb);
379 printk(KERN_INFO "klips_debug:pfkey_destroy_socket: "
380 "pfkey_skb contents:");
381 printk(" next:0p%p", skb->next);
382 printk(" prev:0p%p", skb->prev);
383 printk(" list:0p%p", skb->list);
384 printk(" sk:0p%p", skb->sk);
385 printk(" stamp:%ld.%ld", skb->stamp.tv_sec, skb->stamp.tv_usec);
386 printk(" dev:0p%p", skb->dev);
387 if(skb->dev) {
388 if(skb->dev->name) {
389 printk(" dev->name:%s", skb->dev->name);
390 } else {
391 printk(" dev->name:NULL?");
392 }
393 } else {
394 printk(" dev:NULL");
395 }
396 printk(" h:0p%p", skb->h.raw);
397 printk(" nh:0p%p", skb->nh.raw);
398 printk(" mac:0p%p", skb->mac.raw);
399 printk(" dst:0p%p", skb->dst);
400 if(sysctl_ipsec_debug_verbose) {
401 int i;
402
403 printk(" cb");
404 for(i=0; i<48; i++) {
405 printk(":%2x", skb->cb[i]);
406 }
407 }
408 printk(" len:%d", skb->len);
409 printk(" csum:%d", skb->csum);
410 #ifndef NETDEV_23
411 printk(" used:%d", skb->used);
412 printk(" is_clone:%d", skb->is_clone);
413 #endif /* NETDEV_23 */
414 printk(" cloned:%d", skb->cloned);
415 printk(" pkt_type:%d", skb->pkt_type);
416 printk(" ip_summed:%d", skb->ip_summed);
417 printk(" priority:%d", skb->priority);
418 printk(" protocol:%d", skb->protocol);
419 printk(" security:%d", skb->security);
420 printk(" truesize:%d", skb->truesize);
421 printk(" head:0p%p", skb->head);
422 printk(" data:0p%p", skb->data);
423 printk(" tail:0p%p", skb->tail);
424 printk(" end:0p%p", skb->end);
425 if(sysctl_ipsec_debug_verbose) {
426 unsigned char* i;
427 printk(" data");
428 for(i = skb->head; i < skb->end; i++) {
429 printk(":%2x", (unsigned char)(*(i)));
430 }
431 }
432 printk(" destructor:0p%p", skb->destructor);
433 printk("\n");
434 }
435 #endif /* CONFIG_IPSEC_DEBUG */
436 #endif /* NET_21 */
437 KLIPS_PRINT(debug_pfkey,
438 "klips_debug:pfkey_destroy_socket: "
439 "skb=0p%p freed.\n",
440 skb);
441 ipsec_kfree_skb(skb);
442 }
443
444 sk->dead = 1;
445 sk_free(sk);
446
447 KLIPS_PRINT(debug_pfkey,
448 "klips_debug:pfkey_destroy_socket: destroyed.\n");
449 }
450
451 int
452 pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg)
453 {
454 int error = 0;
455 struct sk_buff * skb = NULL;
456 struct sock *sk;
457
458 if(sock == NULL) {
459 KLIPS_PRINT(debug_pfkey,
460 "klips_debug:pfkey_upmsg: "
461 "NULL socket passed in.\n");
462 return -EINVAL;
463 }
464
465 if(pfkey_msg == NULL) {
466 KLIPS_PRINT(debug_pfkey,
467 "klips_debug:pfkey_upmsg: "
468 "NULL pfkey_msg passed in.\n");
469 return -EINVAL;
470 }
471
472 #ifdef NET_21
473 sk = sock->sk;
474 #else /* NET_21 */
475 sk = sock->data;
476 #endif /* NET_21 */
477
478 if(sk == NULL) {
479 KLIPS_PRINT(debug_pfkey,
480 "klips_debug:pfkey_upmsg: "
481 "NULL sock passed in.\n");
482 return -EINVAL;
483 }
484
485 KLIPS_PRINT(debug_pfkey,
486 "klips_debug:pfkey_upmsg: "
487 "allocating %d bytes...\n",
488 (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN));
489 if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) {
490 KLIPS_PRINT(debug_pfkey,
491 "klips_debug:pfkey_upmsg: "
492 "no buffers left to send up a message.\n");
493 return -ENOBUFS;
494 }
495 KLIPS_PRINT(debug_pfkey,
496 "klips_debug:pfkey_upmsg: "
497 "...allocated at 0p%p.\n",
498 skb);
499
500 skb->dev = NULL;
501
502 if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
503 printk(KERN_WARNING "klips_error:pfkey_upmsg: "
504 "tried to skb_put %ld, %d available. This should never happen, please report.\n",
505 (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN,
506 skb_tailroom(skb));
507 ipsec_kfree_skb(skb);
508 return -ENOBUFS;
509 }
510 skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
511 memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
512
513 #ifndef NET_21
514 skb->free = 1;
515 #endif /* !NET_21 */
516
517 if((error = sock_queue_rcv_skb(sk, skb)) < 0) {
518 skb->sk=NULL;
519 KLIPS_PRINT(debug_pfkey,
520 "klips_debug:pfkey_upmsg: "
521 "error=%d calling sock_queue_rcv_skb with skb=0p%p.\n",
522 error,
523 skb);
524 ipsec_kfree_skb(skb);
525 return error;
526 }
527 return error;
528 }
529
530 DEBUG_NO_STATIC int
531 pfkey_create(struct socket *sock, int protocol)
532 {
533 struct sock *sk;
534
535 if(sock == NULL) {
536 KLIPS_PRINT(debug_pfkey,
537 "klips_debug:pfkey_create: "
538 "socket NULL.\n");
539 return -EINVAL;
540 }
541
542 KLIPS_PRINT(debug_pfkey,
543 "klips_debug:pfkey_create: "
544 "sock=0p%p type:%d state:%d flags:%ld protocol:%d\n",
545 sock,
546 sock->type,
547 (unsigned int)(sock->state),
548 sock->flags, protocol);
549
550 if(sock->type != SOCK_RAW) {
551 KLIPS_PRINT(debug_pfkey,
552 "klips_debug:pfkey_create: "
553 "only SOCK_RAW supported.\n");
554 return -ESOCKTNOSUPPORT;
555 }
556
557 if(protocol != PF_KEY_V2) {
558 KLIPS_PRINT(debug_pfkey,
559 "klips_debug:pfkey_create: "
560 "protocol not PF_KEY_V2.\n");
561 return -EPROTONOSUPPORT;
562 }
563
564 if((current->uid != 0)) {
565 KLIPS_PRINT(debug_pfkey,
566 "klips_debug:pfkey_create: "
567 "must be root to open pfkey sockets.\n");
568 return -EACCES;
569 }
570
571 #ifdef NET_21
572 sock->state = SS_UNCONNECTED;
573 #endif /* NET_21 */
574 MOD_INC_USE_COUNT;
575 #ifdef NET_21
576 if((sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1)) == NULL)
577 #else /* NET_21 */
578 if((sk=(struct sock *)sk_alloc(GFP_KERNEL)) == NULL)
579 #endif /* NET_21 */
580 {
581 KLIPS_PRINT(debug_pfkey,
582 "klips_debug:pfkey_create: "
583 "Out of memory trying to allocate.\n");
584 MOD_DEC_USE_COUNT;
585 return -ENOMEM;
586 }
587
588 #ifndef NET_21
589 memset(sk, 0, sizeof(*sk));
590 #endif /* !NET_21 */
591
592 #ifdef NET_21
593 sock_init_data(sock, sk);
594
595 sk->destruct = NULL;
596 sk->reuse = 1;
597 sock->ops = &pfkey_ops;
598
599 sk->zapped=0;
600 sk->family = PF_KEY;
601 /* sk->num = protocol; */
602 sk->protocol = protocol;
603 key_pid(sk) = current->pid;
604 KLIPS_PRINT(debug_pfkey,
605 "klips_debug:pfkey_create: "
606 "sock->fasync_list=0p%p sk->sleep=0p%p.\n",
607 sock->fasync_list,
608 sk->sleep);
609 #else /* NET_21 */
610 sk->type=sock->type;
611 init_timer(&sk->timer);
612 skb_queue_head_init(&sk->write_queue);
613 skb_queue_head_init(&sk->receive_queue);
614 skb_queue_head_init(&sk->back_log);
615 sk->rcvbuf=SK_RMEM_MAX;
616 sk->sndbuf=SK_WMEM_MAX;
617 sk->allocation=GFP_KERNEL;
618 sk->state=TCP_CLOSE;
619 sk->priority=SOPRI_NORMAL;
620 sk->state_change=pfkey_state_change;
621 sk->data_ready=pfkey_data_ready;
622 sk->write_space=pfkey_write_space;
623 sk->error_report=pfkey_state_change;
624 sk->mtu=4096;
625 sk->socket=sock;
626 sock->data=(void *)sk;
627 sk->sleep=sock->wait;
628 #endif /* NET_21 */
629
630 pfkey_insert_socket(sk);
631 pfkey_list_insert_socket(sock, &pfkey_open_sockets);
632
633 KLIPS_PRINT(debug_pfkey,
634 "klips_debug:pfkey_create: "
635 "Socket sock=0p%p sk=0p%p initialised.\n", sock, sk);
636 return 0;
637 }
638
639 #ifndef NET_21
640 DEBUG_NO_STATIC int
641 pfkey_dup(struct socket *newsock, struct socket *oldsock)
642 {
643 struct sock *sk;
644
645 if(newsock==NULL) {
646 KLIPS_PRINT(debug_pfkey,
647 "klips_debug:pfkey_dup: "
648 "No new socket attached.\n");
649 return -EINVAL;
650 }
651
652 if(oldsock==NULL) {
653 KLIPS_PRINT(debug_pfkey,
654 "klips_debug:pfkey_dup: "
655 "No old socket attached.\n");
656 return -EINVAL;
657 }
658
659 #ifdef NET_21
660 sk=oldsock->sk;
661 #else /* NET_21 */
662 sk=oldsock->data;
663 #endif /* NET_21 */
664
665 /* May not have data attached */
666 if(sk==NULL) {
667 KLIPS_PRINT(debug_pfkey,
668 "klips_debug:pfkey_dup: "
669 "No sock attached to old socket.\n");
670 return -EINVAL;
671 }
672
673 KLIPS_PRINT(debug_pfkey,
674 "klips_debug:pfkey_dup: .\n");
675
676 return pfkey_create(newsock, sk->protocol);
677 }
678 #endif /* !NET_21 */
679
680 DEBUG_NO_STATIC int
681 #ifdef NETDEV_23
682 pfkey_release(struct socket *sock)
683 #else /* NETDEV_23 */
684 pfkey_release(struct socket *sock, struct socket *peersock)
685 #endif /* NETDEV_23 */
686 {
687 struct sock *sk;
688 int i;
689
690 if(sock==NULL) {
691 KLIPS_PRINT(debug_pfkey,
692 "klips_debug:pfkey_release: "
693 "No socket attached.\n");
694 return 0; /* -EINVAL; */
695 }
696
697 #ifdef NET_21
698 sk=sock->sk;
699 #else /* NET_21 */
700 sk=sock->data;
701 #endif /* NET_21 */
702
703 /* May not have data attached */
704 if(sk==NULL) {
705 KLIPS_PRINT(debug_pfkey,
706 "klips_debug:pfkey_release: "
707 "No sk attached to sock=0p%p.\n", sock);
708 return 0; /* -EINVAL; */
709 }
710
711 KLIPS_PRINT(debug_pfkey,
712 "klips_debug:pfkey_release: "
713 "sock=0p%p sk=0p%p\n", sock, sk);
714
715 #ifdef NET_21
716 if(!sk->dead)
717 #endif /* NET_21 */
718 if(sk->state_change) {
719 sk->state_change(sk);
720 }
721
722 #ifdef NET_21
723 sock->sk = NULL;
724 #else /* NET_21 */
725 sock->data = NULL;
726 #endif /* NET_21 */
727
728 /* Try to flush out this socket. Throw out buffers at least */
729 pfkey_destroy_socket(sk);
730 pfkey_list_remove_socket(sock, &pfkey_open_sockets);
731 for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
732 pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i]));
733 }
734
735 MOD_DEC_USE_COUNT;
736 KLIPS_PRINT(debug_pfkey,
737 "klips_debug:pfkey_release: "
738 "succeeded.\n");
739
740 return 0;
741 }
742
743 #ifndef NET_21
744 DEBUG_NO_STATIC int
745 pfkey_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
746 {
747 KLIPS_PRINT(debug_pfkey,
748 "klips_debug:pfkey_bind: "
749 "operation not supported.\n");
750 return -EINVAL;
751 }
752
753 DEBUG_NO_STATIC int
754 pfkey_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)
755 {
756 KLIPS_PRINT(debug_pfkey,
757 "klips_debug:pfkey_connect: "
758 "operation not supported.\n");
759 return -EINVAL;
760 }
761
762 DEBUG_NO_STATIC int
763 pfkey_socketpair(struct socket *a, struct socket *b)
764 {
765 KLIPS_PRINT(debug_pfkey,
766 "klips_debug:pfkey_socketpair: "
767 "operation not supported.\n");
768 return -EINVAL;
769 }
770
771 DEBUG_NO_STATIC int
772 pfkey_accept(struct socket *sock, struct socket *newsock, int flags)
773 {
774 KLIPS_PRINT(debug_pfkey,
775 "klips_debug:pfkey_aaccept: "
776 "operation not supported.\n");
777 return -EINVAL;
778 }
779
780 DEBUG_NO_STATIC int
781 pfkey_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len,
782 int peer)
783 {
784 struct sockaddr *ska = (struct sockaddr*)uaddr;
785
786 KLIPS_PRINT(debug_pfkey,
787 "klips_debug:pfkey_getname: .\n");
788 ska->sa_family = PF_KEY;
789 *uaddr_len = sizeof(*ska);
790 return 0;
791 }
792
793 DEBUG_NO_STATIC int
794 pfkey_select(struct socket *sock, int sel_type, select_table *wait)
795 {
796
797 KLIPS_PRINT(debug_pfkey,
798 "klips_debug:pfkey_select: "
799 ".sock=0p%p sk=0p%p sel_type=%d\n",
800 sock,
801 sock->data,
802 sel_type);
803 if(sock == NULL) {
804 KLIPS_PRINT(debug_pfkey,
805 "klips_debug:pfkey_select: "
806 "Null socket passed in.\n");
807 return -EINVAL;
808 }
809 return datagram_select(sock->data, sel_type, wait);
810 }
811
812 DEBUG_NO_STATIC int
813 pfkey_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
814 {
815 KLIPS_PRINT(debug_pfkey,
816 "klips_debug:pfkey_ioctl: "
817 "not supported.\n");
818 return -EINVAL;
819 }
820
821 DEBUG_NO_STATIC int
822 pfkey_listen(struct socket *sock, int backlog)
823 {
824 KLIPS_PRINT(debug_pfkey,
825 "klips_debug:pfkey_listen: "
826 "not supported.\n");
827 return -EINVAL;
828 }
829 #endif /* !NET_21 */
830
831 DEBUG_NO_STATIC int
832 pfkey_shutdown(struct socket *sock, int mode)
833 {
834 struct sock *sk;
835
836 if(sock == NULL) {
837 KLIPS_PRINT(debug_pfkey,
838 "klips_debug:pfkey_shutdown: "
839 "NULL socket passed in.\n");
840 return -EINVAL;
841 }
842
843 #ifdef NET_21
844 sk=sock->sk;
845 #else /* NET_21 */
846 sk=sock->data;
847 #endif /* NET_21 */
848
849 if(sk == NULL) {
850 KLIPS_PRINT(debug_pfkey,
851 "klips_debug:pfkey_shutdown: "
852 "No sock attached to socket.\n");
853 return -EINVAL;
854 }
855
856 KLIPS_PRINT(debug_pfkey,
857 "klips_debug:pfkey_shutdown: "
858 "mode=%x.\n", mode);
859 mode++;
860
861 if(mode&SEND_SHUTDOWN) {
862 sk->shutdown|=SEND_SHUTDOWN;
863 sk->state_change(sk);
864 }
865
866 if(mode&RCV_SHUTDOWN) {
867 sk->shutdown|=RCV_SHUTDOWN;
868 sk->state_change(sk);
869 }
870 return 0;
871 }
872
873 #ifndef NET_21
874 DEBUG_NO_STATIC int
875 pfkey_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
876 {
877 #ifndef NET_21
878 struct sock *sk;
879
880 if(sock == NULL) {
881 KLIPS_PRINT(debug_pfkey,
882 "klips_debug:pfkey_setsockopt: "
883 "Null socket passed in.\n");
884 return -EINVAL;
885 }
886
887 sk=sock->data;
888
889 if(sk == NULL) {
890 KLIPS_PRINT(debug_pfkey,
891 "klips_debug:pfkey_setsockopt: "
892 "Null sock passed in.\n");
893 return -EINVAL;
894 }
895 #endif /* !NET_21 */
896
897 KLIPS_PRINT(debug_pfkey,
898 "klips_debug:pfkey_setsockopt: .\n");
899 if(level!=SOL_SOCKET) {
900 return -EOPNOTSUPP;
901 }
902 #ifdef NET_21
903 return sock_setsockopt(sock, level, optname, optval, optlen);
904 #else /* NET_21 */
905 return sock_setsockopt(sk, level, optname, optval, optlen);
906 #endif /* NET_21 */
907 }
908
909 DEBUG_NO_STATIC int
910 pfkey_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
911 {
912 #ifndef NET_21
913 struct sock *sk;
914
915 if(sock == NULL) {
916 KLIPS_PRINT(debug_pfkey,
917 "klips_debug:pfkey_setsockopt: "
918 "Null socket passed in.\n");
919 return -EINVAL;
920 }
921
922 sk=sock->data;
923
924 if(sk == NULL) {
925 KLIPS_PRINT(debug_pfkey,
926 "klips_debug:pfkey_setsockopt: "
927 "Null sock passed in.\n");
928 return -EINVAL;
929 }
930 #endif /* !NET_21 */
931
932 KLIPS_PRINT(debug_pfkey,
933 "klips_debug:pfkey_getsockopt: .\n");
934 if(level!=SOL_SOCKET) {
935 return -EOPNOTSUPP;
936 }
937 #ifdef NET_21
938 return sock_getsockopt(sock, level, optname, optval, optlen);
939 #else /* NET_21 */
940 return sock_getsockopt(sk, level, optname, optval, optlen);
941 #endif /* NET_21 */
942 }
943
944 DEBUG_NO_STATIC int
945 pfkey_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
946 {
947 KLIPS_PRINT(debug_pfkey,
948 "klips_debug:pfkey_fcntl: "
949 "not supported.\n");
950 return -EINVAL;
951 }
952 #endif /* !NET_21 */
953
954 /*
955 * Send PF_KEY data down.
956 */
957
958 DEBUG_NO_STATIC int
959 #ifdef NET_21
960 pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
961 #else /* NET_21 */
962 pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags)
963 #endif /* NET_21 */
964 {
965 struct sock *sk;
966 int error = 0;
967 struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL;
968
969 if(sock == NULL) {
970 KLIPS_PRINT(debug_pfkey,
971 "klips_debug:pfkey_sendmsg: "
972 "Null socket passed in.\n");
973 SENDERR(EINVAL);
974 }
975
976 #ifdef NET_21
977 sk = sock->sk;
978 #else /* NET_21 */
979 sk = sock->data;
980 #endif /* NET_21 */
981
982 if(sk == NULL) {
983 KLIPS_PRINT(debug_pfkey,
984 "klips_debug:pfkey_sendmsg: "
985 "Null sock passed in.\n");
986 SENDERR(EINVAL);
987 }
988
989 if(msg == NULL) {
990 KLIPS_PRINT(debug_pfkey,
991 "klips_debug:pfkey_sendmsg: "
992 "Null msghdr passed in.\n");
993 SENDERR(EINVAL);
994 }
995
996 KLIPS_PRINT(debug_pfkey,
997 "klips_debug:pfkey_sendmsg: .\n");
998 if(sk->err) {
999 error = sock_error(sk);
1000 KLIPS_PRINT(debug_pfkey,
1001 "klips_debug:pfkey_sendmsg: "
1002 "sk->err is non-zero, returns %d.\n",
1003 error);
1004 SENDERR(-error);
1005 }
1006
1007 if((current->uid != 0)) {
1008 KLIPS_PRINT(debug_pfkey,
1009 "klips_debug:pfkey_sendmsg: "
1010 "must be root to send messages to pfkey sockets.\n");
1011 SENDERR(EACCES);
1012 }
1013
1014 #ifdef NET_21
1015 if(msg->msg_control)
1016 #else /* NET_21 */
1017 if(flags || msg->msg_control)
1018 #endif /* NET_21 */
1019 {
1020 KLIPS_PRINT(debug_pfkey,
1021 "klips_debug:pfkey_sendmsg: "
1022 "can't set flags or set msg_control.\n");
1023 SENDERR(EINVAL);
1024 }
1025
1026 if(sk->shutdown & SEND_SHUTDOWN) {
1027 KLIPS_PRINT(debug_pfkey,
1028 "klips_debug:pfkey_sendmsg: "
1029 "shutdown.\n");
1030 send_sig(SIGPIPE, current, 0);
1031 SENDERR(EPIPE);
1032 }
1033
1034 if(len < sizeof(struct sadb_msg)) {
1035 KLIPS_PRINT(debug_pfkey,
1036 "klips_debug:pfkey_sendmsg: "
1037 "bogus msg len of %d, too small.\n", len);
1038 SENDERR(EMSGSIZE);
1039 }
1040
1041 KLIPS_PRINT(debug_pfkey,
1042 "klips_debug:pfkey_sendmsg: "
1043 "allocating %d bytes for downward message.\n",
1044 len);
1045 if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) {
1046 KLIPS_PRINT(debug_pfkey,
1047 "klips_debug:pfkey_sendmsg: "
1048 "memory allocation error.\n");
1049 SENDERR(ENOBUFS);
1050 }
1051
1052 memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len);
1053
1054 if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
1055 KLIPS_PRINT(1 || debug_pfkey,
1056 "klips_debug:pfkey_sendmsg: "
1057 "not PF_KEY_V2 msg, found %d, should be %d.\n",
1058 pfkey_msg->sadb_msg_version,
1059 PF_KEY_V2);
1060 kfree((void*)pfkey_msg);
1061 return -EINVAL;
1062 }
1063
1064 if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
1065 KLIPS_PRINT(debug_pfkey,
1066 "klips_debug:pfkey_sendmsg: "
1067 "bogus msg len of %d, not %d byte aligned.\n",
1068 len, (int)IPSEC_PFKEYv2_ALIGN);
1069 SENDERR(EMSGSIZE);
1070 }
1071
1072 #if 0
1073 /* This check is questionable, since a downward message could be
1074 the result of an ACQUIRE either from kernel (PID==0) or
1075 userspace (some other PID). */
1076 /* check PID */
1077 if(pfkey_msg->sadb_msg_pid != current->pid) {
1078 KLIPS_PRINT(debug_pfkey,
1079 "klips_debug:pfkey_sendmsg: "
1080 "pid (%d) does not equal sending process pid (%d).\n",
1081 pfkey_msg->sadb_msg_pid, current->pid);
1082 SENDERR(EINVAL);
1083 }
1084 #endif
1085
1086 if(pfkey_msg->sadb_msg_reserved) {
1087 KLIPS_PRINT(debug_pfkey,
1088 "klips_debug:pfkey_sendmsg: "
1089 "reserved field must be zero, set to %d.\n",
1090 pfkey_msg->sadb_msg_reserved);
1091 SENDERR(EINVAL);
1092 }
1093
1094 if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){
1095 KLIPS_PRINT(debug_pfkey,
1096 "klips_debug:pfkey_sendmsg: "
1097 "msg type too large or small:%d.\n",
1098 pfkey_msg->sadb_msg_type);
1099 SENDERR(EINVAL);
1100 }
1101
1102 KLIPS_PRINT(debug_pfkey,
1103 "klips_debug:pfkey_sendmsg: "
1104 "msg sent for parsing.\n");
1105
1106 if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) {
1107 struct socket_list *pfkey_socketsp;
1108
1109 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
1110 "pfkey_msg_parse returns %d.\n",
1111 error);
1112
1113 if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) {
1114 KLIPS_PRINT(debug_pfkey,
1115 "klips_debug:pfkey_sendmsg: "
1116 "memory allocation error.\n");
1117 SENDERR(ENOBUFS);
1118 }
1119 memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg));
1120 pfkey_reply->sadb_msg_errno = -error;
1121 pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
1122
1123 for(pfkey_socketsp = pfkey_open_sockets;
1124 pfkey_socketsp;
1125 pfkey_socketsp = pfkey_socketsp->next) {
1126 int error_upmsg = 0;
1127 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
1128 "sending up error=%d message=0p%p to socket=0p%p.\n",
1129 error,
1130 pfkey_reply,
1131 pfkey_socketsp->socketp);
1132 if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
1133 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
1134 "sending up error message to socket=0p%p failed with error=%d.\n",
1135 pfkey_socketsp->socketp,
1136 error_upmsg);
1137 /* pfkey_msg_free(&pfkey_reply); */
1138 /* SENDERR(-error); */
1139 }
1140 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
1141 "sending up error message to socket=0p%p succeeded.\n",
1142 pfkey_socketsp->socketp);
1143 }
1144
1145 pfkey_msg_free(&pfkey_reply);
1146
1147 SENDERR(-error);
1148 }
1149
1150 errlab:
1151 if (pfkey_msg) {
1152 kfree((void*)pfkey_msg);
1153 }
1154
1155 if(error) {
1156 return error;
1157 } else {
1158 return len;
1159 }
1160 }
1161
1162 /*
1163 * Receive PF_KEY data up.
1164 */
1165
1166 DEBUG_NO_STATIC int
1167 #ifdef NET_21
1168 pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm)
1169 #else /* NET_21 */
1170 pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock, int flags, int *addr_len)
1171 #endif /* NET_21 */
1172 {
1173 struct sock *sk;
1174 #ifdef NET_21
1175 int noblock = flags & MSG_DONTWAIT;
1176 #endif /* NET_21 */
1177 struct sk_buff *skb;
1178 int error;
1179
1180 if(sock == NULL) {
1181 KLIPS_PRINT(debug_pfkey,
1182 "klips_debug:pfkey_recvmsg: "
1183 "Null socket passed in.\n");
1184 return -EINVAL;
1185 }
1186
1187 #ifdef NET_21
1188 sk = sock->sk;
1189 #else /* NET_21 */
1190 sk = sock->data;
1191 #endif /* NET_21 */
1192
1193 if(sk == NULL) {
1194 KLIPS_PRINT(debug_pfkey,
1195 "klips_debug:pfkey_recvmsg: "
1196 "Null sock passed in for sock=0p%p.\n", sock);
1197 return -EINVAL;
1198 }
1199
1200 if(msg == NULL) {
1201 KLIPS_PRINT(debug_pfkey,
1202 "klips_debug:pfkey_recvmsg: "
1203 "Null msghdr passed in for sock=0p%p, sk=0p%p.\n",
1204 sock, sk);
1205 return -EINVAL;
1206 }
1207
1208 KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
1209 "klips_debug:pfkey_recvmsg: sock=0p%p sk=0p%p msg=0p%p size=%d.\n",
1210 sock, sk, msg, size);
1211 if(flags & ~MSG_PEEK) {
1212 KLIPS_PRINT(debug_pfkey,
1213 "klips_debug:pfkey_sendmsg: "
1214 "flags (%d) other than MSG_PEEK not supported.\n",
1215 flags);
1216 return -EOPNOTSUPP;
1217 }
1218
1219 #ifdef NET_21
1220 msg->msg_namelen = 0; /* sizeof(*ska); */
1221 #else /* NET_21 */
1222 if(addr_len) {
1223 *addr_len = 0; /* sizeof(*ska); */
1224 }
1225 #endif /* NET_21 */
1226
1227 if(sk->err) {
1228 KLIPS_PRINT(debug_pfkey,
1229 "klips_debug:pfkey_sendmsg: "
1230 "sk->err=%d.\n", sk->err);
1231 return sock_error(sk);
1232 }
1233
1234 if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) {
1235 return error;
1236 }
1237
1238 if(size > skb->len) {
1239 size = skb->len;
1240 }
1241 #ifdef NET_21
1242 else if(size <skb->len) {
1243 msg->msg_flags |= MSG_TRUNC;
1244 }
1245 #endif /* NET_21 */
1246
1247 skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
1248 sk->stamp=skb->stamp;
1249
1250 skb_free_datagram(sk, skb);
1251 return size;
1252 }
1253
1254 #ifdef NET_21
1255 struct net_proto_family pfkey_family_ops = {
1256 PF_KEY,
1257 pfkey_create
1258 };
1259
1260 struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = {
1261 #ifdef NETDEV_23
1262 family: PF_KEY,
1263 release: pfkey_release,
1264 bind: sock_no_bind,
1265 connect: sock_no_connect,
1266 socketpair: sock_no_socketpair,
1267 accept: sock_no_accept,
1268 getname: sock_no_getname,
1269 poll: datagram_poll,
1270 ioctl: sock_no_ioctl,
1271 listen: sock_no_listen,
1272 shutdown: pfkey_shutdown,
1273 setsockopt: sock_no_setsockopt,
1274 getsockopt: sock_no_getsockopt,
1275 sendmsg: pfkey_sendmsg,
1276 recvmsg: pfkey_recvmsg,
1277 mmap: sock_no_mmap,
1278 #else /* NETDEV_23 */
1279 PF_KEY,
1280 sock_no_dup,
1281 pfkey_release,
1282 sock_no_bind,
1283 sock_no_connect,
1284 sock_no_socketpair,
1285 sock_no_accept,
1286 sock_no_getname,
1287 datagram_poll,
1288 sock_no_ioctl,
1289 sock_no_listen,
1290 pfkey_shutdown,
1291 sock_no_setsockopt,
1292 sock_no_getsockopt,
1293 sock_no_fcntl,
1294 pfkey_sendmsg,
1295 pfkey_recvmsg
1296 #endif /* NETDEV_23 */
1297 };
1298
1299 #ifdef NETDEV_23
1300 #include <linux/smp_lock.h>
1301 SOCKOPS_WRAP(pfkey, PF_KEY);
1302 #endif /* NETDEV_23 */
1303
1304 #else /* NET_21 */
1305 struct proto_ops pfkey_proto_ops = {
1306 PF_KEY,
1307 pfkey_create,
1308 pfkey_dup,
1309 pfkey_release,
1310 pfkey_bind,
1311 pfkey_connect,
1312 pfkey_socketpair,
1313 pfkey_accept,
1314 pfkey_getname,
1315 pfkey_select,
1316 pfkey_ioctl,
1317 pfkey_listen,
1318 pfkey_shutdown,
1319 pfkey_setsockopt,
1320 pfkey_getsockopt,
1321 pfkey_fcntl,
1322 pfkey_sendmsg,
1323 pfkey_recvmsg
1324 };
1325 #endif /* NET_21 */
1326
1327 #ifdef CONFIG_PROC_FS
1328 #ifndef PROC_FS_2325
1329 DEBUG_NO_STATIC
1330 #endif /* PROC_FS_2325 */
1331 int
1332 pfkey_get_info(char *buffer, char **start, off_t offset, int length
1333 #ifndef PROC_NO_DUMMY
1334 , int dummy
1335 #endif /* !PROC_NO_DUMMY */
1336 )
1337 {
1338 const int max_content = length > 0? length-1 : 0;
1339
1340 off_t begin=0;
1341 int len=0;
1342 struct sock *sk=pfkey_sock_list;
1343
1344 #ifdef CONFIG_IPSEC_DEBUG
1345 if(!sysctl_ipsec_debug_verbose) {
1346 #endif /* CONFIG_IPSEC_DEBUG */
1347 len+= snprintf(buffer,length,
1348 " sock pid socket next prev e n p sndbf Flags Type St\n");
1349 #ifdef CONFIG_IPSEC_DEBUG
1350 } else {
1351 len+= snprintf(buffer,length,
1352 " sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n");
1353 }
1354 #endif /* CONFIG_IPSEC_DEBUG */
1355
1356 while(sk!=NULL) {
1357 #ifdef CONFIG_IPSEC_DEBUG
1358 if(!sysctl_ipsec_debug_verbose) {
1359 #endif /* CONFIG_IPSEC_DEBUG */
1360 len += ipsec_snprintf(buffer+len, length-len,
1361 "%8p %5d %8p %8p %8p %d %d %d %5d %08lX %8X %2X\n",
1362 sk,
1363 key_pid(sk),
1364 sk->socket,
1365 sk->next,
1366 sk->prev,
1367 sk->err,
1368 sk->num,
1369 sk->protocol,
1370 sk->sndbuf,
1371 sk->socket->flags,
1372 sk->socket->type,
1373 sk->socket->state);
1374 #ifdef CONFIG_IPSEC_DEBUG
1375 } else {
1376 len += ipsec_snprintf(buffer+len, length-len,
1377 "%8p %5d %d %8p %8p %8p %8p %d %d %d %d %d %5d %d.%06d %08lX %8X %2X\n",
1378 sk,
1379 key_pid(sk),
1380 sk->dead,
1381 sk->sleep,
1382 sk->socket,
1383 sk->next,
1384 sk->prev,
1385 sk->err,
1386 sk->reuse,
1387 sk->zapped,
1388 sk->num,
1389 sk->protocol,
1390 sk->sndbuf,
1391 (unsigned int)sk->stamp.tv_sec,
1392 (unsigned int)sk->stamp.tv_usec,
1393 sk->socket->flags,
1394 sk->socket->type,
1395 sk->socket->state);
1396 }
1397 #endif /* CONFIG_IPSEC_DEBUG */
1398
1399 if (len >= max_content) {
1400 /* we've done all that can fit -- stop loop */
1401 len = max_content; /* truncate crap */
1402 break;
1403 } else {
1404 const off_t pos = begin + len; /* file position of end of what we've generated */
1405
1406 if (pos <= offset) {
1407 /* all is before first interesting character:
1408 * discard, but note where we are.
1409 */
1410 len = 0;
1411 begin = pos;
1412 }
1413 }
1414 sk=sk->next;
1415 }
1416
1417 *start = buffer + (offset - begin); /* Start of wanted data */
1418 return len - (offset - begin);
1419 }
1420
1421 #ifndef PROC_FS_2325
1422 DEBUG_NO_STATIC
1423 #endif /* PROC_FS_2325 */
1424 int
1425 pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length
1426 #ifndef PROC_NO_DUMMY
1427 , int dummy
1428 #endif /* !PROC_NO_DUMMY */
1429 )
1430 {
1431 const int max_content = length > 0? length-1 : 0;
1432
1433 off_t begin=0;
1434 int len=0;
1435 int satype;
1436 struct supported_list *pfkey_supported_p;
1437
1438 len += ipsec_snprintf(buffer, length,
1439 "satype exttype alg_id ivlen minbits maxbits\n");
1440
1441 for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
1442 pfkey_supported_p = pfkey_supported_list[satype];
1443 while(pfkey_supported_p) {
1444 len += ipsec_snprintf(buffer+len, length-len,
1445 " %2d %2d %2d %3d %3d %3d\n",
1446 satype,
1447 pfkey_supported_p->supportedp->supported_alg_exttype,
1448 pfkey_supported_p->supportedp->supported_alg_id,
1449 pfkey_supported_p->supportedp->supported_alg_ivlen,
1450 pfkey_supported_p->supportedp->supported_alg_minbits,
1451 pfkey_supported_p->supportedp->supported_alg_maxbits);
1452
1453 if (len >= max_content) {
1454 /* we've done all that can fit -- stop loop */
1455 len = max_content; /* truncate crap */
1456 break;
1457 } else {
1458 const off_t pos = begin + len; /* file position of end of what we've generated */
1459
1460 if (pos <= offset) {
1461 /* all is before first interesting character:
1462 * discard, but note where we are.
1463 */
1464 len = 0;
1465 begin = pos;
1466 }
1467 }
1468
1469 pfkey_supported_p = pfkey_supported_p->next;
1470 }
1471 }
1472
1473 *start = buffer + (offset - begin); /* Start of wanted data */
1474 return len - (offset - begin);
1475 }
1476
1477 #ifndef PROC_FS_2325
1478 DEBUG_NO_STATIC
1479 #endif /* PROC_FS_2325 */
1480 int
1481 pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length
1482 #ifndef PROC_NO_DUMMY
1483 , int dummy
1484 #endif /* !PROC_NO_DUMMY */
1485 )
1486 {
1487 const int max_content = length > 0? length-1 : 0;
1488
1489 off_t begin=0;
1490 int len=0;
1491 int satype;
1492 struct socket_list *pfkey_sockets;
1493
1494 len += ipsec_snprintf(buffer, length,
1495 "satype socket pid sk\n");
1496
1497 for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
1498 pfkey_sockets = pfkey_registered_sockets[satype];
1499 while(pfkey_sockets) {
1500 #ifdef NET_21
1501 len += ipsec_snprintf(buffer+len, length-len,
1502 " %2d %8p %5d %8p\n",
1503 satype,
1504 pfkey_sockets->socketp,
1505 key_pid(pfkey_sockets->socketp->sk),
1506 pfkey_sockets->socketp->sk);
1507 #else /* NET_21 */
1508 len += ipsec_snprintf(buffer+len, length-len,
1509 " %2d %8p N/A %8p\n",
1510 satype,
1511 pfkey_sockets->socketp,
1512 #if 0
1513 key_pid((pfkey_sockets->socketp)->data),
1514 #endif
1515 (pfkey_sockets->socketp)->data);
1516 #endif /* NET_21 */
1517
1518 if (len >= max_content) {
1519 /* we've done all that can fit -- stop loop (could stop two) */
1520 len = max_content; /* truncate crap */
1521 break;
1522 } else {
1523 const off_t pos = begin + len; /* file position of end of what we've generated */
1524
1525 if (pos <= offset) {
1526 /* all is before first interesting character:
1527 * discard, but note where we are.
1528 */
1529 len = 0;
1530 begin = pos;
1531 }
1532 }
1533
1534 pfkey_sockets = pfkey_sockets->next;
1535 }
1536 }
1537
1538 *start = buffer + (offset - begin); /* Start of wanted data */
1539 return len - (offset - begin);
1540 }
1541
1542 #ifndef PROC_FS_2325
1543 struct proc_dir_entry proc_net_pfkey =
1544 {
1545 0,
1546 6, "pf_key",
1547 S_IFREG | S_IRUGO, 1, 0, 0,
1548 0, &proc_net_inode_operations,
1549 pfkey_get_info
1550 };
1551 struct proc_dir_entry proc_net_pfkey_supported =
1552 {
1553 0,
1554 16, "pf_key_supported",
1555 S_IFREG | S_IRUGO, 1, 0, 0,
1556 0, &proc_net_inode_operations,
1557 pfkey_supported_get_info
1558 };
1559 struct proc_dir_entry proc_net_pfkey_registered =
1560 {
1561 0,
1562 17, "pf_key_registered",
1563 S_IFREG | S_IRUGO, 1, 0, 0,
1564 0, &proc_net_inode_operations,
1565 pfkey_registered_get_info
1566 };
1567 #endif /* !PROC_FS_2325 */
1568 #endif /* CONFIG_PROC_FS */
1569
1570 DEBUG_NO_STATIC int
1571 supported_add_all(int satype, struct supported supported[], int size)
1572 {
1573 int i;
1574 int error = 0;
1575
1576 KLIPS_PRINT(debug_pfkey,
1577 "klips_debug:init_pfkey: "
1578 "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct supported)[%d]=%d.\n",
1579 satype,
1580 size,
1581 (int)sizeof(struct supported),
1582 (int)(size/sizeof(struct supported)));
1583
1584 for(i = 0; i < size / sizeof(struct supported); i++) {
1585
1586 KLIPS_PRINT(debug_pfkey,
1587 "klips_debug:init_pfkey: "
1588 "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
1589 i,
1590 satype,
1591 supported[i].supported_alg_exttype,
1592 supported[i].supported_alg_id,
1593 supported[i].supported_alg_ivlen,
1594 supported[i].supported_alg_minbits,
1595 supported[i].supported_alg_maxbits);
1596
1597 error |= pfkey_list_insert_supported(&(supported[i]),
1598 &(pfkey_supported_list[satype]));
1599 }
1600 return error;
1601 }
1602
1603 DEBUG_NO_STATIC int
1604 supported_remove_all(int satype)
1605 {
1606 int error = 0;
1607 struct supported*supportedp;
1608
1609 while(pfkey_supported_list[satype]) {
1610 supportedp = pfkey_supported_list[satype]->supportedp;
1611 KLIPS_PRINT(debug_pfkey,
1612 "klips_debug:init_pfkey: "
1613 "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
1614 satype,
1615 supportedp->supported_alg_exttype,
1616 supportedp->supported_alg_id,
1617 supportedp->supported_alg_ivlen,
1618 supportedp->supported_alg_minbits,
1619 supportedp->supported_alg_maxbits);
1620
1621 error |= pfkey_list_remove_supported(supportedp,
1622 &(pfkey_supported_list[satype]));
1623 }
1624 return error;
1625 }
1626
1627 int
1628 pfkey_init(void)
1629 {
1630 int error = 0;
1631 int i;
1632
1633 static struct supported supported_init_ah[] = {
1634 #ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
1635 {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5_HMAC, 0, 128, 128},
1636 #endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
1637 #ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
1638 {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1_HMAC, 0, 160, 160}
1639 #endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
1640 };
1641 static struct supported supported_init_esp[] = {
1642 #ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
1643 {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5_HMAC, 0, 128, 128},
1644 #endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
1645 #ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
1646 {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1_HMAC, 0, 160, 160},
1647 #endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
1648 #ifdef CONFIG_IPSEC_ENC_3DES
1649 {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DES_CBC, 64, 168, 168},
1650 #endif /* CONFIG_IPSEC_ENC_3DES */
1651 };
1652 static struct supported supported_init_ipip[] = {
1653 {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32}
1654 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1655 , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32}
1656 , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128}
1657 , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128}
1658 #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
1659 };
1660 #ifdef CONFIG_IPSEC_IPCOMP
1661 static struct supported supported_init_ipcomp[] = {
1662 {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1}
1663 };
1664 #endif /* CONFIG_IPSEC_IPCOMP */
1665
1666 #if 0
1667 printk(KERN_INFO
1668 "klips_info:pfkey_init: "
1669 "FreeS/WAN: initialising PF_KEYv2 domain sockets.\n");
1670 #endif
1671
1672 for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
1673 pfkey_registered_sockets[i] = NULL;
1674 pfkey_supported_list[i] = NULL;
1675 }
1676
1677 error |= supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah));
1678 error |= supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp));
1679 #ifdef CONFIG_IPSEC_IPCOMP
1680 error |= supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp));
1681 #endif /* CONFIG_IPSEC_IPCOMP */
1682 error |= supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip));
1683
1684 #ifdef NET_21
1685 error |= sock_register(&pfkey_family_ops);
1686 #else /* NET_21 */
1687 error |= sock_register(pfkey_proto_ops.family, &pfkey_proto_ops);
1688 #endif /* NET_21 */
1689
1690 #ifdef CONFIG_PROC_FS
1691 # ifndef PROC_FS_2325
1692 # ifdef PROC_FS_21
1693 error |= proc_register(proc_net, &proc_net_pfkey);
1694 error |= proc_register(proc_net, &proc_net_pfkey_supported);
1695 error |= proc_register(proc_net, &proc_net_pfkey_registered);
1696 # else /* PROC_FS_21 */
1697 error |= proc_register_dynamic(&proc_net, &proc_net_pfkey);
1698 error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported);
1699 error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered);
1700 # endif /* PROC_FS_21 */
1701 # else /* !PROC_FS_2325 */
1702 proc_net_create ("pf_key", 0, pfkey_get_info);
1703 proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info);
1704 proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info);
1705 # endif /* !PROC_FS_2325 */
1706 #endif /* CONFIG_PROC_FS */
1707
1708 return error;
1709 }
1710
1711 int
1712 pfkey_cleanup(void)
1713 {
1714 int error = 0;
1715
1716 printk(KERN_INFO "klips_info:pfkey_cleanup: "
1717 "shutting down PF_KEY domain sockets.\n");
1718 #ifdef NET_21
1719 error |= sock_unregister(PF_KEY);
1720 #else /* NET_21 */
1721 error |= sock_unregister(pfkey_proto_ops.family);
1722 #endif /* NET_21 */
1723
1724 error |= supported_remove_all(SADB_SATYPE_AH);
1725 error |= supported_remove_all(SADB_SATYPE_ESP);
1726 #ifdef CONFIG_IPSEC_IPCOMP
1727 error |= supported_remove_all(SADB_X_SATYPE_COMP);
1728 #endif /* CONFIG_IPSEC_IPCOMP */
1729 error |= supported_remove_all(SADB_X_SATYPE_IPIP);
1730
1731 #ifdef CONFIG_PROC_FS
1732 # ifndef PROC_FS_2325
1733 if (proc_net_unregister(proc_net_pfkey.low_ino) != 0)
1734 printk("klips_debug:pfkey_cleanup: "
1735 "cannot unregister /proc/net/pf_key\n");
1736 if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0)
1737 printk("klips_debug:pfkey_cleanup: "
1738 "cannot unregister /proc/net/pf_key_supported\n");
1739 if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0)
1740 printk("klips_debug:pfkey_cleanup: "
1741 "cannot unregister /proc/net/pf_key_registered\n");
1742 # else /* !PROC_FS_2325 */
1743 proc_net_remove ("pf_key");
1744 proc_net_remove ("pf_key_supported");
1745 proc_net_remove ("pf_key_registered");
1746 # endif /* !PROC_FS_2325 */
1747 #endif /* CONFIG_PROC_FS */
1748
1749 /* other module unloading cleanup happens here */
1750 return error;
1751 }
1752
1753 #ifdef MODULE
1754 #if 0
1755 int
1756 init_module(void)
1757 {
1758 pfkey_init();
1759 return 0;
1760 }
1761
1762 void
1763 cleanup_module(void)
1764 {
1765 pfkey_cleanup();
1766 }
1767 #endif /* 0 */
1768 #else /* MODULE */
1769 void
1770 pfkey_proto_init(struct net_proto *pro)
1771 {
1772 pfkey_init();
1773 }
1774 #endif /* MODULE */
1775
1776 /*
1777 * $Log: pfkey_v2.c,v $
1778 * Revision 1.4 2004/09/29 22:27:41 as
1779 * changed SADB identifiers
1780 *
1781 * Revision 1.3 2004/04/28 08:06:22 as
1782 * added dhr's freeswan-2.06 changes
1783 *
1784 * Revision 1.2 2004/03/22 21:53:19 as
1785 * merged alg-0.8.1 branch with HEAD
1786 *
1787 * Revision 1.1.4.1 2004/03/16 09:48:20 as
1788 * alg-0.8.1rc12 patch merged
1789 *
1790 * Revision 1.1 2004/03/15 20:35:26 as
1791 * added files from freeswan-2.04-x509-1.5.3
1792 *
1793 * Revision 1.78 2003/04/03 17:38:09 rgb
1794 * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
1795 *
1796 * Revision 1.77 2002/10/17 16:49:36 mcr
1797 * sock->ops should reference the unwrapped options so that
1798 * we get hacked in locking on SMP systems.
1799 *
1800 * Revision 1.76 2002/10/12 23:11:53 dhr
1801 *
1802 * [KenB + DHR] more 64-bit cleanup
1803 *
1804 * Revision 1.75 2002/09/20 05:01:57 rgb
1805 * Added memory allocation debugging.
1806 *
1807 * Revision 1.74 2002/09/19 02:42:50 mcr
1808 * do not define the pfkey_ops function for now.
1809 *
1810 * Revision 1.73 2002/09/17 17:29:23 mcr
1811 * #if 0 out some dead code - pfkey_ops is never used as written.
1812 *
1813 * Revision 1.72 2002/07/24 18:44:54 rgb
1814 * Type fiddling to tame ia64 compiler.
1815 *
1816 * Revision 1.71 2002/05/23 07:14:11 rgb
1817 * Cleaned up %p variants to 0p%p for test suite cleanup.
1818 *
1819 * Revision 1.70 2002/04/24 07:55:32 mcr
1820 * #include patches and Makefiles for post-reorg compilation.
1821 *
1822 * Revision 1.69 2002/04/24 07:36:33 mcr
1823 * Moved from ./klips/net/ipsec/pfkey_v2.c,v
1824 *
1825 * Revision 1.68 2002/03/08 01:15:17 mcr
1826 * put some internal structure only debug messages behind
1827 * && sysctl_ipsec_debug_verbose.
1828 *
1829 * Revision 1.67 2002/01/29 17:17:57 mcr
1830 * moved include of ipsec_param.h to after include of linux/kernel.h
1831 * otherwise, it seems that some option that is set in ipsec_param.h
1832 * screws up something subtle in the include path to kernel.h, and
1833 * it complains on the snprintf() prototype.
1834 *
1835 * Revision 1.66 2002/01/29 04:00:54 mcr
1836 * more excise of kversions.h header.
1837 *
1838 * Revision 1.65 2002/01/29 02:13:18 mcr
1839 * introduction of ipsec_kversion.h means that include of
1840 * ipsec_param.h must preceed any decisions about what files to
1841 * include to deal with differences in kernel source.
1842 *
1843 * Revision 1.64 2001/11/26 09:23:51 rgb
1844 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
1845 *
1846 * Revision 1.61.2.1 2001/09/25 02:28:44 mcr
1847 * cleaned up includes.
1848 *
1849 * Revision 1.63 2001/11/12 19:38:00 rgb
1850 * Continue trying other sockets even if one fails and return only original
1851 * error.
1852 *
1853 * Revision 1.62 2001/10/18 04:45:22 rgb
1854 * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
1855 * lib/freeswan.h version macros moved to lib/kversions.h.
1856 * Other compiler directive cleanups.
1857 *
1858 * Revision 1.61 2001/09/20 15:32:59 rgb
1859 * Min/max cleanup.
1860 *
1861 * Revision 1.60 2001/06/14 19:35:12 rgb
1862 * Update copyright date.
1863 *
1864 * Revision 1.59 2001/06/13 15:35:48 rgb
1865 * Fixed #endif comments.
1866 *
1867 * Revision 1.58 2001/05/04 16:37:24 rgb
1868 * Remove erroneous checking of return codes for proc_net_* in 2.4.
1869 *
1870 * Revision 1.57 2001/05/03 19:43:36 rgb
1871 * Initialise error return variable.
1872 * Check error return codes in startup and shutdown.
1873 * Standardise on SENDERR() macro.
1874 *
1875 * Revision 1.56 2001/04/21 23:05:07 rgb
1876 * Define out skb->used for 2.4 kernels.
1877 *
1878 * Revision 1.55 2001/02/28 05:03:28 rgb
1879 * Clean up and rationalise startup messages.
1880 *
1881 * Revision 1.54 2001/02/27 22:24:55 rgb
1882 * Re-formatting debug output (line-splitting, joining, 1arg/line).
1883 * Check for satoa() return codes.
1884 *
1885 * Revision 1.53 2001/02/27 06:48:18 rgb
1886 * Fixed pfkey socket unregister log message to reflect type and function.
1887 *
1888 * Revision 1.52 2001/02/26 22:34:38 rgb
1889 * Fix error return code that was getting overwritten by the error return
1890 * code of an upmsg.
1891 *
1892 * Revision 1.51 2001/01/30 23:42:47 rgb
1893 * Allow pfkey msgs from pid other than user context required for ACQUIRE
1894 * and subsequent ADD or UDATE.
1895 *
1896 * Revision 1.50 2001/01/23 20:22:59 rgb
1897 * 2.4 fix to remove removed is_clone member.
1898 *
1899 * Revision 1.49 2000/11/06 04:33:47 rgb
1900 * Changed non-exported functions to DEBUG_NO_STATIC.
1901 *
1902 * Revision 1.48 2000/09/29 19:47:41 rgb
1903 * Update copyright.
1904 *
1905 * Revision 1.47 2000/09/22 04:23:04 rgb
1906 * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error.
1907 *
1908 * Revision 1.46 2000/09/21 04:20:44 rgb
1909 * Fixed array size off-by-one error. (Thanks Svenning!)
1910 *
1911 * Revision 1.45 2000/09/20 04:01:26 rgb
1912 * Changed static functions to DEBUG_NO_STATIC for revealing function names
1913 * in oopsen.
1914 *
1915 * Revision 1.44 2000/09/19 00:33:17 rgb
1916 * 2.0 fixes.
1917 *
1918 * Revision 1.43 2000/09/16 01:28:13 rgb
1919 * Fixed use of 0 in p format warning.
1920 *
1921 * Revision 1.42 2000/09/16 01:09:41 rgb
1922 * Fixed debug format warning for pointers that was expecting ints.
1923 *
1924 * Revision 1.41 2000/09/13 15:54:00 rgb
1925 * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info().
1926 * Moved supported algos add and remove to functions.
1927 *
1928 * Revision 1.40 2000/09/12 18:49:28 rgb
1929 * Added IPIP tunnel and IPCOMP register support.
1930 *
1931 * Revision 1.39 2000/09/12 03:23:49 rgb
1932 * Converted #if0 debugs to sysctl.
1933 * Removed debug_pfkey initialisations that prevented no_debug loading or
1934 * linking.
1935 *
1936 * Revision 1.38 2000/09/09 06:38:02 rgb
1937 * Return positive errno in pfkey_reply error message.
1938 *
1939 * Revision 1.37 2000/09/08 19:19:09 rgb
1940 * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
1941 * Clean-up of long-unused crud...
1942 * Create pfkey error message on on failure.
1943 * Give pfkey_list_{insert,remove}_{socket,supported}() some error
1944 * checking.
1945 *
1946 * Revision 1.36 2000/09/01 18:49:38 rgb
1947 * Reap experimental NET_21_ bits.
1948 * Turned registered sockets list into an array of one list per satype.
1949 * Remove references to deprecated sklist_{insert,remove}_socket.
1950 * Removed leaking socket debugging code.
1951 * Removed duplicate pfkey_insert_socket in pfkey_create.
1952 * Removed all references to pfkey msg->msg_name, since it is not used for
1953 * pfkey.
1954 * Added a supported algorithms array lists, one per satype and registered
1955 * existing algorithms.
1956 * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
1957 * list.
1958 * Only send pfkey_expire() messages to sockets registered for that satype.
1959 *
1960 * Revision 1.35 2000/08/24 17:03:00 rgb
1961 * Corrected message size error return code for PF_KEYv2.
1962 * Removed downward error prohibition.
1963 *
1964 * Revision 1.34 2000/08/21 16:32:26 rgb
1965 * Re-formatted for cosmetic consistency and readability.
1966 *
1967 * Revision 1.33 2000/08/20 21:38:24 rgb
1968 * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
1969 * Extended the upward message initiation of pfkey_sendmsg(). (Momchil)
1970 *
1971 * Revision 1.32 2000/07/28 14:58:31 rgb
1972 * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
1973 *
1974 * Revision 1.31 2000/05/16 03:04:00 rgb
1975 * Updates for 2.3.99pre8 from MB.
1976 *
1977 * Revision 1.30 2000/05/10 19:22:21 rgb
1978 * Use sklist private functions for 2.3.xx compatibility.
1979 *
1980 * Revision 1.29 2000/03/22 16:17:03 rgb
1981 * Fixed SOCKOPS_WRAPPED macro for SMP (MB).
1982 *
1983 * Revision 1.28 2000/02/21 19:30:45 rgb
1984 * Removed references to pkt_bridged for 2.3.47 compatibility.
1985 *
1986 * Revision 1.27 2000/02/14 21:07:00 rgb
1987 * Fixed /proc/net/pf-key legend spacing.
1988 *
1989 * Revision 1.26 2000/01/22 03:46:59 rgb
1990 * Fixed pfkey error return mechanism so that we are able to free the
1991 * local copy of the pfkey_msg, plugging a memory leak and silencing
1992 * the bad object free complaints.
1993 *
1994 * Revision 1.25 2000/01/21 06:19:44 rgb
1995 * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT.
1996 * Added debugging to pfkey_upmsg.
1997 *
1998 * Revision 1.24 2000/01/10 16:38:23 rgb
1999 * MB fixups for 2.3.x.
2000 *
2001 * Revision 1.23 1999/12/09 23:22:16 rgb
2002 * Added more instrumentation for debugging 2.0 socket
2003 * selection/reading.
2004 * Removed erroneous 2.0 wait==NULL check bug in select.
2005 *
2006 * Revision 1.22 1999/12/08 20:32:16 rgb
2007 * Tidied up 2.0.xx support, after major pfkey work, eliminating
2008 * msg->msg_name twiddling in the process, since it is not defined
2009 * for PF_KEYv2.
2010 *
2011 * Revision 1.21 1999/12/01 22:17:19 rgb
2012 * Set skb->dev to zero on new skb in case it is a reused skb.
2013 * Added check for skb_put overflow and freeing to avoid upmsg on error.
2014 * Added check for wrong pfkey version and freeing to avoid upmsg on
2015 * error.
2016 * Shut off content dumping in pfkey_destroy.
2017 * Added debugging message for size of buffer allocated for upmsg.
2018 *
2019 * Revision 1.20 1999/11/27 12:11:00 rgb
2020 * Minor clean-up, enabling quiet operation of pfkey if desired.
2021 *
2022 * Revision 1.19 1999/11/25 19:04:21 rgb
2023 * Update proc_fs code for pfkey to use dynamic registration.
2024 *
2025 * Revision 1.18 1999/11/25 09:07:17 rgb
2026 * Implemented SENDERR macro for propagating error codes.
2027 * Fixed error return code bug.
2028 *
2029 * Revision 1.17 1999/11/23 23:07:20 rgb
2030 * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer
2031 * parses. (PJO)
2032 * Sort out pfkey and freeswan headers, putting them in a library path.
2033 *
2034 * Revision 1.16 1999/11/20 22:00:22 rgb
2035 * Moved socketlist type declarations and prototypes for shared use.
2036 * Renamed reformatted and generically extended for use by other socket
2037 * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket.
2038 *
2039 * Revision 1.15 1999/11/18 04:15:09 rgb
2040 * Make pfkey_data_ready temporarily available for 2.2.x testing.
2041 * Clean up pfkey_destroy_socket() debugging statements.
2042 * Add Peter Onion's code to send messages up to all listening sockets.
2043 * Changed all occurrences of #include "../../../lib/freeswan.h"
2044 * to #include <freeswan.h> which works due to -Ilibfreeswan in the
2045 * klips/net/ipsec/Makefile.
2046 * Replaced all kernel version macros to shorter, readable form.
2047 * Added CONFIG_PROC_FS compiler directives in case it is shut off.
2048 *
2049 * Revision 1.14 1999/11/17 16:01:00 rgb
2050 * Make pfkey_data_ready temporarily available for 2.2.x testing.
2051 * Clean up pfkey_destroy_socket() debugging statements.
2052 * Add Peter Onion's code to send messages up to all listening sockets.
2053 * Changed #include "../../../lib/freeswan.h" to #include <freeswan.h>
2054 * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile.
2055 *
2056 * Revision 1.13 1999/10/27 19:59:51 rgb
2057 * Removed af_unix comments that are no longer relevant.
2058 * Added debug prink statements.
2059 * Added to the /proc output in pfkey_get_info.
2060 * Made most functions non-static to enable oops tracing.
2061 * Re-enable skb dequeueing and freeing.
2062 * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg().
2063 *
2064 * Revision 1.12 1999/10/26 17:05:42 rgb
2065 * Complete re-ordering based on proto_ops structure order.
2066 * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity.
2067 * Simplification to use built-in socket ops where possible for 2.2.x.
2068 * Add shorter macros for compiler directives to visually clean-up.
2069 * Add lots of sk skb dequeueing debugging statements.
2070 * Added to the /proc output in pfkey_get_info.
2071 *
2072 * Revision 1.11 1999/09/30 02:55:10 rgb
2073 * Bogus skb detection.
2074 * Fix incorrect /proc/net/ipsec-eroute printk message.
2075 *
2076 * Revision 1.10 1999/09/21 15:22:13 rgb
2077 * Temporary fix while I figure out the right way to destroy sockets.
2078 *
2079 * Revision 1.9 1999/07/08 19:19:44 rgb
2080 * Fix pointer format warning.
2081 * Fix missing member error under 2.0.xx kernels.
2082 *
2083 * Revision 1.8 1999/06/13 07:24:04 rgb
2084 * Add more debugging.
2085 *
2086 * Revision 1.7 1999/06/10 05:24:17 rgb
2087 * Clarified compiler directives.
2088 * Renamed variables to reduce confusion.
2089 * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support.
2090 * Added lots of sanity checking.
2091 *
2092 * Revision 1.6 1999/06/03 18:59:50 rgb
2093 * More updates to 2.2.x socket support. Almost works, oops at end of call.
2094 *
2095 * Revision 1.5 1999/05/25 22:44:05 rgb
2096 * Start fixing 2.2 sockets.
2097 *
2098 * Revision 1.4 1999/04/29 15:21:34 rgb
2099 * Move log to the end of the file.
2100 * Eliminate min/max redefinition in #include <net/tcp.h>.
2101 * Correct path for pfkey #includes
2102 * Standardise an error return method.
2103 * Add debugging instrumentation.
2104 * Move message type checking to pfkey_msg_parse().
2105 * Add check for errno incorrectly set.
2106 * Add check for valid PID.
2107 * Add check for reserved illegally set.
2108 * Add check for message out of bounds.
2109 *
2110 * Revision 1.3 1999/04/15 17:58:07 rgb
2111 * Add RCSID labels.
2112 *
2113 * Revision 1.2 1999/04/15 15:37:26 rgb
2114 * Forward check changes from POST1_00 branch.
2115 *
2116 * Revision 1.1.2.2 1999/04/13 20:37:12 rgb
2117 * Header Title correction.
2118 *
2119 * Revision 1.1.2.1 1999/03/26 20:58:55 rgb
2120 * Add pfkeyv2 support to KLIPS.
2121 *
2122 *
2123 * RFC 2367
2124 * PF_KEY_v2 Key Management API
2125 */