Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
static IPsecSAref_t
ipsec_SAref_alloc(int*error) /* pass in error var by pointer */
{
	IPsecSAref_t SAref;

	KLIPS_PRINT(debug_xform,
		    "ipsec_SAref_alloc: "
		    "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n",
		    ipsec_sadb.refFreeListHead,
		    ipsec_sadb.refFreeListCont,
		    ipsec_sadb.refFreeListTail,
		    IPSEC_SA_REF_FREELIST_NUM_ENTRIES);

	if(ipsec_sadb.refFreeListHead == IPSEC_SAREF_NULL) {
		KLIPS_PRINT(debug_xform,
			    "ipsec_SAref_alloc: "
			    "FreeList empty, recycling...\n");
		*error = ipsec_SAref_recycle();
		if(*error) {
			return IPSEC_SAREF_NULL;
		}
	}

	SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead];
	if(SAref == IPSEC_SAREF_NULL) {
		KLIPS_ERROR(debug_xform,
			    "ipsec_SAref_alloc: "
			    "unexpected error, refFreeListHead = %d points to invalid entry.\n",
			    ipsec_sadb.refFreeListHead);
		*error = -ESPIPE;
		return IPSEC_SAREF_NULL;
	}

	KLIPS_PRINT(debug_xform,
		    "ipsec_SAref_alloc: "
		    "allocating SAref=%d, table=%u, entry=%u of %u.\n",
		    SAref,
		    IPsecSAref2table(SAref),
		    IPsecSAref2entry(SAref),
		    IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES);
	
	ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL;
	ipsec_sadb.refFreeListHead++;
	if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) {
		KLIPS_PRINT(debug_xform,
			    "ipsec_SAref_alloc: "
			    "last FreeList entry allocated, resetting list head to empty.\n");
		ipsec_sadb.refFreeListHead = IPSEC_SAREF_NULL;
	}

	return SAref;
}
Ejemplo n.º 3
0
struct ipsec_sa *ipsec_sa_getbyref(IPsecSAref_t ref, int type)
{
	struct ipsec_sa *ips;
	struct IPsecSArefSubTable *st =
		ipsec_sadb.refTable[IPsecSAref2table(ref)];

	if (st == NULL)
		return NULL;

	ips = st->entry[IPsecSAref2entry(ref)];
	if (ips)
		ipsec_sa_get(ips, type);
	return ips;
}
Ejemplo n.º 4
0
struct ipsec_sa *
ipsec_sa_getbyref(IPsecSAref_t ref)
{
	struct ipsec_sa *ips;
	struct IPsecSArefSubTable *st = ipsec_sadb.refTable[IPsecSAref2table(ref)];

	if(st == NULL) {
		return NULL;
	}

	ips = st->entry[IPsecSAref2entry(ref)];
	if(ips) {
		ipsec_sa_get(ips);
	}
	return ips;
}
Ejemplo n.º 5
0
int ipsec_sa_wipe(struct ipsec_sa *ips)
{
	int hashval;
	struct ipsec_sa **tpp;

	if (ips == NULL)
		return -ENODATA;

#if IPSEC_SA_REF_CODE
	/* remove me from the SArefTable */
	if (debug_xform) {
		char sa[SATOT_BUF];
		size_t sa_len;
		struct IPsecSArefSubTable *subtable = NULL;

		if (IPsecSAref2table(IPsecSA2SAref(ips)) <
		    IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES &&
		    ipsec_sadb.refTable != NULL)
			subtable = ipsec_sadb.refTable[
				IPsecSAref2table(IPsecSA2SAref(ips))];

		sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa,
				     sizeof(sa));
		KLIPS_PRINT(debug_xform,
			    "klips_debug:ipsec_sa_wipe: "
			    "removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n",
			    sa_len ? sa : " (error)",
			    ips,
			    ips->ips_ref,
			    IPsecSAref2table(IPsecSA2SAref(ips)),
			    subtable,
			    subtable ? IPsecSAref2entry(IPsecSA2SAref(ips)) : 0);
	}

	if (ips->ips_ref != IPSEC_SAREF_NULL) {
		struct IPsecSArefSubTable *subtable = NULL;
		int ref_table = IPsecSAref2table(IPsecSA2SAref(ips));
		int ref_entry = IPsecSAref2entry(IPsecSA2SAref(ips));

		if (ref_table < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) {
			subtable = ipsec_sadb.refTable[ref_table];
			if (subtable != NULL && subtable->entry[ref_entry] ==
			    ips) {

				subtable->entry[ref_entry] = NULL;
			}
		}
		ips->ips_ref = IPSEC_SAREF_NULL;
	}
#endif  /* IPSEC_SA_REF_CODE */

	/* paranoid clean up */
	if (ips->ips_addr_s != NULL) {
		memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
		kfree(ips->ips_addr_s);
	}
	ips->ips_addr_s = NULL;

	if (ips->ips_addr_d != NULL) {
		memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
		kfree(ips->ips_addr_d);
	}
	ips->ips_addr_d = NULL;

	if (ips->ips_addr_p != NULL) {
		memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
		kfree(ips->ips_addr_p);
	}
	ips->ips_addr_p = NULL;

	if (ips->ips_natt_oa) {
		memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size);
		kfree(ips->ips_natt_oa);
	}
	ips->ips_natt_oa = NULL;

	if (ips->ips_key_a != NULL) {
#ifdef CONFIG_KLIPS_ALG
		if (ips->ips_alg_auth &&
		    ips->ips_alg_auth->ixt_a_destroy_key)
		{
			ips->ips_alg_auth->ixt_a_destroy_key(ips->ips_alg_auth, 
							     ips->ips_key_a);
		} else
#endif
		{
			memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
			kfree(ips->ips_key_a);
		}
	}
	ips->ips_key_a = NULL;

	if (ips->ips_key_e != NULL) {
#ifdef CONFIG_KLIPS_ALG
		if (ips->ips_alg_enc &&
		    ips->ips_alg_enc->ixt_e_destroy_key) {
			ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc,
							    ips->ips_key_e);
		} else
#endif
		{
			memset((caddr_t)(ips->ips_key_e), 0,
			       ips->ips_key_e_size);
			kfree(ips->ips_key_e);
		}
	}
	ips->ips_key_e = NULL;

	if (ips->ips_iv != NULL) {
		memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
		kfree(ips->ips_iv);
	}
	ips->ips_iv = NULL;

#ifdef CONFIG_KLIPS_OCF
	if (ips->ocf_in_use)
		ipsec_ocf_sa_free(ips);
#endif

	if (ips->ips_ident_s.data != NULL) {
		memset((caddr_t)(ips->ips_ident_s.data),
		       0,
		       ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN -
		       sizeof(struct sadb_ident));
		kfree(ips->ips_ident_s.data);
	}
	ips->ips_ident_s.data = NULL;

	if (ips->ips_ident_d.data != NULL) {
		memset((caddr_t)(ips->ips_ident_d.data),
		       0,
		       ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN -
		       sizeof(struct sadb_ident));
		kfree(ips->ips_ident_d.data);
	}
	ips->ips_ident_d.data = NULL;

#ifdef CONFIG_KLIPS_ALG
	if (ips->ips_alg_enc || ips->ips_alg_auth)
		ipsec_alg_sa_wipe(ips);
	ips->ips_alg_enc = NULL;
	ips->ips_alg_auth = NULL;

#endif
	if (ips->ips_prev)
		ips->ips_prev->ips_next = ips->ips_next;
	if (ips->ips_next) {
		ips->ips_next->ips_prev = ips->ips_prev;
		ipsec_sa_put(ips->ips_next, IPSEC_REFALLOC);
	}
	ips->ips_next = NULL;
	ips->ips_prev = NULL;

	hashval = IPS_HASH(&ips->ips_said);
	tpp = &ipsec_sadb_hash[hashval];
	while (*tpp) {
		if (*tpp == ips)
			*tpp = ips->ips_hnext;
		else
			tpp = &((*tpp)->ips_hnext);
	}
	if (ips->ips_hnext)
		ipsec_sa_put(ips->ips_hnext, IPSEC_REFALLOC);
	ips->ips_hnext = NULL;

	BUG_ON(atomic_read(&ips->ips_refcount) != 0);

#ifdef IPSEC_SA_RECOUNT_DEBUG
	if (ips == ipsec_sa_raw) {
		ipsec_sa_raw = ips->ips_raw;
	} else {
		struct ipsec_sa *raw = ipsec_sa_raw;
		while (raw) {
			if (raw->ips_raw == ips) {
				raw->ips_raw = ips->ips_raw;
				break;
			}
			raw = raw->ips_raw;
		}
	}
#endif
	if (ips->ips_out != NULL) {
		ipsec_dev_put(ips->ips_out);
		ips->ips_out = NULL;
	}

	memset((caddr_t)ips, 0, sizeof(*ips));
	kfree(ips);
	ips = NULL;

	return 0;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
IPSEC_PROCFS_DEBUG_NO_STATIC
int ipsec_spi_format(struct ipsec_sa *sa_p, struct seq_file *seq)
{
	char sa[SATOT_BUF];
	char buf_s[SUBNETTOA_BUF];
	char buf_d[SUBNETTOA_BUF];
	size_t sa_len;

	ipsec_sa_get(sa_p, IPSEC_REFPROC);
	sa_len = satot(&sa_p->ips_said, 'x', sa, sizeof(sa));
	seq_printf(seq, "%s ", sa_len ? sa : " (error)");
	seq_printf(seq, "%s%s%s", IPS_XFORM_NAME(sa_p));
	seq_printf(seq, ": dir=%s", (sa_p->ips_flags & EMT_INBOUND) ? "in " : "out");

	if (sa_p->ips_addr_s) {
		sin_addrtot(sa_p->ips_addr_s, 0, buf_s, sizeof(buf_s));
		seq_printf(seq, " src=%s", buf_s);
	}

	if ((sa_p->ips_said.proto == IPPROTO_IPIP)
	   && (sa_p->ips_flags & (SADB_X_SAFLAGS_INFLOW
			   |SADB_X_SAFLAGS_POLICYONLY))) {
		if (sa_p->ips_flow_s.u.v4.sin_family == AF_INET) {
			subnettoa(sa_p->ips_flow_s.u.v4.sin_addr,
				  sa_p->ips_mask_s.u.v4.sin_addr,
				  0,
				  buf_s,
				  sizeof(buf_s));
			subnettoa(sa_p->ips_flow_d.u.v4.sin_addr,
				  sa_p->ips_mask_d.u.v4.sin_addr,
				  0,
				  buf_d,
				  sizeof(buf_d));
		} else {
			subnet6toa(&sa_p->ips_flow_s.u.v6.sin6_addr,
				   &sa_p->ips_mask_s.u.v6.sin6_addr,
				   0,
				   buf_s,
				   sizeof(buf_s));
			subnet6toa(&sa_p->ips_flow_d.u.v6.sin6_addr,
				   &sa_p->ips_mask_d.u.v6.sin6_addr,
				   0,
				   buf_d,
				   sizeof(buf_d));
		}

		seq_printf(seq, " policy=%s->%s", buf_s, buf_d);
	}

	if (sa_p->ips_iv_bits) {
		int j;
		seq_printf(seq, " iv_bits=%dbits iv=0x", sa_p->ips_iv_bits);

		for (j = 0; j < sa_p->ips_iv_bits / 8; j++) {
#ifdef CONFIG_KLIPS_OCF
			if (sa_p->ips_iv == NULL) {
				/*
				 * ocf doesn't set the IV
				 * so fake it for the test cases
				 */
				seq_printf(seq, "%02x", 0xA5 + j);
			} else
#endif
			seq_printf(seq, "%02x", ((__u8*)sa_p->ips_iv)[j]);
		}
	}

	if (sa_p->ips_encalg || sa_p->ips_authalg) {
		if (sa_p->ips_replaywin)
			seq_printf(seq, " ooowin=%d", sa_p->ips_replaywin);
		if (sa_p->ips_errs.ips_replaywin_errs)
			seq_printf(seq, " ooo_errs=%d", sa_p->ips_errs.ips_replaywin_errs);
		if (sa_p->ips_replaywin_lastseq)
		       seq_printf(seq, " seq=%d", sa_p->ips_replaywin_lastseq);
		if (sa_p->ips_replaywin_bitmap)
			seq_printf(seq, " bit=0x%Lx", sa_p->ips_replaywin_bitmap);
		if (sa_p->ips_replaywin_maxdiff)
			seq_printf(seq, " max_seq_diff=%d", sa_p->ips_replaywin_maxdiff);
	}

	if (sa_p->ips_flags & ~EMT_INBOUND) {
		seq_printf(seq, " flags=0x%x", sa_p->ips_flags & ~EMT_INBOUND);
		seq_printf(seq, "<");
		/* flag printing goes here */
		seq_printf(seq, ">");
	}

	if (sa_p->ips_auth_bits)
		seq_printf(seq, " alen=%d", sa_p->ips_auth_bits);
	if (sa_p->ips_key_bits_a)
		seq_printf(seq, " aklen=%d", sa_p->ips_key_bits_a);
	if (sa_p->ips_errs.ips_auth_errs)
		seq_printf(seq, " auth_errs=%d", sa_p->ips_errs.ips_auth_errs);
	if (sa_p->ips_key_bits_e)
		seq_printf(seq, " eklen=%d", sa_p->ips_key_bits_e);
	if (sa_p->ips_errs.ips_encsize_errs)
		seq_printf(seq, " encr_size_errs=%d", sa_p->ips_errs.ips_encsize_errs);
	if (sa_p->ips_errs.ips_encpad_errs)
		seq_printf(seq, " encr_pad_errs=%d", sa_p->ips_errs.ips_encpad_errs);

	seq_printf(seq, " jiffies=%lu", jiffies);

	seq_printf(seq, " life(c,s,h)=");

	ipsec_lifetime_format(seq, "alloc",
			      ipsec_life_countbased, &sa_p->ips_life.ipl_allocations);

	ipsec_lifetime_format(seq, "bytes",
			      ipsec_life_countbased, &sa_p->ips_life.ipl_bytes);

	ipsec_lifetime_format(seq, "addtime",
			      ipsec_life_timebased, &sa_p->ips_life.ipl_addtime);

	ipsec_lifetime_format(seq, "usetime",
			      ipsec_life_timebased, &sa_p->ips_life.ipl_usetime);

	ipsec_lifetime_format(seq, "packets",
			      ipsec_life_countbased, &sa_p->ips_life.ipl_packets);

	if (sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */
		seq_printf(seq, " idle=%Ld",
			   ipsec_jiffieshz_elapsed(jiffies/HZ, sa_p->ips_life.ipl_usetime.ipl_last));
	}

#ifdef CONFIG_KLIPS_IPCOMP
	if (sa_p->ips_said.proto == IPPROTO_COMP &&
	   (sa_p->ips_comp_ratio_dbytes ||
	    sa_p->ips_comp_ratio_cbytes)) {
		seq_printf(seq, " ratio=%Ld:%Ld",
			   sa_p->ips_comp_ratio_dbytes,
			   sa_p->ips_comp_ratio_cbytes);
	}
#endif /* CONFIG_KLIPS_IPCOMP */

	seq_printf(seq, " natencap=");
	switch (sa_p->ips_natt_type) {
	case 0:
		seq_printf(seq, "none");
		break;
	case ESPINUDP_WITH_NON_IKE:
		seq_printf(seq, "nonike");
		break;
	case ESPINUDP_WITH_NON_ESP:
		seq_printf(seq, "nonesp");
		break;
	default:
		seq_printf(seq, "unknown");
		break;
	}

	seq_printf(seq, " natsport=%d", sa_p->ips_natt_sport);
	seq_printf(seq, " natdport=%d", sa_p->ips_natt_dport);

	/* we decrement by one, because this SA has been referenced in order to dump this info */
	seq_printf(seq, " refcount=%d", atomic_read(&sa_p->ips_refcount)-1);
#ifdef IPSEC_SA_RECOUNT_DEBUG
	{
		int f;
		seq_printf(seq, "[");
		for (f = 0; f < sizeof(sa_p->ips_track); f++)
			seq_printf(seq, "%s%d", f == 0 ? "" : ",", sa_p->ips_track[f]);
		seq_printf(seq, "]");
	}
#endif

	seq_printf(seq, " ref=%d", sa_p->ips_ref);
	seq_printf(seq, " refhim=%d", sa_p->ips_refhim);

	if (sa_p->ips_out) {
		seq_printf(seq, " outif=%s:%d",
			   sa_p->ips_out->name,
			   sa_p->ips_transport_direct);
	}

	if (debug_xform) {
		seq_printf(seq, " reftable=%lu refentry=%lu",
			   (unsigned long)IPsecSAref2table(sa_p->ips_ref),
			   (unsigned long)IPsecSAref2entry(sa_p->ips_ref));
	}

	seq_printf(seq, "\n");

	ipsec_sa_put(sa_p, IPSEC_REFPROC);
	return 0;
}
Ejemplo n.º 8
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;
}