2 * Common routines for IPsec SA maintenance routines.
4 * Copyright (C) 1996, 1997 John Ioannidis.
5 * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 * RCSID $Id: ipsec_sa.c,v 1.3 2004/06/13 19:57:50 as Exp $
19 * This is the file formerly known as "ipsec_xform.h"
23 #include <linux/config.h>
24 #include <linux/version.h>
25 #include <linux/kernel.h> /* printk() */
27 #include "freeswan/ipsec_param.h"
30 # include <linux/slab.h> /* kmalloc() */
31 #else /* MALLOC_SLAB */
32 # include <linux/malloc.h> /* kmalloc() */
33 #endif /* MALLOC_SLAB */
34 #include <linux/vmalloc.h> /* vmalloc() */
35 #include <linux/errno.h> /* error codes */
36 #include <linux/types.h> /* size_t */
37 #include <linux/interrupt.h> /* mark_bh */
39 #include <linux/netdevice.h> /* struct device, and other headers */
40 #include <linux/etherdevice.h> /* eth_type_trans */
41 #include <linux/ip.h> /* struct iphdr */
42 #include <linux/skbuff.h>
46 #include <linux/spinlock.h> /* *lock* */
47 #else /* SPINLOCK_23 */
48 #include <asm/spinlock.h> /* *lock* */
49 #endif /* SPINLOCK_23 */
52 #include <asm/uaccess.h>
53 #include <linux/in6.h>
55 #include <asm/checksum.h>
58 #include "freeswan/radij.h"
60 #include "freeswan/ipsec_stats.h"
61 #include "freeswan/ipsec_life.h"
62 #include "freeswan/ipsec_sa.h"
63 #include "freeswan/ipsec_xform.h"
65 #include "freeswan/ipsec_encap.h"
66 #include "freeswan/ipsec_radij.h"
67 #include "freeswan/ipsec_xform.h"
68 #include "freeswan/ipsec_ipe4.h"
69 #include "freeswan/ipsec_ah.h"
70 #include "freeswan/ipsec_esp.h"
75 #include "freeswan/ipsec_proto.h"
76 #include "freeswan/ipsec_alg.h"
79 #ifdef CONFIG_IPSEC_DEBUG
81 #endif /* CONFIG_IPSEC_DEBUG */
83 #define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
85 struct ipsec_sa
*ipsec_sadb_hash
[SADB_HASHMOD
];
87 spinlock_t tdb_lock
= SPIN_LOCK_UNLOCKED
;
92 struct ipsec_sadb ipsec_sadb
;
96 /* the sub table must be narrower (or equal) in bits than the variable type
97 in the main table to count the number of unused entries in it. */
99 int testSizeOf_refSubTable
:
100 ((sizeof(IPsecRefTableUnusedCount
) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH
? -1 : 1);
104 /* The field where the saref will be hosted in the skb must be wide enough to
105 accomodate the information it needs to store. */
107 int testSizeOf_refField
:
108 (IPSEC_SA_REF_HOST_FIELD_WIDTH
< IPSEC_SA_REF_TABLE_IDX_WIDTH
? -1 : 1 );
115 IPsecSAref_t SAref
= 258;
119 printk("klips_debug:ipsec_SAtest: "
120 "IPSEC_SA_REF_SUBTABLE_IDX_WIDTH=%u\n"
121 "IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES=%u\n"
122 "IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES=%u\n"
123 "IPSEC_SA_REF_HOST_FIELD_WIDTH=%lu\n"
124 "IPSEC_SA_REF_TABLE_MASK=%x\n"
125 "IPSEC_SA_REF_ENTRY_MASK=%x\n"
126 "IPsecSAref2table(%d)=%u\n"
127 "IPsecSAref2entry(%d)=%u\n"
128 "IPsecSAref2NFmark(%d)=%u\n"
129 "IPsecSAref2SA(%d)=%p\n"
130 "IPsecSA2SAref(%p)=%d\n"
132 IPSEC_SA_REF_SUBTABLE_IDX_WIDTH
,
133 IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES
,
134 IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES
,
135 (unsigned long) IPSEC_SA_REF_HOST_FIELD_WIDTH
,
136 IPSEC_SA_REF_TABLE_MASK
,
137 IPSEC_SA_REF_ENTRY_MASK
,
138 SAref
, IPsecSAref2table(SAref
),
139 SAref
, IPsecSAref2entry(SAref
),
140 SAref
, IPsecSAref2NFmark(SAref
),
141 SAref
, IPsecSAref2SA(SAref
),
142 (&ips
), IPsecSA2SAref((&ips
))
148 ipsec_SAref_recycle(void)
154 ipsec_sadb
.refFreeListHead
= -1;
155 ipsec_sadb
.refFreeListTail
= -1;
157 if(ipsec_sadb
.refFreeListCont
== IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES
* IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES
) {
158 KLIPS_PRINT(debug_xform
,
159 "klips_debug:ipsec_SAref_recycle: "
160 "end of table reached, continuing at start..\n");
161 ipsec_sadb
.refFreeListCont
= 0;
164 KLIPS_PRINT(debug_xform
,
165 "klips_debug:ipsec_SAref_recycle: "
166 "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n",
167 ipsec_sadb
.refFreeListCont
,
168 (ipsec_sadb
.refTable
[IPsecSAref2table(ipsec_sadb
.refFreeListCont
)] != NULL
) ? IPsecSAref2SA(ipsec_sadb
.refFreeListCont
) : NULL
,
169 IPsecSAref2table(ipsec_sadb
.refFreeListCont
),
170 IPsecSAref2entry(ipsec_sadb
.refFreeListCont
));
172 for(table
= IPsecSAref2table(ipsec_sadb
.refFreeListCont
);
173 table
< IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES
;
175 if(ipsec_sadb
.refTable
[table
] == NULL
) {
176 error
= ipsec_SArefSubTable_alloc(table
);
181 for(entry
= IPsecSAref2entry(ipsec_sadb
.refFreeListCont
);
182 entry
< IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES
;
184 if(ipsec_sadb
.refTable
[table
]->entry
[entry
] == NULL
) {
185 ipsec_sadb
.refFreeList
[++ipsec_sadb
.refFreeListTail
] = IPsecSArefBuild(table
, entry
);
186 if(ipsec_sadb
.refFreeListTail
== (IPSEC_SA_REF_FREELIST_NUM_ENTRIES
- 1)) {
187 ipsec_sadb
.refFreeListHead
= 0;
188 ipsec_sadb
.refFreeListCont
= ipsec_sadb
.refFreeList
[ipsec_sadb
.refFreeListTail
] + 1;
189 KLIPS_PRINT(debug_xform
,
190 "klips_debug:ipsec_SAref_recycle: "
191 "SArefFreeList refilled.\n");
198 if(ipsec_sadb
.refFreeListTail
== -1) {
199 KLIPS_PRINT(debug_xform
,
200 "klips_debug:ipsec_SAref_recycle: "
201 "out of room in the SArefTable.\n");
206 ipsec_sadb
.refFreeListHead
= 0;
207 ipsec_sadb
.refFreeListCont
= ipsec_sadb
.refFreeList
[ipsec_sadb
.refFreeListTail
] + 1;
208 KLIPS_PRINT(debug_xform
,
209 "klips_debug:ipsec_SAref_recycle: "
210 "SArefFreeList partly refilled to %d of %d.\n",
211 ipsec_sadb
.refFreeListTail
,
212 IPSEC_SA_REF_FREELIST_NUM_ENTRIES
);
217 ipsec_SArefSubTable_alloc(unsigned table
)
220 struct IPsecSArefSubTable
* SArefsub
;
222 KLIPS_PRINT(debug_xform
,
223 "klips_debug:ipsec_SArefSubTable_alloc: "
224 "allocating %lu bytes for table %u of %u.\n",
225 (unsigned long) (IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES
* sizeof(struct ipsec_sa
*)),
227 IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES
);
229 /* allocate another sub-table */
230 SArefsub
= vmalloc(IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES
* sizeof(struct ipsec_sa
*));
231 if(SArefsub
== NULL
) {
232 KLIPS_PRINT(debug_xform
,
233 "klips_debug:ipsec_SArefSubTable_alloc: "
234 "error allocating memory for table %u of %u!\n",
236 IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES
);
240 /* add this sub-table to the main table */
241 ipsec_sadb
.refTable
[table
] = SArefsub
;
243 /* initialise each element to NULL */
244 KLIPS_PRINT(debug_xform
,
245 "klips_debug:ipsec_SArefSubTable_alloc: "
246 "initialising %u elements (2 ^ %u) of table %u.\n",
247 IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES
,
248 IPSEC_SA_REF_SUBTABLE_IDX_WIDTH
,
250 for(entry
= 0; entry
< IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES
; entry
++) {
251 SArefsub
->entry
[entry
] = NULL
;
256 #endif /* IPSEC_SA_REF_CODE */
259 ipsec_saref_freelist_init(void)
263 KLIPS_PRINT(debug_xform
,
264 "klips_debug:ipsec_saref_freelist_init: "
265 "initialising %u elements of FreeList.\n",
266 IPSEC_SA_REF_FREELIST_NUM_ENTRIES
);
268 for(i
= 0; i
< IPSEC_SA_REF_FREELIST_NUM_ENTRIES
; i
++) {
269 ipsec_sadb
.refFreeList
[i
] = IPSEC_SAREF_NULL
;
271 ipsec_sadb
.refFreeListHead
= -1;
272 ipsec_sadb
.refFreeListCont
= 0;
273 ipsec_sadb
.refFreeListTail
= -1;
279 ipsec_sadb_init(void)
284 for(i
= 0; i
< SADB_HASHMOD
; i
++) {
285 ipsec_sadb_hash
[i
] = NULL
;
287 /* parts above are for the old style SADB hash table */
290 #if IPSEC_SA_REF_CODE
291 /* initialise SA reference table */
293 /* initialise the main table */
294 KLIPS_PRINT(debug_xform
,
295 "klips_debug:ipsec_sadb_init: "
296 "initialising main table of size %u (2 ^ %u).\n",
297 IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES
,
298 IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
);
301 for(table
= 0; table
< IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES
; table
++) {
302 ipsec_sadb
.refTable
[table
] = NULL
;
306 /* allocate the first sub-table */
307 error
= ipsec_SArefSubTable_alloc(0);
312 error
= ipsec_saref_freelist_init();
313 #endif /* IPSEC_SA_REF_CODE */
317 #if IPSEC_SA_REF_CODE
319 ipsec_SAref_alloc(int*error
) /* pass in error var by pointer */
323 KLIPS_PRINT(debug_xform
,
324 "klips_debug:ipsec_SAref_alloc: "
325 "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n",
326 ipsec_sadb
.refFreeListHead
,
327 ipsec_sadb
.refFreeListCont
,
328 ipsec_sadb
.refFreeListTail
,
329 IPSEC_SA_REF_FREELIST_NUM_ENTRIES
);
331 if(ipsec_sadb
.refFreeListHead
== -1) {
332 KLIPS_PRINT(debug_xform
,
333 "klips_debug:ipsec_SAref_alloc: "
334 "FreeList empty, recycling...\n");
335 *error
= ipsec_SAref_recycle();
337 return IPSEC_SAREF_NULL
;
341 SAref
= ipsec_sadb
.refFreeList
[ipsec_sadb
.refFreeListHead
];
342 if(SAref
== IPSEC_SAREF_NULL
) {
343 KLIPS_PRINT(debug_xform
,
344 "klips_debug:ipsec_SAref_alloc: "
345 "unexpected error, refFreeListHead = %d points to invalid entry.\n",
346 ipsec_sadb
.refFreeListHead
);
348 return IPSEC_SAREF_NULL
;
351 KLIPS_PRINT(debug_xform
,
352 "klips_debug:ipsec_SAref_alloc: "
353 "allocating SAref=%d, table=%u, entry=%u of %u.\n",
355 IPsecSAref2table(SAref
),
356 IPsecSAref2entry(SAref
),
357 IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES
* IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES
);
359 ipsec_sadb
.refFreeList
[ipsec_sadb
.refFreeListHead
] = IPSEC_SAREF_NULL
;
360 ipsec_sadb
.refFreeListHead
++;
361 if(ipsec_sadb
.refFreeListHead
> ipsec_sadb
.refFreeListTail
) {
362 KLIPS_PRINT(debug_xform
,
363 "klips_debug:ipsec_SAref_alloc: "
364 "last FreeList entry allocated, resetting list head to empty.\n");
365 ipsec_sadb
.refFreeListHead
= -1;
370 #endif /* IPSEC_SA_REF_CODE */
373 ipsec_sa_print(struct ipsec_sa
*ips
)
378 printk(KERN_INFO
"klips_debug: SA:");
383 printk(" ref=%d", ips
->ips_ref
);
384 printk(" refcount=%d", atomic_read(&ips
->ips_refcount
));
385 if(ips
->ips_hnext
!= NULL
) {
386 printk(" hnext=0p%p", ips
->ips_hnext
);
388 if(ips
->ips_inext
!= NULL
) {
389 printk(" inext=0p%p", ips
->ips_inext
);
391 if(ips
->ips_onext
!= NULL
) {
392 printk(" onext=0p%p", ips
->ips_onext
);
394 sa_len
= satoa(ips
->ips_said
, 0, sa
, SATOA_BUF
);
395 printk(" said=%s", sa_len
? sa
: " (error)");
397 printk(" seq=%u", ips
->ips_seq
);
400 printk(" pid=%u", ips
->ips_pid
);
402 if(ips
->ips_authalg
) {
403 printk(" authalg=%u", ips
->ips_authalg
);
405 if(ips
->ips_encalg
) {
406 printk(" encalg=%u", ips
->ips_encalg
);
408 printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips
));
409 if(ips
->ips_replaywin
) {
410 printk(" ooowin=%u", ips
->ips_replaywin
);
413 printk(" flags=%u", ips
->ips_flags
);
415 if(ips
->ips_addr_s
) {
416 char buf
[SUBNETTOA_BUF
];
417 addrtoa(((struct sockaddr_in
*)(ips
->ips_addr_s
))->sin_addr
,
418 0, buf
, sizeof(buf
));
419 printk(" src=%s", buf
);
421 if(ips
->ips_addr_d
) {
422 char buf
[SUBNETTOA_BUF
];
423 addrtoa(((struct sockaddr_in
*)(ips
->ips_addr_s
))->sin_addr
,
424 0, buf
, sizeof(buf
));
425 printk(" dst=%s", buf
);
427 if(ips
->ips_addr_p
) {
428 char buf
[SUBNETTOA_BUF
];
429 addrtoa(((struct sockaddr_in
*)(ips
->ips_addr_p
))->sin_addr
,
430 0, buf
, sizeof(buf
));
431 printk(" proxy=%s", buf
);
433 if(ips
->ips_key_bits_a
) {
434 printk(" key_bits_a=%u", ips
->ips_key_bits_a
);
436 if(ips
->ips_key_bits_e
) {
437 printk(" key_bits_e=%u", ips
->ips_key_bits_e
);
445 ipsec_sa_alloc(int*error
) /* pass in error var by pointer */
447 struct ipsec_sa
* ips
;
449 if((ips
= kmalloc(sizeof(*ips
), GFP_ATOMIC
) ) == NULL
) {
450 KLIPS_PRINT(debug_xform
,
451 "klips_debug:ipsec_sa_alloc: "
452 "memory allocation error\n");
456 memset((caddr_t
)ips
, 0, sizeof(*ips
));
457 #if IPSEC_SA_REF_CODE
458 ips
->ips_ref
= ipsec_SAref_alloc(error
); /* pass in error return by pointer */
459 KLIPS_PRINT(debug_xform
,
460 "klips_debug:ipsec_sa_alloc: "
461 "allocated %lu bytes for ipsec_sa struct=0p%p ref=%d.\n",
462 (unsigned long) sizeof(*ips
),
465 if(ips
->ips_ref
== IPSEC_SAREF_NULL
) {
467 KLIPS_PRINT(debug_xform
,
468 "klips_debug:ipsec_sa_alloc: "
469 "SAref allocation error\n");
473 atomic_inc(&ips
->ips_refcount
);
474 IPsecSAref2SA(ips
->ips_ref
) = ips
;
475 #endif /* IPSEC_SA_REF_CODE */
482 ipsec_sa_free(struct ipsec_sa
* ips
)
484 return ipsec_sa_wipe(ips
);
488 ipsec_sa_getbyid(struct sa_id
*said
)
491 struct ipsec_sa
*ips
;
496 KLIPS_PRINT(debug_xform
,
497 "klips_error:ipsec_sa_getbyid: "
498 "null pointer passed in!\n");
502 sa_len
= satoa(*said
, 0, sa
, SATOA_BUF
);
504 hashval
= (said
->spi
+said
->dst
.s_addr
+said
->proto
) % SADB_HASHMOD
;
506 KLIPS_PRINT(debug_xform
,
507 "klips_debug:ipsec_sa_getbyid: "
508 "linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n",
510 sa_len
? sa
: " (error)");
512 if((ips
= ipsec_sadb_hash
[hashval
]) == NULL
) {
513 KLIPS_PRINT(debug_xform
,
514 "klips_debug:ipsec_sa_getbyid: "
515 "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
517 sa_len
? sa
: " (error)");
521 for (; ips
; ips
= ips
->ips_hnext
) {
522 if ((ips
->ips_said
.spi
== said
->spi
) &&
523 (ips
->ips_said
.dst
.s_addr
== said
->dst
.s_addr
) &&
524 (ips
->ips_said
.proto
== said
->proto
)) {
525 atomic_inc(&ips
->ips_refcount
);
530 KLIPS_PRINT(debug_xform
,
531 "klips_debug:ipsec_sa_getbyid: "
532 "no entry in linked list for hash=%d of SA:%s.\n",
534 sa_len
? sa
: " (error)");
539 ipsec_sa_put(struct ipsec_sa
*ips
)
545 KLIPS_PRINT(debug_xform
,
546 "klips_error:ipsec_sa_put: "
547 "null pointer passed in!\n");
551 sa_len
= satoa(ips
->ips_said
, 0, sa
, SATOA_BUF
);
553 KLIPS_PRINT(debug_xform
,
554 "klips_debug:ipsec_sa_put: "
555 "ipsec_sa SA:%s, ref:%d reference count decremented.\n",
556 sa_len
? sa
: " (error)",
559 atomic_dec(&ips
->ips_refcount
);
565 The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen
568 ipsec_sa_add(struct ipsec_sa
*ips
)
571 unsigned int hashval
;
574 KLIPS_PRINT(debug_xform
,
575 "klips_error:ipsec_sa_add: "
576 "null pointer passed in!\n");
579 hashval
= ((ips
->ips_said
.spi
+ ips
->ips_said
.dst
.s_addr
+ ips
->ips_said
.proto
) % SADB_HASHMOD
);
581 atomic_inc(&ips
->ips_refcount
);
582 spin_lock_bh(&tdb_lock
);
584 ips
->ips_hnext
= ipsec_sadb_hash
[hashval
];
585 ipsec_sadb_hash
[hashval
] = ips
;
587 spin_unlock_bh(&tdb_lock
);
593 The ipsec_sa table better be locked before it is handed in, or races might happen
596 ipsec_sa_del(struct ipsec_sa
*ips
)
598 unsigned int hashval
;
599 struct ipsec_sa
*ipstp
;
604 KLIPS_PRINT(debug_xform
,
605 "klips_error:ipsec_sa_del: "
606 "null pointer passed in!\n");
610 sa_len
= satoa(ips
->ips_said
, 0, sa
, SATOA_BUF
);
611 if(ips
->ips_inext
|| ips
->ips_onext
) {
612 KLIPS_PRINT(debug_xform
,
613 "klips_error:ipsec_sa_del: "
614 "SA:%s still linked!\n",
615 sa_len
? sa
: " (error)");
619 hashval
= ((ips
->ips_said
.spi
+ ips
->ips_said
.dst
.s_addr
+ ips
->ips_said
.proto
) % SADB_HASHMOD
);
621 KLIPS_PRINT(debug_xform
,
622 "klips_debug:ipsec_sa_del: "
623 "deleting SA:%s, hashval=%d.\n",
624 sa_len
? sa
: " (error)",
626 if(ipsec_sadb_hash
[hashval
] == NULL
) {
627 KLIPS_PRINT(debug_xform
,
628 "klips_debug:ipsec_sa_del: "
629 "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
631 sa_len
? sa
: " (error)");
635 if (ips
== ipsec_sadb_hash
[hashval
]) {
636 ipsec_sadb_hash
[hashval
] = ipsec_sadb_hash
[hashval
]->ips_hnext
;
637 ips
->ips_hnext
= NULL
;
638 atomic_dec(&ips
->ips_refcount
);
639 KLIPS_PRINT(debug_xform
,
640 "klips_debug:ipsec_sa_del: "
641 "successfully deleted first ipsec_sa in chain.\n");
644 for (ipstp
= ipsec_sadb_hash
[hashval
];
646 ipstp
= ipstp
->ips_hnext
) {
647 if (ipstp
->ips_hnext
== ips
) {
648 ipstp
->ips_hnext
= ips
->ips_hnext
;
649 ips
->ips_hnext
= NULL
;
650 atomic_dec(&ips
->ips_refcount
);
651 KLIPS_PRINT(debug_xform
,
652 "klips_debug:ipsec_sa_del: "
653 "successfully deleted link in ipsec_sa chain.\n");
659 KLIPS_PRINT(debug_xform
,
660 "klips_debug:ipsec_sa_del: "
661 "no entries in linked list for hash=%d of SA:%s.\n",
663 sa_len
? sa
: " (error)");
668 The ipsec_sa table better be locked before it is handed in, or races
672 ipsec_sa_delchain(struct ipsec_sa
*ips
)
674 struct ipsec_sa
*ipsdel
;
680 KLIPS_PRINT(debug_xform
,
681 "klips_error:ipsec_sa_delchain: "
682 "null pointer passed in!\n");
686 sa_len
= satoa(ips
->ips_said
, 0, sa
, SATOA_BUF
);
687 KLIPS_PRINT(debug_xform
,
688 "klips_debug:ipsec_sa_delchain: "
690 sa_len
? sa
: " (error)");
691 while(ips
->ips_onext
!= NULL
) {
692 ips
= ips
->ips_onext
;
696 /* XXX send a pfkey message up to advise of deleted ipsec_sa */
697 sa_len
= satoa(ips
->ips_said
, 0, sa
, SATOA_BUF
);
698 KLIPS_PRINT(debug_xform
,
699 "klips_debug:ipsec_sa_delchain: "
700 "unlinking and delting SA:%s",
701 sa_len
? sa
: " (error)");
703 ips
= ips
->ips_inext
;
705 sa_len
= satoa(ips
->ips_said
, 0, sa
, SATOA_BUF
);
706 KLIPS_PRINT(debug_xform
,
708 sa_len
? sa
: " (error)");
709 atomic_dec(&ipsdel
->ips_refcount
);
710 ipsdel
->ips_inext
= NULL
;
711 atomic_dec(&ips
->ips_refcount
);
712 ips
->ips_onext
= NULL
;
714 KLIPS_PRINT(debug_xform
,
716 if((error
= ipsec_sa_del(ipsdel
))) {
717 KLIPS_PRINT(debug_xform
,
718 "klips_debug:ipsec_sa_delchain: "
719 "ipsec_sa_del returned error %d.\n", -error
);
722 if((error
= ipsec_sa_wipe(ipsdel
))) {
723 KLIPS_PRINT(debug_xform
,
724 "klips_debug:ipsec_sa_delchain: "
725 "ipsec_sa_wipe returned error %d.\n", -error
);
733 ipsec_sadb_cleanup(__u8 proto
)
737 struct ipsec_sa
*ips
, **ipsprev
, *ipsdel
;
741 KLIPS_PRINT(debug_xform
,
742 "klips_debug:ipsec_sadb_cleanup: "
743 "cleaning up proto=%d.\n",
746 spin_lock_bh(&tdb_lock
);
748 for (i
= 0; i
< SADB_HASHMOD
; i
++) {
749 ipsprev
= &(ipsec_sadb_hash
[i
]);
750 ips
= ipsec_sadb_hash
[i
];
752 atomic_inc(&ips
->ips_refcount
);
754 for(; ips
!= NULL
;) {
755 sa_len
= satoa(ips
->ips_said
, 0, sa
, SATOA_BUF
);
756 KLIPS_PRINT(debug_xform
,
757 "klips_debug:ipsec_sadb_cleanup: "
758 "checking SA:%s, hash=%d, ref=%d",
759 sa_len
? sa
: " (error)",
763 ips
= ipsdel
->ips_hnext
;
765 atomic_inc(&ips
->ips_refcount
);
766 sa_len
= satoa(ips
->ips_said
, 0, sa
, SATOA_BUF
);
767 KLIPS_PRINT(debug_xform
,
769 sa_len
? sa
: " (error)");
771 if(*ipsprev
!= NULL
) {
772 sa_len
= satoa((*ipsprev
)->ips_said
, 0, sa
, SATOA_BUF
);
773 KLIPS_PRINT(debug_xform
,
775 sa_len
? sa
: " (error)");
776 if((*ipsprev
)->ips_hnext
) {
777 sa_len
= satoa((*ipsprev
)->ips_hnext
->ips_said
, 0, sa
, SATOA_BUF
);
778 KLIPS_PRINT(debug_xform
,
779 ", *ipsprev->ips_hnext=%s",
780 sa_len
? sa
: " (error)");
783 KLIPS_PRINT(debug_xform
,
785 if(proto
== 0 || (proto
== ipsdel
->ips_said
.proto
)) {
786 sa_len
= satoa(ipsdel
->ips_said
, 0, sa
, SATOA_BUF
);
787 KLIPS_PRINT(debug_xform
,
788 "klips_debug:ipsec_sadb_cleanup: "
789 "deleting SA chain:%s.\n",
790 sa_len
? sa
: " (error)");
791 if((error
= ipsec_sa_delchain(ipsdel
))) {
794 ipsprev
= &(ipsec_sadb_hash
[i
]);
795 ips
= ipsec_sadb_hash
[i
];
797 KLIPS_PRINT(debug_xform
,
798 "klips_debug:ipsec_sadb_cleanup: "
799 "deleted SA chain:%s",
800 sa_len
? sa
: " (error)");
802 sa_len
= satoa(ips
->ips_said
, 0, sa
, SATOA_BUF
);
803 KLIPS_PRINT(debug_xform
,
804 ", ipsec_sadb_hash[%d]=%s",
806 sa_len
? sa
: " (error)");
808 if(*ipsprev
!= NULL
) {
809 sa_len
= satoa((*ipsprev
)->ips_said
, 0, sa
, SATOA_BUF
);
810 KLIPS_PRINT(debug_xform
,
812 sa_len
? sa
: " (error)");
813 if((*ipsprev
)->ips_hnext
!= NULL
) {
814 sa_len
= satoa((*ipsprev
)->ips_hnext
->ips_said
, 0, sa
, SATOA_BUF
);
815 KLIPS_PRINT(debug_xform
,
816 ", *ipsprev->ips_hnext=%s",
817 sa_len
? sa
: " (error)");
820 KLIPS_PRINT(debug_xform
,
826 ipsec_sa_put(ipsdel
);
832 spin_unlock_bh(&tdb_lock
);
835 #if IPSEC_SA_REF_CODE
836 /* clean up SA reference table */
838 /* go through the ref table and clean out all the SAs */
839 KLIPS_PRINT(debug_xform
,
840 "klips_debug:ipsec_sadb_cleanup: "
841 "removing SAref entries and tables.");
843 unsigned table
, entry
;
844 for(table
= 0; table
< IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES
; table
++) {
845 KLIPS_PRINT(debug_xform
,
846 "klips_debug:ipsec_sadb_cleanup: "
847 "cleaning SAref table=%u.\n",
849 if(ipsec_sadb
.refTable
[table
] == NULL
) {
851 KLIPS_PRINT(debug_xform
,
852 "klips_debug:ipsec_sadb_cleanup: "
853 "cleaned %u used refTables.\n",
857 for(entry
= 0; entry
< IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES
; entry
++) {
858 if(ipsec_sadb
.refTable
[table
]->entry
[entry
] != NULL
) {
859 ipsec_sa_delchain(ipsec_sadb
.refTable
[table
]->entry
[entry
]);
860 ipsec_sadb
.refTable
[table
]->entry
[entry
] = NULL
;
865 #endif /* IPSEC_SA_REF_CODE */
871 ipsec_sadb_free(void)
875 KLIPS_PRINT(debug_xform
,
876 "klips_debug:ipsec_sadb_free: "
877 "freeing SArefTable memory.\n");
879 /* clean up SA reference table */
881 /* go through the ref table and clean out all the SAs if any are
882 left and free table memory */
883 KLIPS_PRINT(debug_xform
,
884 "klips_debug:ipsec_sadb_free: "
885 "removing SAref entries and tables.\n");
887 unsigned table
, entry
;
888 for(table
= 0; table
< IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES
; table
++) {
889 KLIPS_PRINT(debug_xform
,
890 "klips_debug:ipsec_sadb_free: "
891 "removing SAref table=%u.\n",
893 if(ipsec_sadb
.refTable
[table
] == NULL
) {
894 KLIPS_PRINT(debug_xform
,
895 "klips_debug:ipsec_sadb_free: "
896 "removed %u used refTables.\n",
900 for(entry
= 0; entry
< IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES
; entry
++) {
901 if(ipsec_sadb
.refTable
[table
]->entry
[entry
] != NULL
) {
902 ipsec_sa_delchain(ipsec_sadb
.refTable
[table
]->entry
[entry
]);
903 ipsec_sadb
.refTable
[table
]->entry
[entry
] = NULL
;
906 vfree(ipsec_sadb
.refTable
[table
]);
907 ipsec_sadb
.refTable
[table
] = NULL
;
915 ipsec_sa_wipe(struct ipsec_sa
*ips
)
921 /* if(atomic_dec_and_test(ips)) {
924 #if IPSEC_SA_REF_CODE
925 /* remove me from the SArefTable */
929 sa_len
= satoa(ips
->ips_said
, 0, sa
, SATOA_BUF
);
930 KLIPS_PRINT(debug_xform
,
931 "klips_debug:ipsec_sa_wipe: "
932 "removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n",
933 sa_len
? sa
: " (error)",
936 IPsecSAref2table(IPsecSA2SAref(ips
)),
937 ipsec_sadb
.refTable
[IPsecSAref2table(IPsecSA2SAref(ips
))],
938 IPsecSAref2entry(IPsecSA2SAref(ips
)));
940 if(ips
->ips_ref
== IPSEC_SAREF_NULL
) {
941 KLIPS_PRINT(debug_xform
,
942 "klips_debug:ipsec_sa_wipe: "
943 "why does this SA not have a valid SAref?.\n");
945 ipsec_sadb
.refTable
[IPsecSAref2table(IPsecSA2SAref(ips
))]->entry
[IPsecSAref2entry(IPsecSA2SAref(ips
))] = NULL
;
946 ips
->ips_ref
= IPSEC_SAREF_NULL
;
948 #endif /* IPSEC_SA_REF_CODE */
950 /* paranoid clean up */
951 if(ips
->ips_addr_s
!= NULL
) {
952 memset((caddr_t
)(ips
->ips_addr_s
), 0, ips
->ips_addr_s_size
);
953 kfree(ips
->ips_addr_s
);
955 ips
->ips_addr_s
= NULL
;
957 if(ips
->ips_addr_d
!= NULL
) {
958 memset((caddr_t
)(ips
->ips_addr_d
), 0, ips
->ips_addr_d_size
);
959 kfree(ips
->ips_addr_d
);
961 ips
->ips_addr_d
= NULL
;
963 if(ips
->ips_addr_p
!= NULL
) {
964 memset((caddr_t
)(ips
->ips_addr_p
), 0, ips
->ips_addr_p_size
);
965 kfree(ips
->ips_addr_p
);
967 ips
->ips_addr_p
= NULL
;
969 #ifdef CONFIG_IPSEC_NAT_TRAVERSAL
970 if(ips
->ips_natt_oa
) {
971 memset((caddr_t
)(ips
->ips_natt_oa
), 0, ips
->ips_natt_oa_size
);
972 kfree(ips
->ips_natt_oa
);
974 ips
->ips_natt_oa
= NULL
;
977 if(ips
->ips_key_a
!= NULL
) {
978 memset((caddr_t
)(ips
->ips_key_a
), 0, ips
->ips_key_a_size
);
979 kfree(ips
->ips_key_a
);
981 ips
->ips_key_a
= NULL
;
983 if(ips
->ips_key_e
!= NULL
) {
984 #ifdef CONFIG_IPSEC_ALG
985 if (ips
->ips_alg_enc
&&ips
->ips_alg_enc
->ixt_e_destroy_key
) {
986 ips
->ips_alg_enc
->ixt_e_destroy_key(ips
->ips_alg_enc
,
989 #endif /* CONFIG_IPSEC_ALG */
990 memset((caddr_t
)(ips
->ips_key_e
), 0, ips
->ips_key_e_size
);
991 kfree(ips
->ips_key_e
);
992 #ifdef CONFIG_IPSEC_ALG
994 #endif /* CONFIG_IPSEC_ALG */
996 ips
->ips_key_e
= NULL
;
998 if(ips
->ips_iv
!= NULL
) {
999 memset((caddr_t
)(ips
->ips_iv
), 0, ips
->ips_iv_size
);
1004 if(ips
->ips_ident_s
.data
!= NULL
) {
1005 memset((caddr_t
)(ips
->ips_ident_s
.data
),
1007 ips
->ips_ident_s
.len
* IPSEC_PFKEYv2_ALIGN
- sizeof(struct sadb_ident
));
1008 kfree(ips
->ips_ident_s
.data
);
1010 ips
->ips_ident_s
.data
= NULL
;
1012 if(ips
->ips_ident_d
.data
!= NULL
) {
1013 memset((caddr_t
)(ips
->ips_ident_d
.data
),
1015 ips
->ips_ident_d
.len
* IPSEC_PFKEYv2_ALIGN
- sizeof(struct sadb_ident
));
1016 kfree(ips
->ips_ident_d
.data
);
1018 ips
->ips_ident_d
.data
= NULL
;
1020 #ifdef CONFIG_IPSEC_ALG
1021 if (ips
->ips_alg_enc
||ips
->ips_alg_auth
) {
1022 ipsec_alg_sa_wipe(ips
);
1024 #endif /* CONFIG_IPSEC_ALG */
1026 memset((caddr_t
)ips
, 0, sizeof(*ips
));