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

📄 db.c

📁 igmp sourde code used in switch
💻 C
字号:
/* * db and hash handle routines */#include <linux/slab.h>		/* for kmalloc, kfree */#include "db.h"#include "util.h"#include "igmp_netfilter.h"	/* TstIgmpSnpStatus */TstIgmpSnpStatus	igmpsnp_global_stats;igmp_db_t *		igmp_db_head;igmp_router_t		igmp_router;static spinlock_t	igmp_db_sem;void igmp_snooping_stats_reset_counter (void){	igmpsnp_global_stats.totol_pkt_rcvd = 0;	igmpsnp_global_stats.valid_pkt_rcvd = 0;	igmpsnp_global_stats.invalid_pkt_rcvd = 0;	igmpsnp_global_stats.g_query_rcvd = 0;	igmpsnp_global_stats.gs_query_rcvd = 0;	igmpsnp_global_stats.leave_rcvd = 0;	igmpsnp_global_stats.report_rcvd = 0;	igmpsnp_global_stats.other_rcvd = 0;	igmpsnp_global_stats.g_query_xmit = 0;	igmpsnp_global_stats.gs_query_xmit = 0;	igmpsnp_global_stats.leave_xmit = 0;	igmpsnp_global_stats.report_xmit = 0;}void igmp_snooping_stats_init (int boot){	if (boot) {		memset (&igmpsnp_global_stats, 0, sizeof(TstIgmpSnpStatus));		igmpsnp_global_stats.igmpsnp_enable = IGMPSNP_DFT_ENABLE;		igmpsnp_global_stats.fastleave_enable = FASTLEAVE_DFT_ENABLE;		igmpsnp_global_stats.querier_enable = QUERIER_DFT_ENABLE;		igmpsnp_global_stats.debug_enable = DEBUG_DFT_ENABLE;	}	else {		igmpsnp_global_stats.igmpsnp_enable = 0;		igmp_snooping_stats_reset_counter ();	}	return;}void igmp_snooping_db_init (int boot){	igmp_router.addr = 0;	igmp_router.port = 0;	igmp_db_head = NULL;	if (boot) {		spin_lock_init (&igmp_db_sem);	}}void igmp_db_copy_entry (igmp_db_t * to, igmp_db_t * from){	/* hnext and pnext are not copied */	to->gda = from->gda;	to->life = from->life;	to->port = from->port;}igmp_db_t * igmp_db_new_entry (__u32 gda, __u8 port, __u32 life){	igmp_db_t * ret;	ret = (igmp_db_t *) kmalloc (sizeof (igmp_db_t), GFP_KERNEL);	if (!ret)		return NULL;	ret->gda = gda;	ret->life = life;	ret->port = port;	ret->hnext = NULL;	ret->pnext = NULL;	return ret;}int igmp_db_find_gda (igmp_db_t * ret, __u32 gda){	igmp_db_t *p;	if (NULL == igmp_db_head)		return 0;	for (p = igmp_db_head; p; p = p->hnext) {		if (gda == p->gda) {			igmp_db_copy_entry (ret, p);			return 1;		}	}	return 0;}int igmp_db_find_entry (igmp_db_t * ret, __u32 gda, __u8 port){	igmp_db_t *head = NULL, *p;	if (NULL == igmp_db_head)		return 0;	for (head = igmp_db_head; head; head = head->hnext) {		if (head->gda == gda) {			for (p = head; p; p = p->pnext) {				if (p->port == port) {					igmp_db_copy_entry (ret, p);					return 1;				}			}			break; /* no need to find another gda */		}	}	return 0;}int igmp_db_find_port (igmp_db_t * ret, __u8 port){	igmp_db_t *head = NULL, *p;	if (NULL == igmp_db_head)		return 0;	for (head = igmp_db_head; head; head = head->hnext) {		for (p = head; p; p = p->pnext) {			if (p->port == port) {				igmp_db_copy_entry (ret, p);				return 1;			}		}	}	return 0;}int igmp_db_insert_entry (igmp_db_t * ins){	igmp_db_t *head, *p = NULL;	int found = 0;	if (NULL == ins)		return 0;	if (NULL == igmp_db_head) {		igmp_db_head = ins;		return 1;	}	if (igmp_db_find_entry (p, ins->gda, ins->port))		return 1;	spin_lock (&igmp_db_sem);	for (head = igmp_db_head; head; head = head->hnext) {		if (head->gda == ins->gda) {			found = 1;			break;		}	}	if (found) {	/* gda exists */		ins->pnext = head->pnext;		head->pnext = ins;	}	else {		ins->hnext = igmp_db_head->hnext;		igmp_db_head->hnext = ins;	}	spin_unlock (&igmp_db_sem);	return 1;}int igmp_db_del_entry (igmp_db_t del){	igmp_db_t *head, *head_bak;	igmp_db_t *p, *p_bak;	char found;	if (NULL == igmp_db_head || del.gda == 0)		return 1;	spin_lock (&igmp_db_sem);	/* find gda head */	for (head = igmp_db_head, head_bak = NULL, found = 0;	     head;	     head_bak = head, head = head->hnext)	{		if (head->gda == del.gda) {			found = 1;			break;		}	}	if (!found) /* gda not found */		return 1;	/* find entry */	for (p = head, p_bak = NULL, found = 0;	     p;	     p_bak = p, p = p->pnext)	{		if (p->port == del.port){			found = 1;			break;		}	}	if (!found) /* entry not found */		return 1;	/* entry found */	if (p_bak == NULL) {		/* p is head */		if (head_bak == NULL) {	/* head is igmp_db_head */			if (p->pnext) {	/* other entries with same gda exist */				igmp_db_head = p->pnext;				igmp_db_head->hnext = p->hnext;			}			else {				igmp_db_head = p->hnext;			}		}		else {			if (p->pnext) {	/* other entries with same gda exist */				p->pnext->hnext = head->hnext;				head_bak->hnext = p->pnext;			}			else {				head_bak->hnext = p->hnext;			}		}	}	else {				/* p is leaf */		p_bak->pnext = p->pnext;	}	spin_unlock (&igmp_db_sem);	kfree (p);	return 1;}void igmp_db_del_all (void){	igmp_db_t *dh, *dh_prev = NULL; /* del_head */	igmp_db_t *d, *d_prev = NULL;   /* del */	if (NULL == igmp_db_head)		return;#define _DEL_SUB_ENTRIES() \	do { \	for (d_prev = dh, d = dh->pnext; d; d_prev = d, d = d->pnext) { \		if (d_prev == dh)	/* first iteration */ \			continue; \		if (d_prev) \			kfree (d_prev); \		if (d->pnext == NULL) {	/* last iteration */ \			kfree (d); \			break; \		} \	} \	} while (0)	spin_lock (&igmp_db_sem);	for (dh_prev = igmp_db_head, dh = igmp_db_head->hnext;	     dh;	     dh_prev = dh, dh = dh->hnext)	{		if (dh_prev == igmp_db_head) {	/* first iteration */			_DEL_SUB_ENTRIES();			continue;		}		/* clean sub entries in the same gda */		_DEL_SUB_ENTRIES();		if (dh_prev)			kfree (dh_prev);		if (dh->hnext == NULL) {	/* last iteration */			kfree (dh);			break;		}	}	kfree (igmp_db_head);	igmp_db_head = NULL;	spin_unlock (&igmp_db_sem);}int igmp_db_modify_life (igmp_db_t mod, __u32 life){	igmp_db_t *p;	char found = 0;	for (p = igmp_db_head; p; p = p->hnext) {		if (p->gda == mod.gda) {			found = 1;			break;		}	}	if (found) {		for (; p; p = p->pnext) {			if (p->port == mod.port) {				p->life = life;				return 1;			}		}	}	return 0;}void igmp_db_decrease_life (void){	igmp_db_t *head, *p;	for (head = igmp_db_head; head; head = head->hnext) {		for (p = head; p; p = p->pnext) {			if (p->life > 0) {				p->life -= 1;				//printk("mod: g:%x,p:%d,l:%d\n", p->gda, p->port, p->life);			}		}	}}int igmp_db_find_dead (igmp_db_t * ret){	igmp_db_t *head, *p;	for (head = igmp_db_head; head; head = head->hnext) {		for (p = head; p; p = p->pnext) {			if ((p->life) == 0) {				igmp_db_copy_entry (ret, p);				return 1;			}		}	}	return 0;}void igmp_db_debug_print (char * title){	igmp_db_t *head, *p;	int i = 0;	if (NULL == title)		printk (" debug print db =>\n");	else		printk (" %s print db =>\n", title);	for (head = igmp_db_head; head; head = head->hnext) {		for (p = head; p; p = p->pnext) {			++i;			printk ("   %d. gda:%x port:%d life:%d\n",				i, p->gda, p->port, p->life);		}	}	if (0 == i)		printk ("   empty\n");}int get_mcast_groups_size (void){	igmp_db_t * p;	int size = 0;	for (p = igmp_db_head; p; p = p->hnext) {		++size;	}	return size;}unsigned long get_mcast_group_entry (int index){	igmp_db_t * p;	int i = 0;	/* starts from zero */	for (p = igmp_db_head; p; p = p->hnext, i++) {		if (i == index)			return (p->gda);	}	return 0UL;}unsigned long get_mcast_router (void){	return (igmp_router.addr);}unsigned char get_mcast_router_port (void){	return (igmp_router.port + 1);}#if 0/* * input: GDA address * function: count a hash key using 23 bits LSB of GDA * output: hash key */inline unsigned int gda_hash_f(struct in_addr gda){	return (unsigned int)((gda.s_addr&0x7FFFFF)%IGMPSNP_HASH_SZ);}/* * check the existence of porxy state given gda */proxy_state_t * report_proxy_lookup(proxy_state_t **phash, struct in_addr gda){	unsigned int key;	proxy_state_t * p;	key = gda_hash_f(gda);	if (!phash[key])		return NULL;	for (p=phash[key]; p!=NULL; p=p->next){		if (p->gda.s_addr == gda.s_addr)			return p;	}	return NULL;}proxy_state_t * new_report_proxy_entry(		struct in_addr addr,		int qtype,		int interval){	proxy_state_t * p;	p = (proxy_state_t *)kmalloc(sizeof(proxy_state_t), GFP_KERNEL);	if (!p)		return NULL;	p->gda.s_addr = addr.s_addr;	switch (qtype) {	case IGMPQ_GENERAL_QUERY:		p->state = IGMPS_PROXY_REPORT;		break;	case IGMPQ_GS_QUERY:		p->state = IGMPS_PROXY_GS_REPORT;		break;	case IGMPQ_LEAVE_GS_QUERY:		p->state = IGMPQ_LEAVE_GS_QUERY;		break;	}	p->proxy_int = interval;	p->num_report = 0;	p->num_gs_query = 0;	p->tlist.expires = 0;	p->lgs_port = 0;	return p;}int report_proxy_add(proxy_state_t **phash, proxy_state_t * padd){	unsigned int key;	if (report_proxy_lookup(phash, padd->gda) != NULL)		return -1;	key = gda_hash_f(padd->gda);	padd->next = phash[key]? phash[key]: NULL;	phash[key] = padd;	return 1;}int report_proxy_del(proxy_state_t **phash, proxy_state_t * pdel){	proxy_state_t * p;	unsigned int key;		key = gda_hash_f(pdel->gda);	if (!phash[key])		return -1;	if (phash[key] == pdel) {		phash[key] = pdel->next;		kfree(pdel);		return 1;	}	for (p=phash[key]; p!=NULL; p=p->next)		if (p->next == pdel)			break;	p->next = pdel->next;	kfree(pdel);	return 1;}#endif

⌨️ 快捷键说明

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