int ipsec_sadb_init(void) { int error = 0; unsigned i; for (i = 0; i < SADB_HASHMOD; i++) ipsec_sadb_hash[i] = NULL; /* parts above are for the old style SADB hash table */ /* initialise SA reference table */ /* initialise the main table */ KLIPS_PRINT(debug_xform, "klips_debug:ipsec_sadb_init: " "initialising main table of size %u (2 ^ %u).\n", IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES, IPSEC_SA_REF_MAINTABLE_IDX_WIDTH); { unsigned table; for (table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) ipsec_sadb.refTable[table] = NULL; } /* allocate the first sub-table */ error = ipsec_SArefSubTable_alloc(0); if (error) return error; error = ipsec_saref_freelist_init(); return error; }
static int ipsec_saref_verify_slot(IPsecSAref_t ref) { int ref_table = IPsecSAref2table(ref); if (ipsec_sadb.refTable[ref_table] == NULL) return ipsec_SArefSubTable_alloc(ref_table); return 0; }
static int ipsec_SAref_recycle(void) { int table, i; int error = 0; int entry; int addone; ipsec_sadb.refFreeListHead = IPSEC_SAREF_NULL; ipsec_sadb.refFreeListTail = IPSEC_SAREF_NULL; KLIPS_PRINT(debug_xform, "klips_debug:ipsec_SAref_recycle: " "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n", ipsec_sadb.refFreeListCont, (ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb. refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL, IPsecSAref2table(ipsec_sadb.refFreeListCont), IPsecSAref2entry(ipsec_sadb.refFreeListCont)); /* add one additional table entry */ addone = 0; for (i = 0; i < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; i++) { if (ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) { KLIPS_PRINT(debug_xform, "klips_debug:ipsec_SAref_recycle: " "end of table reached, continuing at start..\n"); ipsec_sadb.refFreeListCont = IPSEC_SAREF_FIRST; } table = IPsecSAref2table(ipsec_sadb.refFreeListCont); if (ipsec_sadb.refTable[table] == NULL) { if (addone == 0) { addone = 1; error = ipsec_SArefSubTable_alloc(table); if (error) return error; else break; } } for (entry = IPsecSAref2entry(ipsec_sadb.refFreeListCont); entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) { if (ipsec_sadb.refTable[table]->entry[entry] == NULL) { ipsec_sadb.refFreeList[++ipsec_sadb. refFreeListTail] = IPsecSArefBuild(table, entry); if (ipsec_sadb.refFreeListTail == (IPSEC_SA_REF_FREELIST_NUM_ENTRIES - 1)) { ipsec_sadb.refFreeListHead = IPSEC_SAREF_FIRST; ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ ipsec_sadb. refFreeListTail ] + 1; KLIPS_PRINT(debug_xform, "klips_debug:ipsec_SAref_recycle: " "SArefFreeList refilled.\n"); return 0; } } ipsec_sadb.refFreeListCont++; } } if (ipsec_sadb.refFreeListTail == IPSEC_SAREF_NULL) { KLIPS_PRINT(debug_xform, "klips_debug:ipsec_SAref_recycle: " "out of room in the SArefTable.\n"); return -ENOSPC; } ipsec_sadb.refFreeListHead = IPSEC_SAREF_FIRST; ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1; KLIPS_PRINT(debug_xform, "klips_debug:ipsec_SAref_recycle: " "SArefFreeList partly refilled to %d of %d.\n", ipsec_sadb.refFreeListTail, IPSEC_SA_REF_FREELIST_NUM_ENTRIES); return 0; }
int ipsec_SAref_recycle(void) { int table, i; int error = 0; int addone; ipsec_sadb.refFreeListHead = IPSEC_SAREF_NULL; ipsec_sadb.refFreeListTail = IPSEC_SAREF_NULL; if(ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) { KLIPS_PRINT(debug_xform, "klips_debug:ipsec_SAref_recycle: " "end of table reached, continuing at start..\n"); ipsec_sadb.refFreeListCont = IPSEC_SAREF_FIRST; } KLIPS_PRINT(debug_xform, "klips_debug:ipsec_SAref_recycle: " "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n", ipsec_sadb.refFreeListCont, (ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb.refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL, IPsecSAref2table(ipsec_sadb.refFreeListCont), IPsecSAref2entry(ipsec_sadb.refFreeListCont)); /* add one additional table entry */ addone = 0; ipsec_sadb.refFreeListHead = IPSEC_SAREF_FIRST; for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) { table = IPsecSAref2table(ipsec_sadb.refFreeListCont); if(addone == 0 && ipsec_sadb.refTable[table] == NULL) { addone = 1; error = ipsec_SArefSubTable_alloc(table); if(error) { return error; } } if(ipsec_sadb.refTable[table] == NULL) { /* we failed to add a second table, so just stop */ break; } if(IPsecSAref2SA(ipsec_sadb.refFreeListCont) == NULL) { ipsec_sadb.refFreeList[i] = ipsec_sadb.refFreeListCont; } ipsec_sadb.refFreeListCont++; ipsec_sadb.refFreeListTail=i; } if(ipsec_sadb.refFreeListTail == IPSEC_SAREF_NULL) { KLIPS_PRINT(debug_xform, "klips_debug:ipsec_SAref_recycle: " "out of room in the SArefTable.\n"); return(-ENOSPC); } KLIPS_PRINT(debug_xform, "klips_debug:ipsec_SAref_recycle: " "SArefFreeList partly refilled to %d of %d.\n", ipsec_sadb.refFreeListTail, IPSEC_SA_REF_FREELIST_NUM_ENTRIES); return 0; }