Esempio n. 1
0
struct ipsec_sa*
ipsec_sa_alloc(int*error) /* pass in error var by pointer */
{
	struct ipsec_sa* ips;

	if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) {
		KLIPS_PRINT(debug_xform,
			    "ipsec_sa_alloc: "
			    "memory allocation error\n");
		*error = -ENOMEM;
		return NULL;
	}
	memset((caddr_t)ips, 0, sizeof(*ips));

#ifdef IPSEC_SA_RECOUNT_DEBUG
	ips->ips_raw = ipsec_sa_raw;
	ipsec_sa_raw = ips;
#endif

	/* return with at least counter = 1 */
	ipsec_sa_get(ips, IPSEC_REFALLOC);

	*error = 0;
	return(ips);
}
Esempio n. 2
0
/*
  The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen
*/
int
ipsec_sa_add(struct ipsec_sa *ips)
{
	int error = 0;
	unsigned int hashval;

	ips = ipsec_sa_get(ips);

	if(ips == NULL) {
		KLIPS_PRINT(debug_xform,
			    "klips_error:ipsec_sa_add: "
			    "null pointer passed in!\n");
		return -ENODATA;
	}
	hashval = IPS_HASH(&ips->ips_said);

	spin_lock_bh(&tdb_lock);
	
	ips->ips_hnext = ipsec_sadb_hash[hashval];
	ipsec_sadb_hash[hashval] = ips;
	
	spin_unlock_bh(&tdb_lock);

	return error;
}
Esempio 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;
}
Esempio n. 4
0
struct ipsec_sa *
ipsec_sa_getbyid(ip_said *said, int type)
{
	int hashval;
	struct ipsec_sa *ips;
        char sa[SATOT_BUF];
	size_t sa_len;

	if(said == NULL) {
		KLIPS_PRINT(debug_xform,
			    "ipsec_sa_getbyid: "
			    "null pointer passed in!\n");
		return NULL;
	}

	hashval = IPS_HASH(said);
	
	sa_len = KLIPS_SATOT(debug_xform, said, 0, sa, sizeof(sa));
	KLIPS_PRINT(debug_xform,
		    "ipsec_sa_getbyid: "
		    "linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n",
		    hashval,
		    sa_len ? sa : " (error)");

	if((ips = ipsec_sadb_hash[hashval]) == NULL) {
		KLIPS_PRINT(debug_xform,
			    "ipsec_sa_getbyid: "
			    "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
			    hashval,
			    sa_len ? sa : " (error)");
		return NULL;
	}

	for (; ips; ips = ips->ips_hnext) {
		if ((ips->ips_said.spi == said->spi) &&
		    (ip_address_cmp(&ips->ips_said.dst, &said->dst) == 0) &&
		    (ips->ips_said.proto == said->proto)) {
			ipsec_sa_get(ips, type);
			return ips;
		}
	}
	
	KLIPS_PRINT(debug_xform,
		    "ipsec_sa_getbyid: "
		    "no entry in linked list for hash=%d of SA:%s.\n",
		    hashval,
		    sa_len ? sa : " (error)");
	return NULL;
}
Esempio n. 5
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. 6
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;
}
Esempio n. 7
0
struct ipsec_sa*
ipsec_sa_alloc(int*error) /* pass in error var by pointer */
{
	struct ipsec_sa* ips;

	if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) {
		KLIPS_PRINT(debug_xform,
			    "ipsec_sa_alloc: "
			    "memory allocation error\n");
		*error = -ENOMEM;
		return NULL;
	}
	memset((caddr_t)ips, 0, sizeof(*ips));

	/* return with at least counter = 1 */
	ipsec_sa_get(ips);

	*error = 0;
	return(ips);
}
Esempio n. 8
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;
}