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

📄 mpoa_caches.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <linux/types.h>#include <linux/atmmpc.h>#include <linux/time.h>#include "mpoa_caches.h"#include "mpc.h"/* * mpoa_caches.c: Implementation of ingress and egress cache * handling functions */#if 0#define dprintk printk    /* debug */#else#define dprintk(format,args...)#endif#if 0#define ddprintk printk  /* more debug */#else#define ddprintk(format,args...)#endifstatic in_cache_entry *in_cache_get(uint32_t dst_ip,				    struct mpoa_client *client){	in_cache_entry *entry;	read_lock_bh(&client->ingress_lock);	entry = client->in_cache;	while(entry != NULL){		if( entry->ctrl_info.in_dst_ip == dst_ip ){			atomic_inc(&entry->use);			read_unlock_bh(&client->ingress_lock);			return entry;		}		entry = entry->next;	}	read_unlock_bh(&client->ingress_lock);	return NULL;}static in_cache_entry *in_cache_get_with_mask(uint32_t dst_ip,					      struct mpoa_client *client,					      uint32_t mask){	in_cache_entry *entry;	read_lock_bh(&client->ingress_lock);	entry = client->in_cache;	while(entry != NULL){		if((entry->ctrl_info.in_dst_ip & mask)  == (dst_ip & mask )){			atomic_inc(&entry->use);			read_unlock_bh(&client->ingress_lock);			return entry;		}		entry = entry->next;	}	read_unlock_bh(&client->ingress_lock);	return NULL;}static in_cache_entry *in_cache_get_by_vcc(struct atm_vcc *vcc,					   struct mpoa_client *client ){	in_cache_entry *entry;	read_lock_bh(&client->ingress_lock);	entry = client->in_cache;	while(entry != NULL){		if(entry->shortcut == vcc) {			atomic_inc(&entry->use);			read_unlock_bh(&client->ingress_lock);			return entry;		}		entry = entry->next;	}	read_unlock_bh(&client->ingress_lock);	return NULL;}static in_cache_entry *in_cache_add_entry(uint32_t dst_ip,					  struct mpoa_client *client){	unsigned char *ip __attribute__ ((unused)) = (unsigned char *)&dst_ip;	in_cache_entry* entry = kmalloc(sizeof(in_cache_entry), GFP_KERNEL);	if (entry == NULL) {		printk("mpoa: mpoa_caches.c: new_in_cache_entry: out of memory\n");		return NULL;	}	dprintk("mpoa: mpoa_caches.c: adding an ingress entry, ip = %u.%u.%u.%u\n", ip[0], ip[1], ip[2], ip[3]);	memset(entry,0,sizeof(in_cache_entry));	atomic_set(&entry->use, 1);	dprintk("mpoa: mpoa_caches.c: new_in_cache_entry: about to lock\n");	write_lock_bh(&client->ingress_lock);	entry->next = client->in_cache;	entry->prev = NULL;	if (client->in_cache != NULL)		client->in_cache->prev = entry;	client->in_cache = entry;	memcpy(entry->MPS_ctrl_ATM_addr, client->mps_ctrl_addr, ATM_ESA_LEN);	entry->ctrl_info.in_dst_ip = dst_ip;	do_gettimeofday(&(entry->tv));	entry->retry_time = client->parameters.mpc_p4;	entry->count = 1;	entry->entry_state = INGRESS_INVALID;	entry->ctrl_info.holding_time = HOLDING_TIME_DEFAULT;	atomic_inc(&entry->use);	write_unlock_bh(&client->ingress_lock);	dprintk("mpoa: mpoa_caches.c: new_in_cache_entry: unlocked\n");	return entry;}static int cache_hit(in_cache_entry *entry, struct mpoa_client *mpc){	struct atm_mpoa_qos *qos;	struct k_message msg;	entry->count++;	if(entry->entry_state == INGRESS_RESOLVED && entry->shortcut != NULL)		return OPEN;	if(entry->entry_state == INGRESS_REFRESHING){		if(entry->count > mpc->parameters.mpc_p1){			msg.type = SND_MPOA_RES_RQST;			msg.content.in_info = entry->ctrl_info;			memcpy(msg.MPS_ctrl, mpc->mps_ctrl_addr, ATM_ESA_LEN);			qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);			if (qos != NULL) msg.qos = qos->qos;			msg_to_mpoad(&msg, mpc);			do_gettimeofday(&(entry->reply_wait));			entry->entry_state = INGRESS_RESOLVING;		}		if(entry->shortcut != NULL)			return OPEN;		return CLOSED;	}	if(entry->entry_state == INGRESS_RESOLVING && entry->shortcut != NULL)		return OPEN;	if( entry->count > mpc->parameters.mpc_p1 &&	    entry->entry_state == INGRESS_INVALID){		unsigned char *ip __attribute__ ((unused)) =		    (unsigned char *)&entry->ctrl_info.in_dst_ip;		dprintk("mpoa: (%s) mpoa_caches.c: threshold exceeded for ip %u.%u.%u.%u, sending MPOA res req\n", mpc->dev->name, ip[0], ip[1], ip[2], ip[3]);		entry->entry_state = INGRESS_RESOLVING;		msg.type =  SND_MPOA_RES_RQST;		memcpy(msg.MPS_ctrl, mpc->mps_ctrl_addr, ATM_ESA_LEN );		msg.content.in_info = entry->ctrl_info;		qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);		if (qos != NULL) msg.qos = qos->qos;		msg_to_mpoad( &msg, mpc);		do_gettimeofday(&(entry->reply_wait));	}	return CLOSED;}static void in_cache_put(in_cache_entry *entry){	if (atomic_dec_and_test(&entry->use)) {		memset(entry, 0, sizeof(in_cache_entry));		kfree(entry);	}	return;}/* * This should be called with write lock on */static void in_cache_remove_entry(in_cache_entry *entry,				  struct mpoa_client *client){	struct atm_vcc *vcc;	struct k_message msg;	unsigned char *ip;	vcc = entry->shortcut;	ip = (unsigned char *)&entry->ctrl_info.in_dst_ip;	dprintk("mpoa: mpoa_caches.c: removing an ingress entry, ip = %u.%u.%u.%u\n",ip[0], ip[1], ip[2], ip[3]);	if (entry->prev != NULL)		entry->prev->next = entry->next;	else		client->in_cache = entry->next;	if (entry->next != NULL)		entry->next->prev = entry->prev;	client->in_ops->put(entry);	if(client->in_cache == NULL && client->eg_cache == NULL){		msg.type = STOP_KEEP_ALIVE_SM;		msg_to_mpoad(&msg,client);	}	/* Check if the egress side still uses this VCC */	if (vcc != NULL) {		eg_cache_entry *eg_entry = client->eg_ops->get_by_vcc(vcc, client);		if (eg_entry != NULL) {			client->eg_ops->put(eg_entry);			return;		}		atm_async_release_vcc(vcc, -EPIPE);	}	return;}/* Call this every MPC-p2 seconds... Not exactly correct solution,   but an easy one... */static void clear_count_and_expired(struct mpoa_client *client){	unsigned char *ip;	in_cache_entry *entry, *next_entry;	struct timeval now;	do_gettimeofday(&now);	write_lock_bh(&client->ingress_lock);	entry = client->in_cache;	while(entry != NULL){		entry->count=0;		next_entry = entry->next;		if((now.tv_sec - entry->tv.tv_sec)		   > entry->ctrl_info.holding_time){			ip = (unsigned char*)&entry->ctrl_info.in_dst_ip;			dprintk("mpoa: mpoa_caches.c: holding time expired, ip = %u.%u.%u.%u\n", NIPQUAD(ip));			client->in_ops->remove_entry(entry, client);		}		entry = next_entry;	}	write_unlock_bh(&client->ingress_lock);	return;}/* Call this every MPC-p4 seconds. */static void check_resolving_entries(struct mpoa_client *client){	struct atm_mpoa_qos *qos;	in_cache_entry *entry;	struct timeval now;	struct k_message msg;	do_gettimeofday( &now );	read_lock_bh(&client->ingress_lock);	entry = client->in_cache;	while( entry != NULL ){		if(entry->entry_state == INGRESS_RESOLVING){			if(now.tv_sec - entry->hold_down.tv_sec < client->parameters.mpc_p6){				entry = entry->next;                      /* Entry in hold down */				continue;			}			if( (now.tv_sec - entry->reply_wait.tv_sec) >			    entry->retry_time ){				entry->retry_time = MPC_C1*( entry->retry_time );				if(entry->retry_time > client->parameters.mpc_p5){					/* Retry time maximum exceeded, put entry in hold down. */					do_gettimeofday(&(entry->hold_down));					entry->retry_time = client->parameters.mpc_p4;					entry = entry->next;					continue;				}				/* Ask daemon to send a resolution request. */				memset(&(entry->hold_down),0,sizeof(struct timeval));				msg.type = SND_MPOA_RES_RTRY;				memcpy(msg.MPS_ctrl, client->mps_ctrl_addr, ATM_ESA_LEN);				msg.content.in_info = entry->ctrl_info;				qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);				if (qos != NULL) msg.qos = qos->qos;				msg_to_mpoad(&msg, client);				do_gettimeofday(&(entry->reply_wait));			}		}

⌨️ 快捷键说明

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