~ubuntu-branches/ubuntu/hardy/openswan/hardy-updates

« back to all changes in this revision

Viewing changes to debian/openswan-modules-source-build/modules/openswan/linux/net/ipsec/ipsec_sa.c

  • Committer: Bazaar Package Importer
  • Author(s): Rene Mayrhofer
  • Date: 2005-01-27 16:10:11 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050127161011-idgybmyz3vwhpfiq
Tags: 2.3.0-2
Urgency HIGH due to security issue and problems with build-deps in sarge.
* Fix the security issue. Please see
  http://www.idefense.com/application/poi/display?id=190&
      type=vulnerabilities&flashstatus=false
  for more details. Thanks to Martin Schulze for informing me about
  this issue.
  Closes: #292458: Openswan XAUTH/PAM Buffer Overflow Vulnerability
* Added a Build-Dependency to lynx.
  Closes: #291143: openswan: FTBFS: Missing build dependency.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Common routines for IPsec SA maintenance routines.
3
 
 *
4
 
 * Copyright (C) 1996, 1997  John Ioannidis.
5
 
 * Copyright (C) 1998, 1999, 2000, 2001, 2002  Richard Guy Briggs.
6
 
 * 
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>.
11
 
 * 
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
15
 
 * for more details.
16
 
 *
17
 
 * RCSID $Id: ipsec_sa.c,v 1.22 2003/12/10 01:14:27 mcr Exp $
18
 
 *
19
 
 * This is the file formerly known as "ipsec_xform.h"
20
 
 *
21
 
 */
22
 
 
23
 
#include <linux/config.h>
24
 
#include <linux/version.h>
25
 
#include <linux/kernel.h> /* printk() */
26
 
 
27
 
#include "freeswan/ipsec_param.h"
28
 
 
29
 
#ifdef MALLOC_SLAB
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 */
38
 
 
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>
43
 
#include <freeswan.h>
44
 
#ifdef SPINLOCK
45
 
#ifdef SPINLOCK_23
46
 
#include <linux/spinlock.h> /* *lock* */
47
 
#else /* SPINLOCK_23 */
48
 
#include <asm/spinlock.h> /* *lock* */
49
 
#endif /* SPINLOCK_23 */
50
 
#endif /* SPINLOCK */
51
 
#ifdef NET_21
52
 
#include <asm/uaccess.h>
53
 
#include <linux/in6.h>
54
 
#endif
55
 
#include <asm/checksum.h>
56
 
#include <net/ip.h>
57
 
 
58
 
#include "freeswan/radij.h"
59
 
 
60
 
#include "freeswan/ipsec_stats.h"
61
 
#include "freeswan/ipsec_life.h"
62
 
#include "freeswan/ipsec_sa.h"
63
 
#include "freeswan/ipsec_xform.h"
64
 
 
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"
71
 
 
72
 
#include <pfkeyv2.h>
73
 
#include <pfkey.h>
74
 
 
75
 
#include "freeswan/ipsec_proto.h"
76
 
 
77
 
 
78
 
#ifdef CONFIG_IPSEC_DEBUG
79
 
int debug_xform = 0;
80
 
#endif /* CONFIG_IPSEC_DEBUG */
81
 
 
82
 
#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
83
 
 
84
 
struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
85
 
#ifdef SPINLOCK
86
 
spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
87
 
#else /* SPINLOCK */
88
 
spinlock_t tdb_lock;
89
 
#endif /* SPINLOCK */
90
 
 
91
 
struct ipsec_sadb ipsec_sadb;
92
 
 
93
 
#if IPSEC_SA_REF_CODE
94
 
 
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. */
97
 
typedef struct {
98
 
        int testSizeOf_refSubTable :
99
 
                ((sizeof(IPsecRefTableUnusedCount) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH ? -1 : 1);
100
 
} dummy;
101
 
 
102
 
 
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. */
105
 
typedef struct {
106
 
        int testSizeOf_refField : 
107
 
                (IPSEC_SA_REF_HOST_FIELD_WIDTH < IPSEC_SA_REF_TABLE_IDX_WIDTH ? -1 : 1 );
108
 
} dummy2;
109
 
 
110
 
 
111
 
#define IPS_HASH(said) (((said)->spi + (said)->dst.u.v4.sin_addr.s_addr + (said)->proto) % SADB_HASHMOD)
112
 
 
113
 
 
114
 
void
115
 
ipsec_SAtest(void)
116
 
{
117
 
        IPsecSAref_t SAref = 258;
118
 
        struct ipsec_sa ips;
119
 
        ips.ips_ref = 772;
120
 
 
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"
133
 
               ,
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))
145
 
                );
146
 
        return;
147
 
}
148
 
 
149
 
int
150
 
ipsec_SAref_recycle(void)
151
 
{
152
 
        int table;
153
 
        int entry;
154
 
        int error = 0;
155
 
 
156
 
        ipsec_sadb.refFreeListHead = -1;
157
 
        ipsec_sadb.refFreeListTail = -1;
158
 
 
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;
164
 
        }
165
 
 
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));
173
 
 
174
 
        for(table = IPsecSAref2table(ipsec_sadb.refFreeListCont);
175
 
            table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES;
176
 
            table++) {
177
 
                if(ipsec_sadb.refTable[table] == NULL) {
178
 
                        error = ipsec_SArefSubTable_alloc(table);
179
 
                        if(error) {
180
 
                                return error;
181
 
                        }
182
 
                }
183
 
                for(entry = IPsecSAref2entry(ipsec_sadb.refFreeListCont);
184
 
                    entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES;
185
 
                    entry++) {
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");
194
 
                                        return 0;
195
 
                                }
196
 
                        }
197
 
                }
198
 
        }
199
 
 
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");
204
 
 
205
 
                return(-ENOSPC);
206
 
        }
207
 
 
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);
215
 
        return 0;
216
 
}
217
 
 
218
 
int
219
 
ipsec_SArefSubTable_alloc(unsigned table)
220
 
{
221
 
        unsigned entry;
222
 
        struct IPsecSArefSubTable* SArefsub;
223
 
 
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 *)),
228
 
                    table,
229
 
                    IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
230
 
 
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",
237
 
                            table,
238
 
                            IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
239
 
                return -ENOMEM;
240
 
        }
241
 
 
242
 
        /* add this sub-table to the main table */
243
 
        ipsec_sadb.refTable[table] = SArefsub;
244
 
 
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,
251
 
                    table);
252
 
        for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
253
 
                SArefsub->entry[entry] = NULL;
254
 
        }
255
 
 
256
 
        return 0;
257
 
}
258
 
#endif /* IPSEC_SA_REF_CODE */
259
 
 
260
 
int
261
 
ipsec_saref_freelist_init(void)
262
 
{
263
 
        int i;
264
 
 
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);
269
 
 
270
 
        for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) {
271
 
                ipsec_sadb.refFreeList[i] = IPSEC_SAREF_NULL;
272
 
        }
273
 
        ipsec_sadb.refFreeListHead = -1;
274
 
        ipsec_sadb.refFreeListCont = 0;
275
 
        ipsec_sadb.refFreeListTail = -1;
276
 
       
277
 
        return 0;
278
 
}
279
 
 
280
 
int
281
 
ipsec_sadb_init(void)
282
 
{
283
 
        int error = 0;
284
 
        unsigned i;
285
 
 
286
 
        for(i = 0; i < SADB_HASHMOD; i++) {
287
 
                ipsec_sadb_hash[i] = NULL;
288
 
        }
289
 
        /* parts above are for the old style SADB hash table */
290
 
        
291
 
 
292
 
#if IPSEC_SA_REF_CODE
293
 
        /* initialise SA reference table */
294
 
 
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);
301
 
        {
302
 
                unsigned table;
303
 
                for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
304
 
                        ipsec_sadb.refTable[table] = NULL;
305
 
                }
306
 
        }
307
 
 
308
 
        /* allocate the first sub-table */
309
 
        error = ipsec_SArefSubTable_alloc(0);
310
 
        if(error) {
311
 
                return error;
312
 
        }
313
 
 
314
 
        error = ipsec_saref_freelist_init();
315
 
#endif /* IPSEC_SA_REF_CODE */
316
 
        return error;
317
 
}
318
 
 
319
 
#if IPSEC_SA_REF_CODE
320
 
IPsecSAref_t
321
 
ipsec_SAref_alloc(int*error) /* pass in error var by pointer */
322
 
{
323
 
        IPsecSAref_t SAref;
324
 
 
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);
332
 
 
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();
338
 
                if(*error) {
339
 
                        return IPSEC_SAREF_NULL;
340
 
                }
341
 
        }
342
 
 
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);
349
 
                        *error = -ESPIPE;
350
 
                        return IPSEC_SAREF_NULL;
351
 
        }
352
 
 
353
 
        KLIPS_PRINT(debug_xform,
354
 
                    "klips_debug:ipsec_SAref_alloc: "
355
 
                    "allocating SAref=%d, table=%u, entry=%u of %u.\n",
356
 
                    SAref,
357
 
                    IPsecSAref2table(SAref),
358
 
                    IPsecSAref2entry(SAref),
359
 
                    IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES);
360
 
        
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;
368
 
        }
369
 
 
370
 
        return SAref;
371
 
}
372
 
#endif /* IPSEC_SA_REF_CODE */
373
 
 
374
 
int
375
 
ipsec_sa_print(struct ipsec_sa *ips)
376
 
{
377
 
        char sa[SATOT_BUF];
378
 
        size_t sa_len;
379
 
 
380
 
        printk(KERN_INFO "klips_debug:   SA:");
381
 
        if(ips == NULL) {
382
 
                printk("NULL\n");
383
 
                return -ENOENT;
384
 
        }
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);
389
 
        }
390
 
        if(ips->ips_inext != NULL) {
391
 
                printk(" inext=0p%p", ips->ips_inext);
392
 
        }
393
 
        if(ips->ips_onext != NULL) {
394
 
                printk(" onext=0p%p", ips->ips_onext);
395
 
        }
396
 
        sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
397
 
        printk(" said=%s", sa_len ? sa : " (error)");
398
 
        if(ips->ips_seq) {
399
 
                printk(" seq=%u", ips->ips_seq);
400
 
        }
401
 
        if(ips->ips_pid) {
402
 
                printk(" pid=%u", ips->ips_pid);
403
 
        }
404
 
        if(ips->ips_authalg) {
405
 
                printk(" authalg=%u", ips->ips_authalg);
406
 
        }
407
 
        if(ips->ips_encalg) {
408
 
                printk(" encalg=%u", ips->ips_encalg);
409
 
        }
410
 
        printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips));
411
 
        if(ips->ips_replaywin) {
412
 
                printk(" ooowin=%u", ips->ips_replaywin);
413
 
        }
414
 
        if(ips->ips_flags) {
415
 
                printk(" flags=%u", ips->ips_flags);
416
 
        }
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);
422
 
        }
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);
428
 
        }
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);
434
 
        }
435
 
        if(ips->ips_key_bits_a) {
436
 
                printk(" key_bits_a=%u", ips->ips_key_bits_a);
437
 
        }
438
 
        if(ips->ips_key_bits_e) {
439
 
                printk(" key_bits_e=%u", ips->ips_key_bits_e);
440
 
        }
441
 
 
442
 
        printk("\n");
443
 
        return 0;
444
 
}
445
 
 
446
 
struct ipsec_sa*
447
 
ipsec_sa_alloc(int*error) /* pass in error var by pointer */
448
 
{
449
 
        struct ipsec_sa* ips;
450
 
 
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");
455
 
                *error = -ENOMEM;
456
 
                return NULL;
457
 
        }
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),
465
 
                    ips,
466
 
                    ips->ips_ref);
467
 
        if(ips->ips_ref == IPSEC_SAREF_NULL) {
468
 
                kfree(ips);
469
 
                KLIPS_PRINT(debug_xform,
470
 
                            "klips_debug:ipsec_sa_alloc: "
471
 
                            "SAref allocation error\n");
472
 
                return NULL;
473
 
        }
474
 
 
475
 
        atomic_inc(&ips->ips_refcount);
476
 
        IPsecSAref2SA(ips->ips_ref) = ips;
477
 
#endif /* IPSEC_SA_REF_CODE */
478
 
 
479
 
        *error = 0;
480
 
        return(ips);
481
 
}
482
 
 
483
 
int
484
 
ipsec_sa_free(struct ipsec_sa* ips)
485
 
{
486
 
        return ipsec_sa_wipe(ips);
487
 
}
488
 
 
489
 
struct ipsec_sa *
490
 
ipsec_sa_getbyid(ip_said *said)
491
 
{
492
 
        int hashval;
493
 
        struct ipsec_sa *ips;
494
 
        char sa[SATOT_BUF];
495
 
        size_t sa_len;
496
 
 
497
 
        if(said == NULL) {
498
 
                KLIPS_PRINT(debug_xform,
499
 
                            "klips_error:ipsec_sa_getbyid: "
500
 
                            "null pointer passed in!\n");
501
 
                return NULL;
502
 
        }
503
 
 
504
 
        sa_len = satot(said, 0, sa, sizeof(sa));
505
 
 
506
 
        hashval = IPS_HASH(said);
507
 
        
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",
511
 
                    hashval,
512
 
                    sa_len ? sa : " (error)");
513
 
 
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",
518
 
                            hashval,
519
 
                            sa_len ? sa : " (error)");
520
 
                return NULL;
521
 
        }
522
 
 
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);
528
 
                        return ips;
529
 
                }
530
 
        }
531
 
        
532
 
        KLIPS_PRINT(debug_xform,
533
 
                    "klips_debug:ipsec_sa_getbyid: "
534
 
                    "no entry in linked list for hash=%d of SA:%s.\n",
535
 
                    hashval,
536
 
                    sa_len ? sa : " (error)");
537
 
        return NULL;
538
 
}
539
 
 
540
 
int
541
 
ipsec_sa_put(struct ipsec_sa *ips)
542
 
{
543
 
        char sa[SATOT_BUF];
544
 
        size_t sa_len;
545
 
 
546
 
        if(ips == NULL) {
547
 
                KLIPS_PRINT(debug_xform,
548
 
                            "klips_error:ipsec_sa_put: "
549
 
                            "null pointer passed in!\n");
550
 
                return -1;
551
 
        }
552
 
 
553
 
        sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
554
 
 
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)",
559
 
                    ips->ips_ref);
560
 
 
561
 
        atomic_dec(&ips->ips_refcount);
562
 
 
563
 
        return 0;
564
 
}
565
 
 
566
 
/*
567
 
  The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen
568
 
*/
569
 
int
570
 
ipsec_sa_add(struct ipsec_sa *ips)
571
 
{
572
 
        int error = 0;
573
 
        unsigned int hashval;
574
 
 
575
 
        if(ips == NULL) {
576
 
                KLIPS_PRINT(debug_xform,
577
 
                            "klips_error:ipsec_sa_add: "
578
 
                            "null pointer passed in!\n");
579
 
                return -ENODATA;
580
 
        }
581
 
        hashval = IPS_HASH(&ips->ips_said);
582
 
 
583
 
        atomic_inc(&ips->ips_refcount);
584
 
        spin_lock_bh(&tdb_lock);
585
 
        
586
 
        ips->ips_hnext = ipsec_sadb_hash[hashval];
587
 
        ipsec_sadb_hash[hashval] = ips;
588
 
        
589
 
        spin_unlock_bh(&tdb_lock);
590
 
 
591
 
        return error;
592
 
}
593
 
 
594
 
/*
595
 
  The ipsec_sa table better be locked before it is handed in, or races might happen
596
 
*/
597
 
int
598
 
ipsec_sa_del(struct ipsec_sa *ips)
599
 
{
600
 
        unsigned int hashval;
601
 
        struct ipsec_sa *ipstp;
602
 
        char sa[SATOT_BUF];
603
 
        size_t sa_len;
604
 
 
605
 
        if(ips == NULL) {
606
 
                KLIPS_PRINT(debug_xform,
607
 
                            "klips_error:ipsec_sa_del: "
608
 
                            "null pointer passed in!\n");
609
 
                return -ENODATA;
610
 
        }
611
 
        
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)");
618
 
                return -EMLINK;
619
 
        }
620
 
        
621
 
        hashval = IPS_HASH(&ips->ips_said);
622
 
        
623
 
        KLIPS_PRINT(debug_xform,
624
 
                    "klips_debug:ipsec_sa_del: "
625
 
                    "deleting SA:%s, hashval=%d.\n",
626
 
                    sa_len ? sa : " (error)",
627
 
                    hashval);
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",
632
 
                            hashval,
633
 
                            sa_len ? sa : " (error)");
634
 
                return -ENOENT;
635
 
        }
636
 
        
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");
644
 
                return 0;
645
 
        } else {
646
 
                for (ipstp = ipsec_sadb_hash[hashval];
647
 
                     ipstp;
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");
656
 
                                return 0;
657
 
                        }
658
 
                }
659
 
        }
660
 
        
661
 
        KLIPS_PRINT(debug_xform,
662
 
                    "klips_debug:ipsec_sa_del: "
663
 
                    "no entries in linked list for hash=%d of SA:%s.\n",
664
 
                    hashval,
665
 
                    sa_len ? sa : " (error)");
666
 
        return -ENOENT;
667
 
}
668
 
 
669
 
/*
670
 
  The ipsec_sa table better be locked before it is handed in, or races
671
 
  might happen
672
 
*/
673
 
int
674
 
ipsec_sa_delchain(struct ipsec_sa *ips)
675
 
{
676
 
        struct ipsec_sa *ipsdel;
677
 
        int error = 0;
678
 
        char sa[SATOT_BUF];
679
 
        size_t sa_len;
680
 
 
681
 
        if(ips == NULL) {
682
 
                KLIPS_PRINT(debug_xform,
683
 
                            "klips_error:ipsec_sa_delchain: "
684
 
                            "null pointer passed in!\n");
685
 
                return -ENODATA;
686
 
        }
687
 
 
688
 
        sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
689
 
        KLIPS_PRINT(debug_xform,
690
 
                    "klips_debug:ipsec_sa_delchain: "
691
 
                    "passed SA:%s\n",
692
 
                    sa_len ? sa : " (error)");
693
 
        while(ips->ips_onext != NULL) {
694
 
                ips = ips->ips_onext;
695
 
        }
696
 
 
697
 
        while(ips) {
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)");
704
 
                ipsdel = ips;
705
 
                ips = ips->ips_inext;
706
 
                if(ips != NULL) {
707
 
                        sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
708
 
                        KLIPS_PRINT(debug_xform,
709
 
                                    ", inext=%s",
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;
715
 
                }
716
 
                KLIPS_PRINT(debug_xform,
717
 
                            ".\n");
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);
722
 
                        return error;
723
 
                }
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);
728
 
                        return error;
729
 
                }
730
 
        }
731
 
        return error;
732
 
}
733
 
 
734
 
int 
735
 
ipsec_sadb_cleanup(__u8 proto)
736
 
{
737
 
        unsigned i;
738
 
        int error = 0;
739
 
        struct ipsec_sa *ips, **ipsprev, *ipsdel;
740
 
        char sa[SATOT_BUF];
741
 
        size_t sa_len;
742
 
 
743
 
        KLIPS_PRINT(debug_xform,
744
 
                    "klips_debug:ipsec_sadb_cleanup: "
745
 
                    "cleaning up proto=%d.\n",
746
 
                    proto);
747
 
 
748
 
        spin_lock_bh(&tdb_lock);
749
 
 
750
 
        for (i = 0; i < SADB_HASHMOD; i++) {
751
 
                ipsprev = &(ipsec_sadb_hash[i]);
752
 
                ips = ipsec_sadb_hash[i];
753
 
                if(ips != NULL) {
754
 
                        atomic_inc(&ips->ips_refcount);
755
 
                }
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)",
762
 
                                    i,
763
 
                                    ips->ips_ref);
764
 
                        ipsdel = ips;
765
 
                        ips = ipsdel->ips_hnext;
766
 
                        if(ips != NULL) {
767
 
                                atomic_inc(&ips->ips_refcount);
768
 
                                sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
769
 
                                KLIPS_PRINT(debug_xform,
770
 
                                            ", hnext=%s",
771
 
                                            sa_len ? sa : " (error)");
772
 
                        }
773
 
                        if(*ipsprev != NULL) {
774
 
                                sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));
775
 
                                KLIPS_PRINT(debug_xform,
776
 
                                            ", *ipsprev=%s",
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)");
783
 
                                }
784
 
                        }
785
 
                        KLIPS_PRINT(debug_xform,
786
 
                                    ".\n");
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))) {
794
 
                                        SENDERR(-error);
795
 
                                }
796
 
                                ipsprev = &(ipsec_sadb_hash[i]);
797
 
                                ips = ipsec_sadb_hash[i];
798
 
 
799
 
                                KLIPS_PRINT(debug_xform,
800
 
                                            "klips_debug:ipsec_sadb_cleanup: "
801
 
                                            "deleted SA chain:%s",
802
 
                                            sa_len ? sa : " (error)");
803
 
                                if(ips != NULL) {
804
 
                                        sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
805
 
                                        KLIPS_PRINT(debug_xform,
806
 
                                                    ", ipsec_sadb_hash[%d]=%s",
807
 
                                                    i,
808
 
                                                    sa_len ? sa : " (error)");
809
 
                                }
810
 
                                if(*ipsprev != NULL) {
811
 
                                        sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));
812
 
                                        KLIPS_PRINT(debug_xform,
813
 
                                                    ", *ipsprev=%s",
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)");
820
 
                                        }
821
 
                                }
822
 
                                KLIPS_PRINT(debug_xform,
823
 
                                            ".\n");
824
 
                        } else {
825
 
                                ipsprev = &ipsdel;
826
 
                        }
827
 
                        if(ipsdel != NULL) {
828
 
                                ipsec_sa_put(ipsdel);
829
 
                        }
830
 
                }
831
 
        }
832
 
 errlab:
833
 
 
834
 
        spin_unlock_bh(&tdb_lock);
835
 
 
836
 
 
837
 
#if IPSEC_SA_REF_CODE
838
 
        /* clean up SA reference table */
839
 
 
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.");
844
 
        {
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",
850
 
                                    table);
851
 
                        if(ipsec_sadb.refTable[table] == NULL) {
852
 
                                printk("\n");
853
 
                                KLIPS_PRINT(debug_xform,
854
 
                                            "klips_debug:ipsec_sadb_cleanup: "
855
 
                                            "cleaned %u used refTables.\n",
856
 
                                            table);
857
 
                                break;
858
 
                        }
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;
863
 
                                }
864
 
                        }
865
 
                }
866
 
        }
867
 
#endif /* IPSEC_SA_REF_CODE */
868
 
 
869
 
        return(error);
870
 
}
871
 
 
872
 
int 
873
 
ipsec_sadb_free(void)
874
 
{
875
 
        int error = 0;
876
 
 
877
 
        KLIPS_PRINT(debug_xform,
878
 
                    "klips_debug:ipsec_sadb_free: "
879
 
                    "freeing SArefTable memory.\n");
880
 
 
881
 
        /* clean up SA reference table */
882
 
 
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");
888
 
        {
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",
894
 
                                    table);
895
 
                        if(ipsec_sadb.refTable[table] == NULL) {
896
 
                                KLIPS_PRINT(debug_xform,
897
 
                                            "klips_debug:ipsec_sadb_free: "
898
 
                                            "removed %u used refTables.\n",
899
 
                                            table);
900
 
                                break;
901
 
                        }
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;
906
 
                                }
907
 
                        }
908
 
                        vfree(ipsec_sadb.refTable[table]);
909
 
                        ipsec_sadb.refTable[table] = NULL;
910
 
                }
911
 
        }
912
 
 
913
 
        return(error);
914
 
}
915
 
 
916
 
int
917
 
ipsec_sa_wipe(struct ipsec_sa *ips)
918
 
{
919
 
        if(ips == NULL) {
920
 
                return -ENODATA;
921
 
        }
922
 
 
923
 
        /* if(atomic_dec_and_test(ips)) {
924
 
        }; */
925
 
 
926
 
#if IPSEC_SA_REF_CODE
927
 
        /* remove me from the SArefTable */
928
 
        {
929
 
                char sa[SATOT_BUF];
930
 
                size_t sa_len;
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)",
936
 
                            ips,
937
 
                            ips->ips_ref,
938
 
                            IPsecSAref2table(IPsecSA2SAref(ips)),
939
 
                            ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))],
940
 
                            IPsecSAref2entry(IPsecSA2SAref(ips)));
941
 
        }
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");
946
 
        }
947
 
        ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))]->entry[IPsecSAref2entry(IPsecSA2SAref(ips))] = NULL;
948
 
        ips->ips_ref = IPSEC_SAREF_NULL;
949
 
        ipsec_sa_put(ips);
950
 
#endif /* IPSEC_SA_REF_CODE */
951
 
 
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);
956
 
        }
957
 
        ips->ips_addr_s = NULL;
958
 
 
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);
962
 
        }
963
 
        ips->ips_addr_d = NULL;
964
 
 
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);
968
 
        }
969
 
        ips->ips_addr_p = NULL;
970
 
 
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);
975
 
        }
976
 
        ips->ips_natt_oa = NULL;
977
 
#endif
978
 
 
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);
982
 
        }
983
 
        ips->ips_key_a = NULL;
984
 
 
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);
988
 
        }
989
 
        ips->ips_key_e = NULL;
990
 
 
991
 
        if(ips->ips_iv != NULL) {
992
 
                memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
993
 
                kfree(ips->ips_iv);
994
 
        }
995
 
        ips->ips_iv = NULL;
996
 
 
997
 
        if(ips->ips_ident_s.data != NULL) {
998
 
                memset((caddr_t)(ips->ips_ident_s.data),
999
 
                       0,
1000
 
                       ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
1001
 
                kfree(ips->ips_ident_s.data);
1002
 
        }
1003
 
        ips->ips_ident_s.data = NULL;
1004
 
        
1005
 
        if(ips->ips_ident_d.data != NULL) {
1006
 
                memset((caddr_t)(ips->ips_ident_d.data),
1007
 
                       0,
1008
 
                       ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
1009
 
                kfree(ips->ips_ident_d.data);
1010
 
        }
1011
 
        ips->ips_ident_d.data = NULL;
1012
 
        
1013
 
        memset((caddr_t)ips, 0, sizeof(*ips));
1014
 
        kfree(ips);
1015
 
        ips = NULL;
1016
 
 
1017
 
        return 0;
1018
 
}
1019
 
 
1020
 
/*
1021
 
 * $Log: ipsec_sa.c,v $
1022
 
 * Revision 1.22  2003/12/10 01:14:27  mcr
1023
 
 *      NAT-traversal patches to KLIPS.
1024
 
 *
1025
 
 * Revision 1.21  2003/10/31 02:27:55  mcr
1026
 
 *      pulled up port-selector patches and sa_id elimination.
1027
 
 *
1028
 
 * Revision 1.20.4.1  2003/10/29 01:30:41  mcr
1029
 
 *      elimited "struct sa_id".
1030
 
 *
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.
1033
 
 *
1034
 
 * Revision 1.19  2003/01/30 02:32:22  rgb
1035
 
 *
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.
1039
 
 *
1040
 
 * Revision 1.18  2002/10/12 23:11:53  dhr
1041
 
 *
1042
 
 * [KenB + DHR] more 64-bit cleanup
1043
 
 *
1044
 
 * Revision 1.17  2002/10/07 18:31:43  rgb
1045
 
 * Move field width sanity checks to ipsec_sa.c
1046
 
 *
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.
1058
 
 *
1059
 
 * Revision 1.15  2002/09/20 05:01:44  rgb
1060
 
 * Update copyright date.
1061
 
 *
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.
1065
 
 *
1066
 
 * Revision 1.13  2002/07/29 03:06:20  mcr
1067
 
 *      get rid of variable not used warnings.
1068
 
 *
1069
 
 * Revision 1.12  2002/07/26 08:48:31  rgb
1070
 
 * Added SA ref table code.
1071
 
 *
1072
 
 * Revision 1.11  2002/06/04 16:48:49  rgb
1073
 
 * Tidied up pointer code for processor independance.
1074
 
 *
1075
 
 * Revision 1.10  2002/05/23 07:16:17  rgb
1076
 
 * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
1077
 
 * Pointer clean-up.
1078
 
 * Added refcount code.
1079
 
 * Convert "usecount" to "refcount" to remove ambiguity.
1080
 
 *
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.
1087
 
 *
1088
 
 * Revision 1.8  2002/04/24 07:55:32  mcr
1089
 
 *      #include patches and Makefiles for post-reorg compilation.
1090
 
 *
1091
 
 * Revision 1.7  2002/04/24 07:36:30  mcr
1092
 
 * Moved from ./klips/net/ipsec/ipsec_sa.c,v
1093
 
 *
1094
 
 * Revision 1.6  2002/04/20 00:12:25  rgb
1095
 
 * Added esp IV CBC attack fix, disabled.
1096
 
 *
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.
1102
 
 *
1103
 
 * Revision 1.4  2002/01/29 04:00:52  mcr
1104
 
 *      more excise of kversions.h header.
1105
 
 *
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.
1110
 
 *
1111
 
 * Revision 1.2  2001/11/26 09:16:15  rgb
1112
 
 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
1113
 
 *
1114
 
 * Revision 1.1.2.2  2001/10/22 21:05:41  mcr
1115
 
 *      removed phony prototype for des_set_key.
1116
 
 *
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.
1121
 
 *
1122
 
 *
1123
 
 *
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)
1127
 
 *
1128
 
 * Revision 1.52  2001/06/14 19:35:11  rgb
1129
 
 * Update copyright date.
1130
 
 *
1131
 
 * Revision 1.51  2001/05/30 08:14:03  rgb
1132
 
 * Removed vestiges of esp-null transforms.
1133
 
 *
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().
1139
 
 *
1140
 
 * Revision 1.49  2001/04/19 18:56:17  rgb
1141
 
 * Fixed tdb table locking comments.
1142
 
 *
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.
1146
 
 *
1147
 
 * Revision 1.47  2000/11/06 04:32:08  rgb
1148
 
 * Ditched spin_lock_irqsave in favour of spin_lock_bh.
1149
 
 *
1150
 
 * Revision 1.46  2000/09/20 16:21:57  rgb
1151
 
 * Cleaned up ident string alloc/free.
1152
 
 *
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.
1156
 
 *
1157
 
 * Revision 1.44  2000/08/30 05:29:04  rgb
1158
 
 * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
1159
 
 *
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.
1162
 
 *
1163
 
 * Revision 1.42  2000/08/01 14:51:51  rgb
1164
 
 * Removed _all_ remaining traces of DES.
1165
 
 *
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.
1168
 
 *
1169
 
 * Revision 1.40  2000/06/28 05:50:11  rgb
1170
 
 * Actually set iv_bits.
1171
 
 *
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.
1175
 
 *
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
1178
 
 * compile noisy.
1179
 
 *
1180
 
 * Revision 1.37  2000/03/16 14:04:59  rgb
1181
 
 * Hardwired CONFIG_IPSEC_PFKEYv2 on.
1182
 
 *
1183
 
 * Revision 1.36  2000/01/26 10:11:28  rgb
1184
 
 * Fixed spacing in error text causing run-in words.
1185
 
 *
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.
1192
 
 *
1193
 
 * Revision 1.34  1999/12/08 00:04:19  rgb
1194
 
 * Fixed SA direction overwriting bug for netlink users.
1195
 
 *
1196
 
 * Revision 1.33  1999/12/01 22:16:44  rgb
1197
 
 * Minor formatting changes in ESP MD5 initialisation.
1198
 
 *
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
1203
 
 * in.
1204
 
 *
1205
 
 * Revision 1.31  1999/11/23 23:06:26  rgb
1206
 
 * Sort out pfkey and freeswan headers, putting them in a library path.
1207
 
 *
1208
 
 * Revision 1.30  1999/11/18 04:09:20  rgb
1209
 
 * Replaced all kernel version macros to shorter, readable form.
1210
 
 *
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.
1215
 
 *
1216
 
 * Revision 1.28  1999/10/18 20:04:01  rgb
1217
 
 * Clean-out unused cruft.
1218
 
 *
1219
 
 * Revision 1.27  1999/10/03 19:01:03  rgb
1220
 
 * Spinlock support for 2.3.xx and 2.0.xx kernels.
1221
 
 *
1222
 
 * Revision 1.26  1999/10/01 16:22:24  rgb
1223
 
 * Switch from assignment init. to functional init. of spinlocks.
1224
 
 *
1225
 
 * Revision 1.25  1999/10/01 15:44:54  rgb
1226
 
 * Move spinlock header include to 2.1> scope.
1227
 
 *
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.
1232
 
 *
1233
 
 * Revision 1.23  1999/05/25 22:42:12  rgb
1234
 
 * Add deltdbchain() debugging.
1235
 
 *
1236
 
 * Revision 1.22  1999/05/25 21:24:31  rgb
1237
 
 * Add debugging statements to deltdbchain().
1238
 
 *
1239
 
 * Revision 1.21  1999/05/25 03:51:48  rgb
1240
 
 * Refix error return code.
1241
 
 *
1242
 
 * Revision 1.20  1999/05/25 03:34:07  rgb
1243
 
 * Fix error return for flush.
1244
 
 *
1245
 
 * Revision 1.19  1999/05/09 03:25:37  rgb
1246
 
 * Fix bug introduced by 2.2 quick-and-dirty patch.
1247
 
 *
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>.
1250
 
 *
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
1260
 
 * structures.
1261
 
 *
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.
1264
 
 *
1265
 
 * Revision 1.15  1999/04/11 00:29:01  henry
1266
 
 * GPL boilerplate
1267
 
 *
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.
1271
 
 *
1272
 
 * Revision 1.13  1999/02/19 18:23:01  rgb
1273
 
 * Nix debug off compile warning.
1274
 
 *
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.
1281
 
 *
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.
1289
 
 *
1290
 
 * Revision 1.10  1999/01/22 06:28:55  rgb
1291
 
 * Cruft clean-out.
1292
 
 * Put random IV generation in kernel.
1293
 
 * Added algorithm switch code.
1294
 
 * Enhanced debugging.
1295
 
 * 64-bit clean-up.
1296
 
 *
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.
1300
 
 *
1301
 
 * Revision 1.8  1998/11/25 04:59:06  rgb
1302
 
 * Add conditionals for no IPIP tunnel code.
1303
 
 * Delete commented out code.
1304
 
 *
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.
1308
 
 *
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.
1312
 
 *
1313
 
 * Revision 1.5  1998/10/09 04:32:19  rgb
1314
 
 * Added 'klips_debug' prefix to all klips printk debug statements.
1315
 
 *
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.
1319
 
 *
1320
 
 * Revision 1.3  1998/07/09 17:45:31  rgb
1321
 
 * Clarify algorithm not available message.
1322
 
 *
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).
1327
 
 *
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
1331
 
 *
1332
 
 * Revision 1.3  1998/06/11 05:54:59  rgb
1333
 
 * Added transform version string pointer to xformsw initialisations.
1334
 
 *
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.
1340
 
 *
1341
 
 * Revision 1.1  1998/04/09 03:06:13  henry
1342
 
 * sources moved up from linux/net/ipsec
1343
 
 *
1344
 
 * Revision 1.1.1.1  1998/04/08 05:35:02  henry
1345
 
 * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
1346
 
 *
1347
 
 * Revision 0.5  1997/06/03 04:24:48  ji
1348
 
 * Added ESP-3DES-MD5-96
1349
 
 *
1350
 
 * Revision 0.4  1997/01/15 01:28:15  ji
1351
 
 * Added new transforms.
1352
 
 *
1353
 
 * Revision 0.3  1996/11/20 14:39:04  ji
1354
 
 * Minor cleanups.
1355
 
 * Rationalized debugging code.
1356
 
 *
1357
 
 * Revision 0.2  1996/11/02 00:18:33  ji
1358
 
 * First limited release.
1359
 
 *
1360
 
 *
1361
 
 */