Esempio n. 1
0
int
ipsec_sa_intern(struct ipsec_sa *ips)
{
	int error = 0;
	IPsecSAref_t ref = ips->ips_ref;

	if(ref == IPSEC_SAREF_NULL) {
		ref = ipsec_SAref_alloc(&error); /* pass in error return by pointer */
		KLIPS_PRINT(debug_xform,
			    "ipsec_sa_intern: "
			    "allocated ref=%u for sa %p\n", ref, ips);

		if(ref == IPSEC_SAREF_NULL) {
			KLIPS_PRINT(debug_xform,
				    "ipsec_sa_intern: "
				    "SAref allocation error\n");
			return error;
		}

		ips->ips_ref = ref;
	}

	error = ipsec_saref_verify_slot(ref);
	if(error) {
		return error;
	}

	ipsec_sa_get(ips, IPSEC_REFINTERN);
	/*
	 * if there is an existing SA at this reference, then free it
	 * note, that nsa might == ips!. That's okay, we just incremented
	 * the reference count above.
	 */
	{
		struct ipsec_sa *nsa = IPsecSAref2SA(ref);
		if(nsa) {
			ipsec_sa_put(nsa, IPSEC_REFINTERN);
		}
	}

	KLIPS_PRINT(debug_xform,
		    "ipsec_sa_intern: "
		    "SAref[%d]=%p\n",
		    ips->ips_ref, ips);
	IPsecSAref2SA(ips->ips_ref) = ips;

	/* return OK */
	return 0;
}
Esempio n. 2
0
void ipsec_sa_untern(struct ipsec_sa *ips)
{
	IPsecSAref_t ref = ips->ips_ref;
	int error;

	/* verify that we are removing correct item! */
	error = ipsec_saref_verify_slot(ref);
	if (error)
		return;

	if (IPsecSAref2SA(ref) == ips) {
		IPsecSAref2SA(ref) = NULL;
		ipsec_sa_put(ips, IPSEC_REFINTERN);
	} else {
		KLIPS_PRINT(debug_xform,
			    "ipsec_sa_untern: "
			    "ref=%u -> %p but untern'ing %p\n", ref,
			    IPsecSAref2SA(ref), ips);
	}

}
Esempio n. 3
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;
}
Esempio n. 4
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;
}