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

📄 mpoa_caches.c

📁 《嵌入式系统设计与实例开发实验教材二源码》Linux内核移植与编译实验
💻 C
📖 第 1 页 / 共 2 页
字号:
		entry = entry->next;	}	read_unlock_bh(&client->ingress_lock);}/* Call this every MPC-p5 seconds. */static void refresh_entries(struct mpoa_client *client){	struct timeval now;	struct in_cache_entry *entry = client->in_cache;	ddprintk("mpoa: mpoa_caches.c: refresh_entries\n");	do_gettimeofday(&now);	read_lock_bh(&client->ingress_lock);	while( entry != NULL ){		if( entry->entry_state == INGRESS_RESOLVED ){			if(!(entry->refresh_time))				entry->refresh_time = (2*(entry->ctrl_info.holding_time))/3;			if( (now.tv_sec - entry->reply_wait.tv_sec) > entry->refresh_time ){				dprintk("mpoa: mpoa_caches.c: refreshing an entry.\n");				entry->entry_state = INGRESS_REFRESHING;			}		}		entry = entry->next;	}	read_unlock_bh(&client->ingress_lock);}static void in_destroy_cache(struct mpoa_client *mpc){	write_lock_irq(&mpc->ingress_lock);	while(mpc->in_cache != NULL)		mpc->in_ops->remove_entry(mpc->in_cache, mpc);	write_unlock_irq(&mpc->ingress_lock);	return;}static eg_cache_entry *eg_cache_get_by_cache_id(uint32_t cache_id, struct mpoa_client *mpc){	eg_cache_entry *entry;	read_lock_irq(&mpc->egress_lock);	entry = mpc->eg_cache;	while(entry != NULL){		if(entry->ctrl_info.cache_id == cache_id){			atomic_inc(&entry->use);			read_unlock_irq(&mpc->egress_lock);			return entry;		}		entry = entry->next;	}	read_unlock_irq(&mpc->egress_lock);	return NULL;}/* This can be called from any context since it saves CPU flags */static eg_cache_entry *eg_cache_get_by_tag(uint32_t tag, struct mpoa_client *mpc){	unsigned long flags;	eg_cache_entry *entry;	read_lock_irqsave(&mpc->egress_lock, flags);	entry = mpc->eg_cache;	while (entry != NULL){		if (entry->ctrl_info.tag == tag) {			atomic_inc(&entry->use);			read_unlock_irqrestore(&mpc->egress_lock, flags);			return entry;		}		entry = entry->next;	}	read_unlock_irqrestore(&mpc->egress_lock, flags);	return NULL;}/* This can be called from any context since it saves CPU flags */static eg_cache_entry *eg_cache_get_by_vcc(struct atm_vcc *vcc, struct mpoa_client *mpc){	unsigned long flags;	eg_cache_entry *entry;	read_lock_irqsave(&mpc->egress_lock, flags);	entry = mpc->eg_cache;	while (entry != NULL){		if (entry->shortcut == vcc) {			atomic_inc(&entry->use);	       		read_unlock_irqrestore(&mpc->egress_lock, flags);			return entry;		}		entry = entry->next;	}	read_unlock_irqrestore(&mpc->egress_lock, flags);	return NULL;}static eg_cache_entry *eg_cache_get_by_src_ip(uint32_t ipaddr, struct mpoa_client *mpc){	eg_cache_entry *entry;	read_lock_irq(&mpc->egress_lock);	entry = mpc->eg_cache;	while(entry != NULL){		if(entry->latest_ip_addr == ipaddr) {			atomic_inc(&entry->use);	       		read_unlock_irq(&mpc->egress_lock);			return entry;		}		entry = entry->next;	}	read_unlock_irq(&mpc->egress_lock);	return NULL;}static void eg_cache_put(eg_cache_entry *entry){	if (atomic_dec_and_test(&entry->use)) {		memset(entry, 0, sizeof(eg_cache_entry));		kfree(entry);	}	return;}/* * This should be called with write lock on */static void eg_cache_remove_entry(eg_cache_entry *entry,				  struct mpoa_client *client){	struct atm_vcc *vcc;	struct k_message msg;	vcc = entry->shortcut;	dprintk("mpoa: mpoa_caches.c: removing an egress entry.\n");	if (entry->prev != NULL)		entry->prev->next = entry->next;	else		client->eg_cache = entry->next;	if (entry->next != NULL)		entry->next->prev = entry->prev;	client->eg_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 ingress side still uses this VCC */	if (vcc != NULL) {		in_cache_entry *in_entry = client->in_ops->get_by_vcc(vcc, client);		if (in_entry != NULL) {			client->in_ops->put(in_entry);			return;		}		atm_async_release_vcc(vcc, -EPIPE);	}	return;}static eg_cache_entry *eg_cache_add_entry(struct k_message *msg, struct mpoa_client *client){	unsigned char *ip;	eg_cache_entry *entry = kmalloc(sizeof(eg_cache_entry), GFP_KERNEL);	if (entry == NULL) {		printk("mpoa: mpoa_caches.c: new_eg_cache_entry: out of memory\n");		return NULL;	}	ip = (unsigned char *)&msg->content.eg_info.eg_dst_ip;	dprintk("mpoa: mpoa_caches.c: adding an egress entry, ip = %u.%u.%u.%u, this should be our IP\n", NIPQUAD(ip));	memset(entry, 0, sizeof(eg_cache_entry));	atomic_set(&entry->use, 1);	dprintk("mpoa: mpoa_caches.c: new_eg_cache_entry: about to lock\n");	write_lock_irq(&client->egress_lock);	entry->next = client->eg_cache;	entry->prev = NULL;	if (client->eg_cache != NULL)		client->eg_cache->prev = entry;	client->eg_cache = entry;	memcpy(entry->MPS_ctrl_ATM_addr, client->mps_ctrl_addr, ATM_ESA_LEN);	entry->ctrl_info = msg->content.eg_info;	do_gettimeofday(&(entry->tv));	entry->entry_state = EGRESS_RESOLVED;	dprintk("mpoa: mpoa_caches.c: new_eg_cache_entry cache_id %lu\n", ntohl(entry->ctrl_info.cache_id));	ip = (unsigned char *)&entry->ctrl_info.mps_ip;	dprintk("mpoa: mpoa_caches.c: mps_ip = %u.%u.%u.%u\n", NIPQUAD(ip));	atomic_inc(&entry->use);	write_unlock_irq(&client->egress_lock);	dprintk("mpoa: mpoa_caches.c: new_eg_cache_entry: unlocked\n");	return entry;}static void update_eg_cache_entry(eg_cache_entry * entry, uint16_t holding_time){	do_gettimeofday(&(entry->tv));	entry->entry_state = EGRESS_RESOLVED;	entry->ctrl_info.holding_time = holding_time;	return;}static void clear_expired(struct mpoa_client *client){	eg_cache_entry *entry, *next_entry;	struct timeval now;	struct k_message msg;	do_gettimeofday(&now);	write_lock_irq(&client->egress_lock);	entry = client->eg_cache;	while(entry != NULL){		next_entry = entry->next;		if((now.tv_sec - entry->tv.tv_sec)		   > entry->ctrl_info.holding_time){			msg.type = SND_EGRESS_PURGE;			msg.content.eg_info = entry->ctrl_info;			dprintk("mpoa: mpoa_caches.c: egress_cache: holding time expired, cache_id = %lu.\n",ntohl(entry->ctrl_info.cache_id));			msg_to_mpoad(&msg, client);			client->eg_ops->remove_entry(entry, client);		}		entry = next_entry;	}	write_unlock_irq(&client->egress_lock);	return;}static void eg_destroy_cache(struct mpoa_client *mpc){	write_lock_irq(&mpc->egress_lock);	while(mpc->eg_cache != NULL)		mpc->eg_ops->remove_entry(mpc->eg_cache, mpc);	write_unlock_irq(&mpc->egress_lock);	return;}static struct in_cache_ops ingress_ops = {	in_cache_add_entry,               /* add_entry       */	in_cache_get,                     /* get             */	in_cache_get_with_mask,           /* get_with_mask   */	in_cache_get_by_vcc,              /* get_by_vcc      */	in_cache_put,                     /* put             */	in_cache_remove_entry,            /* remove_entry    */	cache_hit,                        /* cache_hit       */	clear_count_and_expired,          /* clear_count     */	check_resolving_entries,          /* check_resolving */	refresh_entries,                  /* refresh         */	in_destroy_cache                  /* destroy_cache   */};static struct eg_cache_ops egress_ops = {	eg_cache_add_entry,               /* add_entry        */	eg_cache_get_by_cache_id,         /* get_by_cache_id  */	eg_cache_get_by_tag,              /* get_by_tag       */	eg_cache_get_by_vcc,              /* get_by_vcc       */	eg_cache_get_by_src_ip,           /* get_by_src_ip    */	eg_cache_put,                     /* put              */	eg_cache_remove_entry,            /* remove_entry     */	update_eg_cache_entry,            /* update           */	clear_expired,                    /* clear_expired    */	eg_destroy_cache                  /* destroy_cache    */};void atm_mpoa_init_cache(struct mpoa_client *mpc){	mpc->in_ops = &ingress_ops;	mpc->eg_ops = &egress_ops;	return;}

⌨️ 快捷键说明

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