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.22 2003/12/10 01:14:27 mcr 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"
78
#ifdef CONFIG_IPSEC_DEBUG
80
#endif /* CONFIG_IPSEC_DEBUG */
82
#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
84
struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
86
spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
91
struct ipsec_sadb ipsec_sadb;
95
/* the sub table must be narrower (or equal) in bits than the variable type
96
in the main table to count the number of unused entries in it. */
98
int testSizeOf_refSubTable :
99
((sizeof(IPsecRefTableUnusedCount) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH ? -1 : 1);
103
/* The field where the saref will be hosted in the skb must be wide enough to
104
accomodate the information it needs to store. */
106
int testSizeOf_refField :
107
(IPSEC_SA_REF_HOST_FIELD_WIDTH < IPSEC_SA_REF_TABLE_IDX_WIDTH ? -1 : 1 );
111
#define IPS_HASH(said) (((said)->spi + (said)->dst.u.v4.sin_addr.s_addr + (said)->proto) % SADB_HASHMOD)
117
IPsecSAref_t SAref = 258;
121
printk("klips_debug:ipsec_SAtest: "
122
"IPSEC_SA_REF_SUBTABLE_IDX_WIDTH=%u\n"
123
"IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES=%u\n"
124
"IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES=%u\n"
125
"IPSEC_SA_REF_HOST_FIELD_WIDTH=%lu\n"
126
"IPSEC_SA_REF_TABLE_MASK=%x\n"
127
"IPSEC_SA_REF_ENTRY_MASK=%x\n"
128
"IPsecSAref2table(%d)=%u\n"
129
"IPsecSAref2entry(%d)=%u\n"
130
"IPsecSAref2NFmark(%d)=%u\n"
131
"IPsecSAref2SA(%d)=%p\n"
132
"IPsecSA2SAref(%p)=%d\n"
134
IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
135
IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
136
IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
137
(unsigned long) IPSEC_SA_REF_HOST_FIELD_WIDTH,
138
IPSEC_SA_REF_TABLE_MASK,
139
IPSEC_SA_REF_ENTRY_MASK,
140
SAref, IPsecSAref2table(SAref),
141
SAref, IPsecSAref2entry(SAref),
142
SAref, IPsecSAref2NFmark(SAref),
143
SAref, IPsecSAref2SA(SAref),
144
(&ips), IPsecSA2SAref((&ips))
150
ipsec_SAref_recycle(void)
156
ipsec_sadb.refFreeListHead = -1;
157
ipsec_sadb.refFreeListTail = -1;
159
if(ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) {
160
KLIPS_PRINT(debug_xform,
161
"klips_debug:ipsec_SAref_recycle: "
162
"end of table reached, continuing at start..\n");
163
ipsec_sadb.refFreeListCont = 0;
166
KLIPS_PRINT(debug_xform,
167
"klips_debug:ipsec_SAref_recycle: "
168
"recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n",
169
ipsec_sadb.refFreeListCont,
170
(ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb.refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL,
171
IPsecSAref2table(ipsec_sadb.refFreeListCont),
172
IPsecSAref2entry(ipsec_sadb.refFreeListCont));
174
for(table = IPsecSAref2table(ipsec_sadb.refFreeListCont);
175
table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES;
177
if(ipsec_sadb.refTable[table] == NULL) {
178
error = ipsec_SArefSubTable_alloc(table);
183
for(entry = IPsecSAref2entry(ipsec_sadb.refFreeListCont);
184
entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES;
186
if(ipsec_sadb.refTable[table]->entry[entry] == NULL) {
187
ipsec_sadb.refFreeList[++ipsec_sadb.refFreeListTail] = IPsecSArefBuild(table, entry);
188
if(ipsec_sadb.refFreeListTail == (IPSEC_SA_REF_FREELIST_NUM_ENTRIES - 1)) {
189
ipsec_sadb.refFreeListHead = 0;
190
ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
191
KLIPS_PRINT(debug_xform,
192
"klips_debug:ipsec_SAref_recycle: "
193
"SArefFreeList refilled.\n");
200
if(ipsec_sadb.refFreeListTail == -1) {
201
KLIPS_PRINT(debug_xform,
202
"klips_debug:ipsec_SAref_recycle: "
203
"out of room in the SArefTable.\n");
208
ipsec_sadb.refFreeListHead = 0;
209
ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
210
KLIPS_PRINT(debug_xform,
211
"klips_debug:ipsec_SAref_recycle: "
212
"SArefFreeList partly refilled to %d of %d.\n",
213
ipsec_sadb.refFreeListTail,
214
IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
219
ipsec_SArefSubTable_alloc(unsigned table)
222
struct IPsecSArefSubTable* SArefsub;
224
KLIPS_PRINT(debug_xform,
225
"klips_debug:ipsec_SArefSubTable_alloc: "
226
"allocating %lu bytes for table %u of %u.\n",
227
(unsigned long) (IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)),
229
IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
231
/* allocate another sub-table */
232
SArefsub = vmalloc(IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *));
233
if(SArefsub == NULL) {
234
KLIPS_PRINT(debug_xform,
235
"klips_debug:ipsec_SArefSubTable_alloc: "
236
"error allocating memory for table %u of %u!\n",
238
IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
242
/* add this sub-table to the main table */
243
ipsec_sadb.refTable[table] = SArefsub;
245
/* initialise each element to NULL */
246
KLIPS_PRINT(debug_xform,
247
"klips_debug:ipsec_SArefSubTable_alloc: "
248
"initialising %u elements (2 ^ %u) of table %u.\n",
249
IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
250
IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
252
for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
253
SArefsub->entry[entry] = NULL;
258
#endif /* IPSEC_SA_REF_CODE */
261
ipsec_saref_freelist_init(void)
265
KLIPS_PRINT(debug_xform,
266
"klips_debug:ipsec_saref_freelist_init: "
267
"initialising %u elements of FreeList.\n",
268
IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
270
for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) {
271
ipsec_sadb.refFreeList[i] = IPSEC_SAREF_NULL;
273
ipsec_sadb.refFreeListHead = -1;
274
ipsec_sadb.refFreeListCont = 0;
275
ipsec_sadb.refFreeListTail = -1;
281
ipsec_sadb_init(void)
286
for(i = 0; i < SADB_HASHMOD; i++) {
287
ipsec_sadb_hash[i] = NULL;
289
/* parts above are for the old style SADB hash table */
292
#if IPSEC_SA_REF_CODE
293
/* initialise SA reference table */
295
/* initialise the main table */
296
KLIPS_PRINT(debug_xform,
297
"klips_debug:ipsec_sadb_init: "
298
"initialising main table of size %u (2 ^ %u).\n",
299
IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
300
IPSEC_SA_REF_MAINTABLE_IDX_WIDTH);
303
for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
304
ipsec_sadb.refTable[table] = NULL;
308
/* allocate the first sub-table */
309
error = ipsec_SArefSubTable_alloc(0);
314
error = ipsec_saref_freelist_init();
315
#endif /* IPSEC_SA_REF_CODE */
319
#if IPSEC_SA_REF_CODE
321
ipsec_SAref_alloc(int*error) /* pass in error var by pointer */
325
KLIPS_PRINT(debug_xform,
326
"klips_debug:ipsec_SAref_alloc: "
327
"SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n",
328
ipsec_sadb.refFreeListHead,
329
ipsec_sadb.refFreeListCont,
330
ipsec_sadb.refFreeListTail,
331
IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
333
if(ipsec_sadb.refFreeListHead == -1) {
334
KLIPS_PRINT(debug_xform,
335
"klips_debug:ipsec_SAref_alloc: "
336
"FreeList empty, recycling...\n");
337
*error = ipsec_SAref_recycle();
339
return IPSEC_SAREF_NULL;
343
SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead];
344
if(SAref == IPSEC_SAREF_NULL) {
345
KLIPS_PRINT(debug_xform,
346
"klips_debug:ipsec_SAref_alloc: "
347
"unexpected error, refFreeListHead = %d points to invalid entry.\n",
348
ipsec_sadb.refFreeListHead);
350
return IPSEC_SAREF_NULL;
353
KLIPS_PRINT(debug_xform,
354
"klips_debug:ipsec_SAref_alloc: "
355
"allocating SAref=%d, table=%u, entry=%u of %u.\n",
357
IPsecSAref2table(SAref),
358
IPsecSAref2entry(SAref),
359
IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES);
361
ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL;
362
ipsec_sadb.refFreeListHead++;
363
if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) {
364
KLIPS_PRINT(debug_xform,
365
"klips_debug:ipsec_SAref_alloc: "
366
"last FreeList entry allocated, resetting list head to empty.\n");
367
ipsec_sadb.refFreeListHead = -1;
372
#endif /* IPSEC_SA_REF_CODE */
375
ipsec_sa_print(struct ipsec_sa *ips)
380
printk(KERN_INFO "klips_debug: SA:");
385
printk(" ref=%d", ips->ips_ref);
386
printk(" refcount=%d", atomic_read(&ips->ips_refcount));
387
if(ips->ips_hnext != NULL) {
388
printk(" hnext=0p%p", ips->ips_hnext);
390
if(ips->ips_inext != NULL) {
391
printk(" inext=0p%p", ips->ips_inext);
393
if(ips->ips_onext != NULL) {
394
printk(" onext=0p%p", ips->ips_onext);
396
sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
397
printk(" said=%s", sa_len ? sa : " (error)");
399
printk(" seq=%u", ips->ips_seq);
402
printk(" pid=%u", ips->ips_pid);
404
if(ips->ips_authalg) {
405
printk(" authalg=%u", ips->ips_authalg);
407
if(ips->ips_encalg) {
408
printk(" encalg=%u", ips->ips_encalg);
410
printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips));
411
if(ips->ips_replaywin) {
412
printk(" ooowin=%u", ips->ips_replaywin);
415
printk(" flags=%u", ips->ips_flags);
417
if(ips->ips_addr_s) {
418
char buf[SUBNETTOA_BUF];
419
addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
420
0, buf, sizeof(buf));
421
printk(" src=%s", buf);
423
if(ips->ips_addr_d) {
424
char buf[SUBNETTOA_BUF];
425
addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
426
0, buf, sizeof(buf));
427
printk(" dst=%s", buf);
429
if(ips->ips_addr_p) {
430
char buf[SUBNETTOA_BUF];
431
addrtoa(((struct sockaddr_in*)(ips->ips_addr_p))->sin_addr,
432
0, buf, sizeof(buf));
433
printk(" proxy=%s", buf);
435
if(ips->ips_key_bits_a) {
436
printk(" key_bits_a=%u", ips->ips_key_bits_a);
438
if(ips->ips_key_bits_e) {
439
printk(" key_bits_e=%u", ips->ips_key_bits_e);
447
ipsec_sa_alloc(int*error) /* pass in error var by pointer */
449
struct ipsec_sa* ips;
451
if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) {
452
KLIPS_PRINT(debug_xform,
453
"klips_debug:ipsec_sa_alloc: "
454
"memory allocation error\n");
458
memset((caddr_t)ips, 0, sizeof(*ips));
459
#if IPSEC_SA_REF_CODE
460
ips->ips_ref = ipsec_SAref_alloc(error); /* pass in error return by pointer */
461
KLIPS_PRINT(debug_xform,
462
"klips_debug:ipsec_sa_alloc: "
463
"allocated %lu bytes for ipsec_sa struct=0p%p ref=%d.\n",
464
(unsigned long) sizeof(*ips),
467
if(ips->ips_ref == IPSEC_SAREF_NULL) {
469
KLIPS_PRINT(debug_xform,
470
"klips_debug:ipsec_sa_alloc: "
471
"SAref allocation error\n");
475
atomic_inc(&ips->ips_refcount);
476
IPsecSAref2SA(ips->ips_ref) = ips;
477
#endif /* IPSEC_SA_REF_CODE */
484
ipsec_sa_free(struct ipsec_sa* ips)
486
return ipsec_sa_wipe(ips);
490
ipsec_sa_getbyid(ip_said *said)
493
struct ipsec_sa *ips;
498
KLIPS_PRINT(debug_xform,
499
"klips_error:ipsec_sa_getbyid: "
500
"null pointer passed in!\n");
504
sa_len = satot(said, 0, sa, sizeof(sa));
506
hashval = IPS_HASH(said);
508
KLIPS_PRINT(debug_xform,
509
"klips_debug:ipsec_sa_getbyid: "
510
"linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n",
512
sa_len ? sa : " (error)");
514
if((ips = ipsec_sadb_hash[hashval]) == NULL) {
515
KLIPS_PRINT(debug_xform,
516
"klips_debug:ipsec_sa_getbyid: "
517
"no entries in ipsec_sa table for hash=%d of SA:%s.\n",
519
sa_len ? sa : " (error)");
523
for (; ips; ips = ips->ips_hnext) {
524
if ((ips->ips_said.spi == said->spi) &&
525
(ips->ips_said.dst.u.v4.sin_addr.s_addr == said->dst.u.v4.sin_addr.s_addr) &&
526
(ips->ips_said.proto == said->proto)) {
527
atomic_inc(&ips->ips_refcount);
532
KLIPS_PRINT(debug_xform,
533
"klips_debug:ipsec_sa_getbyid: "
534
"no entry in linked list for hash=%d of SA:%s.\n",
536
sa_len ? sa : " (error)");
541
ipsec_sa_put(struct ipsec_sa *ips)
547
KLIPS_PRINT(debug_xform,
548
"klips_error:ipsec_sa_put: "
549
"null pointer passed in!\n");
553
sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
555
KLIPS_PRINT(debug_xform,
556
"klips_debug:ipsec_sa_put: "
557
"ipsec_sa SA:%s, ref:%d reference count decremented.\n",
558
sa_len ? sa : " (error)",
561
atomic_dec(&ips->ips_refcount);
567
The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen
570
ipsec_sa_add(struct ipsec_sa *ips)
573
unsigned int hashval;
576
KLIPS_PRINT(debug_xform,
577
"klips_error:ipsec_sa_add: "
578
"null pointer passed in!\n");
581
hashval = IPS_HASH(&ips->ips_said);
583
atomic_inc(&ips->ips_refcount);
584
spin_lock_bh(&tdb_lock);
586
ips->ips_hnext = ipsec_sadb_hash[hashval];
587
ipsec_sadb_hash[hashval] = ips;
589
spin_unlock_bh(&tdb_lock);
595
The ipsec_sa table better be locked before it is handed in, or races might happen
598
ipsec_sa_del(struct ipsec_sa *ips)
600
unsigned int hashval;
601
struct ipsec_sa *ipstp;
606
KLIPS_PRINT(debug_xform,
607
"klips_error:ipsec_sa_del: "
608
"null pointer passed in!\n");
612
sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
613
if(ips->ips_inext || ips->ips_onext) {
614
KLIPS_PRINT(debug_xform,
615
"klips_error:ipsec_sa_del: "
616
"SA:%s still linked!\n",
617
sa_len ? sa : " (error)");
621
hashval = IPS_HASH(&ips->ips_said);
623
KLIPS_PRINT(debug_xform,
624
"klips_debug:ipsec_sa_del: "
625
"deleting SA:%s, hashval=%d.\n",
626
sa_len ? sa : " (error)",
628
if(ipsec_sadb_hash[hashval] == NULL) {
629
KLIPS_PRINT(debug_xform,
630
"klips_debug:ipsec_sa_del: "
631
"no entries in ipsec_sa table for hash=%d of SA:%s.\n",
633
sa_len ? sa : " (error)");
637
if (ips == ipsec_sadb_hash[hashval]) {
638
ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;
639
ips->ips_hnext = NULL;
640
atomic_dec(&ips->ips_refcount);
641
KLIPS_PRINT(debug_xform,
642
"klips_debug:ipsec_sa_del: "
643
"successfully deleted first ipsec_sa in chain.\n");
646
for (ipstp = ipsec_sadb_hash[hashval];
648
ipstp = ipstp->ips_hnext) {
649
if (ipstp->ips_hnext == ips) {
650
ipstp->ips_hnext = ips->ips_hnext;
651
ips->ips_hnext = NULL;
652
atomic_dec(&ips->ips_refcount);
653
KLIPS_PRINT(debug_xform,
654
"klips_debug:ipsec_sa_del: "
655
"successfully deleted link in ipsec_sa chain.\n");
661
KLIPS_PRINT(debug_xform,
662
"klips_debug:ipsec_sa_del: "
663
"no entries in linked list for hash=%d of SA:%s.\n",
665
sa_len ? sa : " (error)");
670
The ipsec_sa table better be locked before it is handed in, or races
674
ipsec_sa_delchain(struct ipsec_sa *ips)
676
struct ipsec_sa *ipsdel;
682
KLIPS_PRINT(debug_xform,
683
"klips_error:ipsec_sa_delchain: "
684
"null pointer passed in!\n");
688
sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
689
KLIPS_PRINT(debug_xform,
690
"klips_debug:ipsec_sa_delchain: "
692
sa_len ? sa : " (error)");
693
while(ips->ips_onext != NULL) {
694
ips = ips->ips_onext;
698
/* XXX send a pfkey message up to advise of deleted ipsec_sa */
699
sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
700
KLIPS_PRINT(debug_xform,
701
"klips_debug:ipsec_sa_delchain: "
702
"unlinking and delting SA:%s",
703
sa_len ? sa : " (error)");
705
ips = ips->ips_inext;
707
sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
708
KLIPS_PRINT(debug_xform,
710
sa_len ? sa : " (error)");
711
atomic_dec(&ipsdel->ips_refcount);
712
ipsdel->ips_inext = NULL;
713
atomic_dec(&ips->ips_refcount);
714
ips->ips_onext = NULL;
716
KLIPS_PRINT(debug_xform,
718
if((error = ipsec_sa_del(ipsdel))) {
719
KLIPS_PRINT(debug_xform,
720
"klips_debug:ipsec_sa_delchain: "
721
"ipsec_sa_del returned error %d.\n", -error);
724
if((error = ipsec_sa_wipe(ipsdel))) {
725
KLIPS_PRINT(debug_xform,
726
"klips_debug:ipsec_sa_delchain: "
727
"ipsec_sa_wipe returned error %d.\n", -error);
735
ipsec_sadb_cleanup(__u8 proto)
739
struct ipsec_sa *ips, **ipsprev, *ipsdel;
743
KLIPS_PRINT(debug_xform,
744
"klips_debug:ipsec_sadb_cleanup: "
745
"cleaning up proto=%d.\n",
748
spin_lock_bh(&tdb_lock);
750
for (i = 0; i < SADB_HASHMOD; i++) {
751
ipsprev = &(ipsec_sadb_hash[i]);
752
ips = ipsec_sadb_hash[i];
754
atomic_inc(&ips->ips_refcount);
756
for(; ips != NULL;) {
757
sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
758
KLIPS_PRINT(debug_xform,
759
"klips_debug:ipsec_sadb_cleanup: "
760
"checking SA:%s, hash=%d, ref=%d",
761
sa_len ? sa : " (error)",
765
ips = ipsdel->ips_hnext;
767
atomic_inc(&ips->ips_refcount);
768
sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
769
KLIPS_PRINT(debug_xform,
771
sa_len ? sa : " (error)");
773
if(*ipsprev != NULL) {
774
sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));
775
KLIPS_PRINT(debug_xform,
777
sa_len ? sa : " (error)");
778
if((*ipsprev)->ips_hnext) {
779
sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));
780
KLIPS_PRINT(debug_xform,
781
", *ipsprev->ips_hnext=%s",
782
sa_len ? sa : " (error)");
785
KLIPS_PRINT(debug_xform,
787
if(proto == 0 || (proto == ipsdel->ips_said.proto)) {
788
sa_len = satot(&ipsdel->ips_said, 0, sa, sizeof(sa));
789
KLIPS_PRINT(debug_xform,
790
"klips_debug:ipsec_sadb_cleanup: "
791
"deleting SA chain:%s.\n",
792
sa_len ? sa : " (error)");
793
if((error = ipsec_sa_delchain(ipsdel))) {
796
ipsprev = &(ipsec_sadb_hash[i]);
797
ips = ipsec_sadb_hash[i];
799
KLIPS_PRINT(debug_xform,
800
"klips_debug:ipsec_sadb_cleanup: "
801
"deleted SA chain:%s",
802
sa_len ? sa : " (error)");
804
sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
805
KLIPS_PRINT(debug_xform,
806
", ipsec_sadb_hash[%d]=%s",
808
sa_len ? sa : " (error)");
810
if(*ipsprev != NULL) {
811
sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));
812
KLIPS_PRINT(debug_xform,
814
sa_len ? sa : " (error)");
815
if((*ipsprev)->ips_hnext != NULL) {
816
sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));
817
KLIPS_PRINT(debug_xform,
818
", *ipsprev->ips_hnext=%s",
819
sa_len ? sa : " (error)");
822
KLIPS_PRINT(debug_xform,
828
ipsec_sa_put(ipsdel);
834
spin_unlock_bh(&tdb_lock);
837
#if IPSEC_SA_REF_CODE
838
/* clean up SA reference table */
840
/* go through the ref table and clean out all the SAs */
841
KLIPS_PRINT(debug_xform,
842
"klips_debug:ipsec_sadb_cleanup: "
843
"removing SAref entries and tables.");
845
unsigned table, entry;
846
for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
847
KLIPS_PRINT(debug_xform,
848
"klips_debug:ipsec_sadb_cleanup: "
849
"cleaning SAref table=%u.\n",
851
if(ipsec_sadb.refTable[table] == NULL) {
853
KLIPS_PRINT(debug_xform,
854
"klips_debug:ipsec_sadb_cleanup: "
855
"cleaned %u used refTables.\n",
859
for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
860
if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
861
ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
862
ipsec_sadb.refTable[table]->entry[entry] = NULL;
867
#endif /* IPSEC_SA_REF_CODE */
873
ipsec_sadb_free(void)
877
KLIPS_PRINT(debug_xform,
878
"klips_debug:ipsec_sadb_free: "
879
"freeing SArefTable memory.\n");
881
/* clean up SA reference table */
883
/* go through the ref table and clean out all the SAs if any are
884
left and free table memory */
885
KLIPS_PRINT(debug_xform,
886
"klips_debug:ipsec_sadb_free: "
887
"removing SAref entries and tables.\n");
889
unsigned table, entry;
890
for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
891
KLIPS_PRINT(debug_xform,
892
"klips_debug:ipsec_sadb_free: "
893
"removing SAref table=%u.\n",
895
if(ipsec_sadb.refTable[table] == NULL) {
896
KLIPS_PRINT(debug_xform,
897
"klips_debug:ipsec_sadb_free: "
898
"removed %u used refTables.\n",
902
for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
903
if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
904
ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
905
ipsec_sadb.refTable[table]->entry[entry] = NULL;
908
vfree(ipsec_sadb.refTable[table]);
909
ipsec_sadb.refTable[table] = NULL;
917
ipsec_sa_wipe(struct ipsec_sa *ips)
923
/* if(atomic_dec_and_test(ips)) {
926
#if IPSEC_SA_REF_CODE
927
/* remove me from the SArefTable */
931
sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
932
KLIPS_PRINT(debug_xform,
933
"klips_debug:ipsec_sa_wipe: "
934
"removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n",
935
sa_len ? sa : " (error)",
938
IPsecSAref2table(IPsecSA2SAref(ips)),
939
ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))],
940
IPsecSAref2entry(IPsecSA2SAref(ips)));
942
if(ips->ips_ref == IPSEC_SAREF_NULL) {
943
KLIPS_PRINT(debug_xform,
944
"klips_debug:ipsec_sa_wipe: "
945
"why does this SA not have a valid SAref?.\n");
947
ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))]->entry[IPsecSAref2entry(IPsecSA2SAref(ips))] = NULL;
948
ips->ips_ref = IPSEC_SAREF_NULL;
950
#endif /* IPSEC_SA_REF_CODE */
952
/* paranoid clean up */
953
if(ips->ips_addr_s != NULL) {
954
memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
955
kfree(ips->ips_addr_s);
957
ips->ips_addr_s = NULL;
959
if(ips->ips_addr_d != NULL) {
960
memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
961
kfree(ips->ips_addr_d);
963
ips->ips_addr_d = NULL;
965
if(ips->ips_addr_p != NULL) {
966
memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
967
kfree(ips->ips_addr_p);
969
ips->ips_addr_p = NULL;
971
#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
972
if(ips->ips_natt_oa) {
973
memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size);
974
kfree(ips->ips_natt_oa);
976
ips->ips_natt_oa = NULL;
979
if(ips->ips_key_a != NULL) {
980
memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
981
kfree(ips->ips_key_a);
983
ips->ips_key_a = NULL;
985
if(ips->ips_key_e != NULL) {
986
memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size);
987
kfree(ips->ips_key_e);
989
ips->ips_key_e = NULL;
991
if(ips->ips_iv != NULL) {
992
memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
997
if(ips->ips_ident_s.data != NULL) {
998
memset((caddr_t)(ips->ips_ident_s.data),
1000
ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
1001
kfree(ips->ips_ident_s.data);
1003
ips->ips_ident_s.data = NULL;
1005
if(ips->ips_ident_d.data != NULL) {
1006
memset((caddr_t)(ips->ips_ident_d.data),
1008
ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
1009
kfree(ips->ips_ident_d.data);
1011
ips->ips_ident_d.data = NULL;
1013
memset((caddr_t)ips, 0, sizeof(*ips));
1021
* $Log: ipsec_sa.c,v $
1022
* Revision 1.22 2003/12/10 01:14:27 mcr
1023
* NAT-traversal patches to KLIPS.
1025
* Revision 1.21 2003/10/31 02:27:55 mcr
1026
* pulled up port-selector patches and sa_id elimination.
1028
* Revision 1.20.4.1 2003/10/29 01:30:41 mcr
1029
* elimited "struct sa_id".
1031
* Revision 1.20 2003/02/06 01:50:34 rgb
1032
* Fixed initialisation bug for first sadb hash bucket that would only manifest itself on platforms where NULL != 0.
1034
* Revision 1.19 2003/01/30 02:32:22 rgb
1036
* Rename SAref table macro names for clarity.
1037
* Transmit error code through to caller from callee for better diagnosis of problems.
1038
* Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
1040
* Revision 1.18 2002/10/12 23:11:53 dhr
1042
* [KenB + DHR] more 64-bit cleanup
1044
* Revision 1.17 2002/10/07 18:31:43 rgb
1045
* Move field width sanity checks to ipsec_sa.c
1047
* Revision 1.16 2002/09/20 15:41:02 rgb
1048
* Re-wrote most of the SAref code to eliminate Entry pointers.
1049
* Added SAref code compiler directive switch.
1050
* Added a saref test function for testing macros.
1051
* Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
1052
* Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
1053
* of freeing newly created structures when clearing the reftable upon startup
1054
* to start from a known state.
1055
* Place all ipsec sadb globals into one struct.
1056
* Rework saref freelist.
1057
* Added memory allocation debugging.
1059
* Revision 1.15 2002/09/20 05:01:44 rgb
1060
* Update copyright date.
1062
* Revision 1.14 2002/08/13 19:01:25 mcr
1063
* patches from kenb to permit compilation of FreeSWAN on ia64.
1064
* des library patched to use proper DES_LONG type for ia64.
1066
* Revision 1.13 2002/07/29 03:06:20 mcr
1067
* get rid of variable not used warnings.
1069
* Revision 1.12 2002/07/26 08:48:31 rgb
1070
* Added SA ref table code.
1072
* Revision 1.11 2002/06/04 16:48:49 rgb
1073
* Tidied up pointer code for processor independance.
1075
* Revision 1.10 2002/05/23 07:16:17 rgb
1076
* Added ipsec_sa_put() for releasing an ipsec_sa refcount.
1078
* Added refcount code.
1079
* Convert "usecount" to "refcount" to remove ambiguity.
1081
* Revision 1.9 2002/05/14 02:34:49 rgb
1082
* Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
1083
* with "put" usage in the kernel.
1084
* Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
1085
* ipsec_sa or ipsec_sa.
1086
* Added some preliminary refcount code.
1088
* Revision 1.8 2002/04/24 07:55:32 mcr
1089
* #include patches and Makefiles for post-reorg compilation.
1091
* Revision 1.7 2002/04/24 07:36:30 mcr
1092
* Moved from ./klips/net/ipsec/ipsec_sa.c,v
1094
* Revision 1.6 2002/04/20 00:12:25 rgb
1095
* Added esp IV CBC attack fix, disabled.
1097
* Revision 1.5 2002/01/29 17:17:56 mcr
1098
* moved include of ipsec_param.h to after include of linux/kernel.h
1099
* otherwise, it seems that some option that is set in ipsec_param.h
1100
* screws up something subtle in the include path to kernel.h, and
1101
* it complains on the snprintf() prototype.
1103
* Revision 1.4 2002/01/29 04:00:52 mcr
1104
* more excise of kversions.h header.
1106
* Revision 1.3 2002/01/29 02:13:18 mcr
1107
* introduction of ipsec_kversion.h means that include of
1108
* ipsec_param.h must preceed any decisions about what files to
1109
* include to deal with differences in kernel source.
1111
* Revision 1.2 2001/11/26 09:16:15 rgb
1112
* Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
1114
* Revision 1.1.2.2 2001/10/22 21:05:41 mcr
1115
* removed phony prototype for des_set_key.
1117
* Revision 1.1.2.1 2001/09/25 02:24:57 mcr
1118
* struct tdb -> struct ipsec_sa.
1119
* sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
1120
* ipsec_xform.c removed. header file still contains useful things.
1124
* CLONED from ipsec_xform.c:
1125
* Revision 1.53 2001/09/08 21:13:34 rgb
1126
* Added pfkey ident extension support for ISAKMPd. (NetCelo)
1128
* Revision 1.52 2001/06/14 19:35:11 rgb
1129
* Update copyright date.
1131
* Revision 1.51 2001/05/30 08:14:03 rgb
1132
* Removed vestiges of esp-null transforms.
1134
* Revision 1.50 2001/05/03 19:43:18 rgb
1135
* Initialise error return variable.
1136
* Update SENDERR macro.
1137
* Fix sign of error return code for ipsec_tdbcleanup().
1138
* Use more appropriate return code for ipsec_tdbwipe().
1140
* Revision 1.49 2001/04/19 18:56:17 rgb
1141
* Fixed tdb table locking comments.
1143
* Revision 1.48 2001/02/27 22:24:55 rgb
1144
* Re-formatting debug output (line-splitting, joining, 1arg/line).
1145
* Check for satoa() return codes.
1147
* Revision 1.47 2000/11/06 04:32:08 rgb
1148
* Ditched spin_lock_irqsave in favour of spin_lock_bh.
1150
* Revision 1.46 2000/09/20 16:21:57 rgb
1151
* Cleaned up ident string alloc/free.
1153
* Revision 1.45 2000/09/08 19:16:51 rgb
1154
* Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
1155
* Removed all references to CONFIG_IPSEC_PFKEYv2.
1157
* Revision 1.44 2000/08/30 05:29:04 rgb
1158
* Compiler-define out no longer used tdb_init() in ipsec_xform.c.
1160
* Revision 1.43 2000/08/18 21:30:41 rgb
1161
* Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
1163
* Revision 1.42 2000/08/01 14:51:51 rgb
1164
* Removed _all_ remaining traces of DES.
1166
* Revision 1.41 2000/07/28 14:58:31 rgb
1167
* Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
1169
* Revision 1.40 2000/06/28 05:50:11 rgb
1170
* Actually set iv_bits.
1172
* Revision 1.39 2000/05/10 23:11:09 rgb
1173
* Added netlink debugging output.
1174
* Added a cast to quiet down the ntohl bug.
1176
* Revision 1.38 2000/05/10 19:18:42 rgb
1177
* Cast output of ntohl so that the broken prototype doesn't make our
1180
* Revision 1.37 2000/03/16 14:04:59 rgb
1181
* Hardwired CONFIG_IPSEC_PFKEYv2 on.
1183
* Revision 1.36 2000/01/26 10:11:28 rgb
1184
* Fixed spacing in error text causing run-in words.
1186
* Revision 1.35 2000/01/21 06:17:16 rgb
1187
* Tidied up compiler directive indentation for readability.
1188
* Added ictx,octx vars for simplification.(kravietz)
1189
* Added macros for HMAC padding magic numbers.(kravietz)
1190
* Fixed missing key length reporting bug.
1191
* Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
1193
* Revision 1.34 1999/12/08 00:04:19 rgb
1194
* Fixed SA direction overwriting bug for netlink users.
1196
* Revision 1.33 1999/12/01 22:16:44 rgb
1197
* Minor formatting changes in ESP MD5 initialisation.
1199
* Revision 1.32 1999/11/25 09:06:36 rgb
1200
* Fixed error return messages, should be returning negative numbers.
1201
* Implemented SENDERR macro for propagating error codes.
1202
* Added debug message and separate error code for algorithms not compiled
1205
* Revision 1.31 1999/11/23 23:06:26 rgb
1206
* Sort out pfkey and freeswan headers, putting them in a library path.
1208
* Revision 1.30 1999/11/18 04:09:20 rgb
1209
* Replaced all kernel version macros to shorter, readable form.
1211
* Revision 1.29 1999/11/17 15:53:40 rgb
1212
* Changed all occurrences of #include "../../../lib/freeswan.h"
1213
* to #include <freeswan.h> which works due to -Ilibfreeswan in the
1214
* klips/net/ipsec/Makefile.
1216
* Revision 1.28 1999/10/18 20:04:01 rgb
1217
* Clean-out unused cruft.
1219
* Revision 1.27 1999/10/03 19:01:03 rgb
1220
* Spinlock support for 2.3.xx and 2.0.xx kernels.
1222
* Revision 1.26 1999/10/01 16:22:24 rgb
1223
* Switch from assignment init. to functional init. of spinlocks.
1225
* Revision 1.25 1999/10/01 15:44:54 rgb
1226
* Move spinlock header include to 2.1> scope.
1228
* Revision 1.24 1999/10/01 00:03:46 rgb
1229
* Added tdb structure locking.
1230
* Minor formatting changes.
1231
* Add function to initialize tdb hash table.
1233
* Revision 1.23 1999/05/25 22:42:12 rgb
1234
* Add deltdbchain() debugging.
1236
* Revision 1.22 1999/05/25 21:24:31 rgb
1237
* Add debugging statements to deltdbchain().
1239
* Revision 1.21 1999/05/25 03:51:48 rgb
1240
* Refix error return code.
1242
* Revision 1.20 1999/05/25 03:34:07 rgb
1243
* Fix error return for flush.
1245
* Revision 1.19 1999/05/09 03:25:37 rgb
1246
* Fix bug introduced by 2.2 quick-and-dirty patch.
1248
* Revision 1.18 1999/05/05 22:02:32 rgb
1249
* Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
1251
* Revision 1.17 1999/04/29 15:20:16 rgb
1252
* Change gettdb parameter to a pointer to reduce stack loading and
1253
* facilitate parameter sanity checking.
1254
* Add sanity checking for null pointer arguments.
1255
* Add debugging instrumentation.
1256
* Add function deltdbchain() which will take care of unlinking,
1257
* zeroing and deleting a chain of tdbs.
1258
* Add a parameter to tdbcleanup to be able to delete a class of SAs.
1259
* tdbwipe now actually zeroes the tdb as well as any of its pointed
1262
* Revision 1.16 1999/04/16 15:36:29 rgb
1263
* Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
1265
* Revision 1.15 1999/04/11 00:29:01 henry
1268
* Revision 1.14 1999/04/06 04:54:28 rgb
1269
* Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
1270
* patch shell fixes.
1272
* Revision 1.13 1999/02/19 18:23:01 rgb
1273
* Nix debug off compile warning.
1275
* Revision 1.12 1999/02/17 16:52:16 rgb
1276
* Consolidate satoa()s for space and speed efficiency.
1277
* Convert DEBUG_IPSEC to KLIPS_PRINT
1278
* Clean out unused cruft.
1279
* Ditch NET_IPIP dependancy.
1280
* Loop for 3des key setting.
1282
* Revision 1.11 1999/01/26 02:09:05 rgb
1283
* Remove ah/esp/IPIP switching on include files.
1284
* Removed CONFIG_IPSEC_ALGO_SWITCH macro.
1285
* Removed dead code.
1286
* Clean up debug code when switched off.
1287
* Remove references to INET_GET_PROTOCOL.
1288
* Added code exclusion macros to reduce code from unused algorithms.
1290
* Revision 1.10 1999/01/22 06:28:55 rgb
1292
* Put random IV generation in kernel.
1293
* Added algorithm switch code.
1294
* Enhanced debugging.
1297
* Revision 1.9 1998/11/30 13:22:55 rgb
1298
* Rationalised all the klips kernel file headers. They are much shorter
1299
* now and won't conflict under RH5.2.
1301
* Revision 1.8 1998/11/25 04:59:06 rgb
1302
* Add conditionals for no IPIP tunnel code.
1303
* Delete commented out code.
1305
* Revision 1.7 1998/10/31 06:50:41 rgb
1306
* Convert xform ASCII names to no spaces.
1307
* Fixed up comments in #endif directives.
1309
* Revision 1.6 1998/10/19 14:44:28 rgb
1310
* Added inclusion of freeswan.h.
1311
* sa_id structure implemented and used: now includes protocol.
1313
* Revision 1.5 1998/10/09 04:32:19 rgb
1314
* Added 'klips_debug' prefix to all klips printk debug statements.
1316
* Revision 1.4 1998/08/12 00:11:31 rgb
1317
* Added new xform functions to the xform table.
1318
* Fixed minor debug output spelling error.
1320
* Revision 1.3 1998/07/09 17:45:31 rgb
1321
* Clarify algorithm not available message.
1323
* Revision 1.2 1998/06/23 03:00:51 rgb
1324
* Check for presence of IPIP protocol if it is setup one way (we don't
1325
* know what has been set up the other way and can only assume it will be
1326
* symmetrical with the exception of keys).
1328
* Revision 1.1 1998/06/18 21:27:51 henry
1329
* move sources from klips/src to klips/net/ipsec, to keep stupid
1330
* kernel-build scripts happier in the presence of symlinks
1332
* Revision 1.3 1998/06/11 05:54:59 rgb
1333
* Added transform version string pointer to xformsw initialisations.
1335
* Revision 1.2 1998/04/21 21:28:57 rgb
1336
* Rearrange debug switches to change on the fly debug output from user
1337
* space. Only kernel changes checked in at this time. radij.c was also
1338
* changed to temporarily remove buggy debugging code in rj_delete causing
1339
* an OOPS and hence, netlink device open errors.
1341
* Revision 1.1 1998/04/09 03:06:13 henry
1342
* sources moved up from linux/net/ipsec
1344
* Revision 1.1.1.1 1998/04/08 05:35:02 henry
1345
* RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
1347
* Revision 0.5 1997/06/03 04:24:48 ji
1348
* Added ESP-3DES-MD5-96
1350
* Revision 0.4 1997/01/15 01:28:15 ji
1351
* Added new transforms.
1353
* Revision 0.3 1996/11/20 14:39:04 ji
1355
* Rationalized debugging code.
1357
* Revision 0.2 1996/11/02 00:18:33 ji
1358
* First limited release.