⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipsec_sa.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 3 页
字号:
		    (unsigned long) sizeof(*ips),		    ips,		    ips->ips_ref);	if(ips->ips_ref == IPSEC_SAREF_NULL) {		kfree(ips);		KLIPS_PRINT(debug_xform,			    "klips_debug:ipsec_sa_alloc: "			    "SAref allocation error\n");		return NULL;	}	atomic_inc(&ips->ips_refcount);	IPsecSAref2SA(ips->ips_ref) = ips;#endif /* IPSEC_SA_REF_CODE */	*error = 0;	return(ips);}intipsec_sa_free(struct ipsec_sa* ips){	return ipsec_sa_wipe(ips);}struct ipsec_sa *ipsec_sa_getbyid(ip_said *said){	int hashval;	struct ipsec_sa *ips;        char sa[SATOT_BUF];	size_t sa_len;	if(said == NULL) {		KLIPS_PRINT(debug_xform,			    "klips_error:ipsec_sa_getbyid: "			    "null pointer passed in!\n");		return NULL;	}	sa_len = satot(said, 0, sa, sizeof(sa));	hashval = IPS_HASH(said);		KLIPS_PRINT(debug_xform,		    "klips_debug: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,			    "klips_debug: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) &&		    (ips->ips_said.dst.u.v4.sin_addr.s_addr == said->dst.u.v4.sin_addr.s_addr) &&		    (ips->ips_said.proto == said->proto)) {			atomic_inc(&ips->ips_refcount);			return ips;		}	}		KLIPS_PRINT(debug_xform,		    "klips_debug:ipsec_sa_getbyid: "		    "no entry in linked list for hash=%d of SA:%s.\n",		    hashval,		    sa_len ? sa : " (error)");	return NULL;}intipsec_sa_put(struct ipsec_sa *ips){        char sa[SATOT_BUF];	size_t sa_len;	if(ips == NULL) {		KLIPS_PRINT(debug_xform,			    "klips_error:ipsec_sa_put: "			    "null pointer passed in!\n");		return -1;	}	sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));	KLIPS_PRINT(debug_xform,		    "klips_debug:ipsec_sa_put: "		    "ipsec_sa SA:%s, ref:%d reference count decremented.\n",		    sa_len ? sa : " (error)",		    ips->ips_ref);	atomic_dec(&ips->ips_refcount);	return 0;}/*  The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen*/intipsec_sa_add(struct ipsec_sa *ips){	int error = 0;	unsigned int hashval;	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);	atomic_inc(&ips->ips_refcount);	spin_lock_bh(&tdb_lock);		ips->ips_hnext = ipsec_sadb_hash[hashval];	ipsec_sadb_hash[hashval] = ips;		spin_unlock_bh(&tdb_lock);	return error;}/*  The ipsec_sa table better be locked before it is handed in, or races might happen*/intipsec_sa_del(struct ipsec_sa *ips){	unsigned int hashval;	struct ipsec_sa *ipstp;        char sa[SATOT_BUF];	size_t sa_len;	if(ips == NULL) {		KLIPS_PRINT(debug_xform,			    "klips_error:ipsec_sa_del: "			    "null pointer passed in!\n");		return -ENODATA;	}		sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));	if(ips->ips_inext || ips->ips_onext) {		KLIPS_PRINT(debug_xform,			    "klips_error:ipsec_sa_del: "			    "SA:%s still linked!\n",			    sa_len ? sa : " (error)");		return -EMLINK;	}		hashval = IPS_HASH(&ips->ips_said);		KLIPS_PRINT(debug_xform,		    "klips_debug:ipsec_sa_del: "		    "deleting SA:%s, hashval=%d.\n",		    sa_len ? sa : " (error)",		    hashval);	if(ipsec_sadb_hash[hashval] == NULL) {		KLIPS_PRINT(debug_xform,			    "klips_debug:ipsec_sa_del: "			    "no entries in ipsec_sa table for hash=%d of SA:%s.\n",			    hashval,			    sa_len ? sa : " (error)");		return -ENOENT;	}		if (ips == ipsec_sadb_hash[hashval]) {		ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;		ips->ips_hnext = NULL;		atomic_dec(&ips->ips_refcount);		KLIPS_PRINT(debug_xform,			    "klips_debug:ipsec_sa_del: "			    "successfully deleted first ipsec_sa in chain.\n");		return 0;	} else {		for (ipstp = ipsec_sadb_hash[hashval];		     ipstp;		     ipstp = ipstp->ips_hnext) {			if (ipstp->ips_hnext == ips) {				ipstp->ips_hnext = ips->ips_hnext;				ips->ips_hnext = NULL;				atomic_dec(&ips->ips_refcount);				KLIPS_PRINT(debug_xform,					    "klips_debug:ipsec_sa_del: "					    "successfully deleted link in ipsec_sa chain.\n");				return 0;			}		}	}		KLIPS_PRINT(debug_xform,		    "klips_debug:ipsec_sa_del: "		    "no entries in linked list for hash=%d of SA:%s.\n",		    hashval,		    sa_len ? sa : " (error)");	return -ENOENT;}/*  The ipsec_sa table better be locked before it is handed in, or races  might happen*/intipsec_sa_delchain(struct ipsec_sa *ips){	struct ipsec_sa *ipsdel;	int error = 0;        char sa[SATOT_BUF];	size_t sa_len;	if(ips == NULL) {		KLIPS_PRINT(debug_xform,			    "klips_error:ipsec_sa_delchain: "			    "null pointer passed in!\n");		return -ENODATA;	}	sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));	KLIPS_PRINT(debug_xform,		    "klips_debug:ipsec_sa_delchain: "		    "passed SA:%s\n",		    sa_len ? sa : " (error)");	while(ips->ips_onext != NULL) {		ips = ips->ips_onext;	}	while(ips) {		/* XXX send a pfkey message up to advise of deleted ipsec_sa */		sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));		KLIPS_PRINT(debug_xform,			    "klips_debug:ipsec_sa_delchain: "			    "unlinking and delting SA:%s",			    sa_len ? sa : " (error)");		ipsdel = ips;		ips = ips->ips_inext;		if(ips != NULL) {			sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));			KLIPS_PRINT(debug_xform,				    ", inext=%s",				    sa_len ? sa : " (error)");			atomic_dec(&ipsdel->ips_refcount);			ipsdel->ips_inext = NULL;			atomic_dec(&ips->ips_refcount);			ips->ips_onext = NULL;		}		KLIPS_PRINT(debug_xform,			    ".\n");		if((error = ipsec_sa_del(ipsdel))) {			KLIPS_PRINT(debug_xform,				    "klips_debug:ipsec_sa_delchain: "				    "ipsec_sa_del returned error %d.\n", -error);			return error;		}		if((error = ipsec_sa_wipe(ipsdel))) {			KLIPS_PRINT(debug_xform,				    "klips_debug:ipsec_sa_delchain: "				    "ipsec_sa_wipe returned error %d.\n", -error);			return error;		}	}	return error;}int ipsec_sadb_cleanup(__u8 proto){	unsigned i;	int error = 0;	struct ipsec_sa *ips, **ipsprev, *ipsdel;        char sa[SATOT_BUF];	size_t sa_len;	KLIPS_PRINT(debug_xform,		    "klips_debug:ipsec_sadb_cleanup: "		    "cleaning up proto=%d.\n",		    proto);	spin_lock_bh(&tdb_lock);	for (i = 0; i < SADB_HASHMOD; i++) {		ipsprev = &(ipsec_sadb_hash[i]);		ips = ipsec_sadb_hash[i];		if(ips != NULL) {			atomic_inc(&ips->ips_refcount);		}		for(; ips != NULL;) {			sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));			KLIPS_PRINT(debug_xform,				    "klips_debug:ipsec_sadb_cleanup: "				    "checking SA:%s, hash=%d, ref=%d",				    sa_len ? sa : " (error)",				    i,				    ips->ips_ref);			ipsdel = ips;			ips = ipsdel->ips_hnext;			if(ips != NULL) {				atomic_inc(&ips->ips_refcount);				sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));				KLIPS_PRINT(debug_xform,					    ", hnext=%s",					    sa_len ? sa : " (error)");			}			if(*ipsprev != NULL) {				sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));				KLIPS_PRINT(debug_xform,					    ", *ipsprev=%s",					    sa_len ? sa : " (error)");				if((*ipsprev)->ips_hnext) {					sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));					KLIPS_PRINT(debug_xform,						    ", *ipsprev->ips_hnext=%s",						    sa_len ? sa : " (error)");				}			}			KLIPS_PRINT(debug_xform,				    ".\n");			if(proto == 0 || (proto == ipsdel->ips_said.proto)) {				sa_len = satot(&ipsdel->ips_said, 0, sa, sizeof(sa));				KLIPS_PRINT(debug_xform,					    "klips_debug:ipsec_sadb_cleanup: "					    "deleting SA chain:%s.\n",					    sa_len ? sa : " (error)");				if((error = ipsec_sa_delchain(ipsdel))) {					SENDERR(-error);				}				ipsprev = &(ipsec_sadb_hash[i]);				ips = ipsec_sadb_hash[i];				KLIPS_PRINT(debug_xform,					    "klips_debug:ipsec_sadb_cleanup: "					    "deleted SA chain:%s",					    sa_len ? sa : " (error)");				if(ips != NULL) {					sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));					KLIPS_PRINT(debug_xform,						    ", ipsec_sadb_hash[%d]=%s",						    i,						    sa_len ? sa : " (error)");				}				if(*ipsprev != NULL) {					sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));					KLIPS_PRINT(debug_xform,						    ", *ipsprev=%s",						    sa_len ? sa : " (error)");					if((*ipsprev)->ips_hnext != NULL) {					        sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));						KLIPS_PRINT(debug_xform,							    ", *ipsprev->ips_hnext=%s",							    sa_len ? sa : " (error)");					}				}				KLIPS_PRINT(debug_xform,					    ".\n");			} else {				ipsprev = &ipsdel;			}			if(ipsdel != NULL) {				ipsec_sa_put(ipsdel);			}		}	} errlab:	spin_unlock_bh(&tdb_lock);#if IPSEC_SA_REF_CODE	/* clean up SA reference table */	/* go through the ref table and clean out all the SAs */	KLIPS_PRINT(debug_xform,		    "klips_debug:ipsec_sadb_cleanup: "		    "removing SAref entries and tables.");	{		unsigned table, entry;		for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {			KLIPS_PRINT(debug_xform,				    "klips_debug:ipsec_sadb_cleanup: "				    "cleaning SAref table=%u.\n",				    table);			if(ipsec_sadb.refTable[table] == NULL) {				printk("\n");				KLIPS_PRINT(debug_xform,					    "klips_debug:ipsec_sadb_cleanup: "					    "cleaned %u used refTables.\n",					    table);				break;			}			for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {				if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {					ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);					ipsec_sadb.refTable[table]->entry[entry] = NULL;				}			}		}	}#endif /* IPSEC_SA_REF_CODE */	return(error);}int ipsec_sadb_free(void){	int error = 0;	KLIPS_PRINT(debug_xform,		    "klips_debug:ipsec_sadb_free: "		    "freeing SArefTable memory.\n");	/* clean up SA reference table */	/* go through the ref table and clean out all the SAs if any are	   left and free table memory */	KLIPS_PRINT(debug_xform,		    "klips_debug:ipsec_sadb_free: "		    "removing SAref entries and tables.\n");	{		unsigned table, entry;		for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {			KLIPS_PRINT(debug_xform,				    "klips_debug:ipsec_sadb_free: "				    "removing SAref table=%u.\n",				    table);			if(ipsec_sadb.refTable[table] == NULL) {				KLIPS_PRINT(debug_xform,					    "klips_debug:ipsec_sadb_free: "					    "removed %u used refTables.\n",					    table);				break;			}			for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {				if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {					ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);					ipsec_sadb.refTable[table]->entry[entry] = NULL;				}			}			vfree(ipsec_sadb.refTable[table]);			ipsec_sadb.refTable[table] = NULL;		}	}	return(error);}intipsec_sa_wipe(struct ipsec_sa *ips){	if(ips == NULL) {		return -ENODATA;	}	/* if(atomic_dec_and_test(ips)) {	}; */#if IPSEC_SA_REF_CODE	/* remove me from the SArefTable */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -