void IPACM_EvtDispatcher::ProcessEvt(ipacm_cmd_q_data *data)
{

	cmd_evts *tmp = head, tmp1;

	if(head == NULL)
	{
		IPACMDBG("Queue is empty\n");
	}

	while(tmp != NULL)
	{
	        memcpy(&tmp1, tmp, sizeof(tmp1));
		if(data->event == tmp1.event)
		{
			ipacm_event_stats[data->event]++;
			tmp1.obj->event_callback(data->event, data->evt_data);
			IPACMDBG(" Find matched registered events\n");
		}
	        tmp = tmp1.next;
	}

	IPACMDBG(" Finished process events\n");
			
	if(data->evt_data != NULL)
	{
		IPACMDBG("free the event:%d data: %p\n", data->event, data->evt_data);
		free(data->evt_data);
	}
	return;
}
bool IPACM_LanToLan::is_lan2lan_connection(ipacm_event_connection* data)
{
	if(data->iptype == IPA_IP_v4)
	{
		if(client_info_v4_.count(data->src_ipv4_addr) == 0 || client_info_v4_.count(data->dst_ipv4_addr) == 0)
		{
			IPACMDBG("Either source or destination is not in client table\n");
			return false;
		}

		ipacm_iface_type src_type, dst_type;
		src_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v4_[data->src_ipv4_addr].p_iface->ipa_if_num].if_cat;
		dst_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v4_[data->dst_ipv4_addr].p_iface->ipa_if_num].if_cat;

		return (src_type != dst_type);
	}
	else
	{
		uint64_t src_v6_addr, dst_v6_addr;
		memcpy(&src_v6_addr, &(data->src_ipv6_addr[2]), sizeof(uint64_t));
		memcpy(&dst_v6_addr, &(data->dst_ipv6_addr[2]), sizeof(uint64_t));

		if(client_info_v6_.count(src_v6_addr) == 0 || client_info_v6_.count(dst_v6_addr) == 0)
		{
			IPACMDBG("Either source or destination is not in client table\n");
			return false;
		}

		ipacm_iface_type src_type, dst_type;
		src_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v6_[src_v6_addr].p_iface->ipa_if_num].if_cat;
		dst_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v6_[dst_v6_addr].p_iface->ipa_if_num].if_cat;

		return (src_type != dst_type);
	}
}
bool IPACM_LanToLan::is_potential_lan2lan_connection(ipacm_event_connection* new_conn)
{
	int i, num_private_subnet;
	bool src_is_valid = false;
	bool dst_is_valid = false;

	if(new_conn->iptype == IPA_IP_v4)
	{
		num_private_subnet = IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
		for(i=0; i<num_private_subnet; i++)
		{
			if( (new_conn->src_ipv4_addr & IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask)
				== (IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr & IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask) )
			{
				src_is_valid = true;
			}
			if( (new_conn->dst_ipv4_addr & IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask)
				== (IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr & IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask) )
			{
				dst_is_valid = true;
			}
		}

		if(src_is_valid && dst_is_valid)
		{
			IPACMDBG("Both src and dst are potentially in subnet.\n");
			return true;
		}
	}
	else
	{
		if( (new_conn->src_ipv6_addr[0] & ipv6_multicast_mask) != (ipv6_multicast_addr & ipv6_multicast_mask) )
		{
			src_is_valid = true;
		}
		if( (new_conn->dst_ipv6_addr[0] & ipv6_multicast_mask) != (ipv6_multicast_addr & ipv6_multicast_mask) )
		{
			dst_is_valid = true;
		}

		if(src_is_valid && dst_is_valid)
		{
			IPACMDBG("Both src and dst are potentially in subnet.\n");
			return true;
		}
	}

	IPACMDBG("This connection is not a lan2lan connection potentially.\n");
	return false;
}
IPACM_LanToLan::~IPACM_LanToLan()
{
	client_table_v4::iterator it_v4;
	for(it_v4 = client_info_v4_.begin(); it_v4 != client_info_v4_.end(); it_v4++)
	{
		turnoff_offload_links(IPA_IP_v4, &(it_v4->second));
		clear_peer_list(&(it_v4->second));
	}
	client_info_v4_.clear();
	IPACMDBG("Clear IPv4 hash table in Lan2Lan distructor.\n");

	client_table_v6::iterator it_v6;
	for(it_v6 = client_info_v6_.begin(); it_v6 != client_info_v6_.end(); it_v6++)
	{
		turnoff_offload_links(IPA_IP_v6, &(it_v6->second));
		clear_peer_list(&(it_v6->second));
	}
	client_info_v6_.clear();
	IPACMDBG("Clear IPv6 hash table in Lan2Lan distructor.\n");

	return;
}
void IPACM_LanToLan::remove_cache_connection(ipacm_event_connection* del_conn)
{
	connection_list::iterator it;
	if(is_potential_lan2lan_connection(del_conn) == true)
	{
		if(del_conn->iptype == IPA_IP_v4)
		{
			for(it = connection_v4_.begin(); it != connection_v4_.end(); it++)
			{
				if(it->src_ipv4_addr == del_conn->src_ipv4_addr && it->dst_ipv4_addr == del_conn->dst_ipv4_addr)
				{
					IPACMDBG("Find the cached ipv4 connection, remove it from list.\n");
					connection_v4_.erase(it);
					IPACMDBG_H("Now the number of ipv4 cache connection is %d.\n", connection_v4_.size());
					return;
				}
			}
			IPACMDBG_H("Do not find the cached ipv4 connection, do nothing.\n");
		}
		else
		{
			for(it = connection_v6_.begin(); it != connection_v6_.end(); it++)
			{
				if(memcmp(it->src_ipv6_addr, del_conn->src_ipv6_addr, 4*sizeof(uint32_t)) == 0
					&& memcmp(it->dst_ipv6_addr, del_conn->dst_ipv6_addr, 4*sizeof(uint32_t)) == 0 )
				{
					IPACMDBG("Find the cached ipv6 connection, remove it from list.\n");
					connection_v6_.erase(it);
					IPACMDBG_H("Now the number of ipv6 cache connection is %d.\n", connection_v6_.size());
					return;
				}
			}
			IPACMDBG_H("Do not find the cached ipv6 connection, do nothing.\n");
		}
	}
	return;
}
bool IPACM_Routing::AddRoutingRule(struct ipa_ioc_add_rt_rule *ruleTable)
{
	int retval = 0, cnt=0;
	bool isInvalid = false;

	if (!DeviceNodeIsOpened())
	{
		IPACMERR("Device is not opened\n");
		return false;
	}

	for(cnt=0; cnt<ruleTable->num_rules; cnt++)
	{
		if(ruleTable->rules[cnt].rule.dst > IPA_CLIENT_MAX)
		{
			IPACMERR("Invalid dst pipe, Rule:%d  dst_pipe:%d\n", cnt, ruleTable->rules[cnt].rule.dst);
			isInvalid = true;
		}
	}

	if(isInvalid)
	{
		return false;
	}

	retval = ioctl(m_fd, IPA_IOC_ADD_RT_RULE, ruleTable);
	if (retval)
	{
		IPACMERR("Failed adding routing rule %p\n", ruleTable);
		return false;
	}

	for(cnt=0; cnt<ruleTable->num_rules; cnt++)
	{
		IPACMDBG("Rule:%d  dst_pipe:%d\n", cnt, ruleTable->rules[cnt].rule.dst);
	}

	IPACMDBG_H("Added routing rule %p\n", ruleTable);
	return true;
}
Пример #7
0
/* This function traverses the xml tree*/
static int ipacm_cfg_xml_parse_tree
(
	 xmlNode* xml_node,
	 IPACM_conf_t *config
)
{
	int32_t ret_val = IPACM_SUCCESS;
	int str_size;
	char* content;
	char content_buf[MAX_XML_STR_LEN];

	if (NULL == xml_node)
		return ret_val;
	while ( xml_node != NULL &&
				 ret_val == IPACM_SUCCESS)
	{
		switch (xml_node->type)
		{
		case XML_ELEMENT_NODE:
			{
				if (IPACM_util_icmp_string((char*)xml_node->name, system_TAG) == 0 ||
						IPACM_util_icmp_string((char*)xml_node->name, ODU_TAG) == 0 ||
						IPACM_util_icmp_string((char*)xml_node->name, IPACMCFG_TAG) == 0 ||
						IPACM_util_icmp_string((char*)xml_node->name, IPACMIFACECFG_TAG) == 0 ||
						IPACM_util_icmp_string((char*)xml_node->name, IFACE_TAG) == 0 ||
						IPACM_util_icmp_string((char*)xml_node->name, IPACMPRIVATESUBNETCFG_TAG) == 0 ||
						IPACM_util_icmp_string((char*)xml_node->name, SUBNET_TAG) == 0 ||
						IPACM_util_icmp_string((char*)xml_node->name, IPACMALG_TAG) == 0 ||
						IPACM_util_icmp_string((char*)xml_node->name, ALG_TAG) == 0 ||
						IPACM_util_icmp_string((char*)xml_node->name, IPACMNat_TAG) == 0)
				{
					if (0 == IPACM_util_icmp_string((char*)xml_node->name, IFACE_TAG))
					{
						/* increase iface entry number */
						config->iface_config.num_iface_entries++;
					}

					if (0 == IPACM_util_icmp_string((char*)xml_node->name, SUBNET_TAG))
					{
						/* increase iface entry number */
						config->private_subnet_config.num_subnet_entries++;
					}

					if (0 == IPACM_util_icmp_string((char*)xml_node->name, ALG_TAG))
					{
						/* increase iface entry number */
						config->alg_config.num_alg_entries++;
					}
					/* go to child */
					ret_val = ipacm_cfg_xml_parse_tree(xml_node->children, config);
				}
				else if (IPACM_util_icmp_string((char*)xml_node->name, ODUMODE_TAG) == 0)
				{
					IPACMDBG_H("inside ODU-XML\n");
					content = IPACM_read_content_element(xml_node);
					if (content)
					{
						str_size = strlen(content);
						memset(content_buf, 0, sizeof(content_buf));
						memcpy(content_buf, (void *)content, str_size);
						if (0 == strncasecmp(content_buf, ODU_ROUTER_TAG, str_size))
						{
							config->router_mode_enable = true;
							IPACMDBG_H("router-mode enable %d\n", config->router_mode_enable);
						}
						else if (0 == strncasecmp(content_buf, ODU_BRIDGE_TAG, str_size))
						{
							config->router_mode_enable = false;
							IPACMDBG_H("router-mode enable %d\n", config->router_mode_enable);
						}
					}
				}
				else if (IPACM_util_icmp_string((char*)xml_node->name, ODUEMBMS_OFFLOAD_TAG) == 0)
				{
					IPACMDBG_H("inside ODU-XML\n");
					content = IPACM_read_content_element(xml_node);
					if (content)
					{
						str_size = strlen(content);
						memset(content_buf, 0, sizeof(content_buf));
						memcpy(content_buf, (void *)content, str_size);
						if (atoi(content_buf))
						{
							config->odu_embms_enable = true;
							IPACMDBG_H("router-mode enable %d buf(%d)\n", config->odu_embms_enable, atoi(content_buf));
						}
						else
						{
							config->odu_embms_enable = false;
							IPACMDBG_H("router-mode enable %d buf(%d)\n", config->odu_embms_enable, atoi(content_buf));
						}
					}
				}
				else if (IPACM_util_icmp_string((char*)xml_node->name, NAME_TAG) == 0)
				{
					content = IPACM_read_content_element(xml_node);
					if (content)
					{
						str_size = strlen(content);
						memset(content_buf, 0, sizeof(content_buf));
						memcpy(content_buf, (void *)content, str_size);
						strncpy(config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].iface_name, content_buf, str_size);
						IPACMDBG_H("Name %s\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].iface_name);
					}
				}
				else if (IPACM_util_icmp_string((char*)xml_node->name, CATEGORY_TAG) == 0)
				{
					content = IPACM_read_content_element(xml_node);
					if (content)
					{
						str_size = strlen(content);
						memset(content_buf, 0, sizeof(content_buf));
						memcpy(content_buf, (void *)content, str_size);
						if (0 == strncasecmp(content_buf, WANIF_TAG, str_size))
						{
							config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat = WAN_IF;
							IPACMDBG_H("Category %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat);
						}
						else if (0 == strncasecmp(content_buf, LANIF_TAG, str_size))
						{
							config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat = LAN_IF;
							IPACMDBG_H("Category %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat);
						}
						else if (0 == strncasecmp(content_buf, WLANIF_TAG, str_size))
						{
							config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat = WLAN_IF;
							IPACMDBG_H("Category %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat);
						}
						else  if (0 == strncasecmp(content_buf, VIRTUALIF_TAG, str_size))
						{
							config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat = VIRTUAL_IF;
							IPACMDBG_H("Category %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat);
						}
						else  if (0 == strncasecmp(content_buf, UNKNOWNIF_TAG, str_size))
						{
							config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat = UNKNOWN_IF;
							IPACMDBG_H("Category %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat);
						}
						else  if (0 == strncasecmp(content_buf, ETHIF_TAG, str_size))
						{
							config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat = ETH_IF;
							IPACMDBG_H("Category %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat);
						}
						else  if (0 == strncasecmp(content_buf, ODUIF_TAG, str_size))
						{
							config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat = ODU_IF;
							IPACMDBG("Category %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_cat);
						}
					}
				}
				else if (IPACM_util_icmp_string((char*)xml_node->name, MODE_TAG) == 0)
				{
					content = IPACM_read_content_element(xml_node);
					if (content)
					{
						str_size = strlen(content);
						memset(content_buf, 0, sizeof(content_buf));
						memcpy(content_buf, (void *)content, str_size);
						if (0 == strncasecmp(content_buf, IFACE_ROUTER_MODE_TAG, str_size))
						{
							config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_mode = ROUTER;
							IPACMDBG_H("Iface mode %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_mode);
						}
						else  if (0 == strncasecmp(content_buf, IFACE_BRIDGE_MODE_TAG, str_size))
						{
							config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_mode = BRIDGE;
							IPACMDBG_H("Iface mode %d\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].if_mode);
						}
					}
				}
				else if (IPACM_util_icmp_string((char*)xml_node->name, WLAN_MODE_TAG) == 0)
				{
					IPACMDBG_H("Inside WLAN-XML\n");
					content = IPACM_read_content_element(xml_node);
					if (content)
					{
						str_size = strlen(content);
						memset(content_buf, 0, sizeof(content_buf));
						memcpy(content_buf, (void *)content, str_size);

						if (0 == strncasecmp(content_buf, WLAN_FULL_MODE_TAG, str_size))
						{
							config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].wlan_mode = FULL;
							IPACMDBG_H("Wlan-mode full(%d)\n",
									config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].wlan_mode);
						}
						else  if (0 == strncasecmp(content_buf, WLAN_INTERNET_MODE_TAG, str_size))
						{
							config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].wlan_mode = INTERNET;
							config->num_wlan_guest_ap++;
							IPACMDBG_H("Wlan-mode internet(%d)\n",
									config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].wlan_mode);
						}
					}
				}
				else if (IPACM_util_icmp_string((char*)xml_node->name, SUBNETADDRESS_TAG) == 0)
				{
					content = IPACM_read_content_element(xml_node);
					if (content)
					{
						str_size = strlen(content);
						memset(content_buf, 0, sizeof(content_buf));
						memcpy(content_buf, (void *)content, str_size);
						content_buf[MAX_XML_STR_LEN-1] = '\0';
						config->private_subnet_config.private_subnet_entries[config->private_subnet_config.num_subnet_entries - 1].subnet_addr
							 = ntohl(inet_addr(content_buf));
						IPACMDBG_H("subnet_addr: %s \n", content_buf);
					}
				}
				else if (IPACM_util_icmp_string((char*)xml_node->name, SUBNETMASK_TAG) == 0)
				{
					content = IPACM_read_content_element(xml_node);
					if (content)
					{
						str_size = strlen(content);
						memset(content_buf, 0, sizeof(content_buf));
						memcpy(content_buf, (void *)content, str_size);
						content_buf[MAX_XML_STR_LEN-1] = '\0';
						config->private_subnet_config.private_subnet_entries[config->private_subnet_config.num_subnet_entries - 1].subnet_mask
							 = ntohl(inet_addr(content_buf));
						IPACMDBG_H("subnet_mask: %s \n", content_buf);
					}
				}
				else if (IPACM_util_icmp_string((char*)xml_node->name, Protocol_TAG) == 0)
				{
					content = IPACM_read_content_element(xml_node);
					if (content)
					{
						str_size = strlen(content);
						memset(content_buf, 0, sizeof(content_buf));
						memcpy(content_buf, (void *)content, str_size);
						content_buf[MAX_XML_STR_LEN-1] = '\0';

						if (0 == strncasecmp(content_buf, TCP_PROTOCOL_TAG, str_size))
						{
							config->alg_config.alg_entries[config->alg_config.num_alg_entries - 1].protocol = IPPROTO_TCP;
							IPACMDBG_H("Protocol %s: %d\n",
									content_buf, config->alg_config.alg_entries[config->alg_config.num_alg_entries - 1].protocol);
						}
						else if (0 == strncasecmp(content_buf, UDP_PROTOCOL_TAG, str_size))
						{
							config->alg_config.alg_entries[config->alg_config.num_alg_entries - 1].protocol = IPPROTO_UDP;
							IPACMDBG_H("Protocol %s: %d\n",
									content_buf, config->alg_config.alg_entries[config->alg_config.num_alg_entries - 1].protocol);
						}
					}
				}
				else if (IPACM_util_icmp_string((char*)xml_node->name, Port_TAG) == 0)
				{
					content = IPACM_read_content_element(xml_node);
					if (content)
					{
						str_size = strlen(content);
						memset(content_buf, 0, sizeof(content_buf));
						memcpy(content_buf, (void *)content, str_size);
						config->alg_config.alg_entries[config->alg_config.num_alg_entries - 1].port
							 = atoi(content_buf);
						IPACMDBG_H("port %d\n", config->alg_config.alg_entries[config->alg_config.num_alg_entries - 1].port);
					}
				}
				else if (IPACM_util_icmp_string((char*)xml_node->name, NAT_MaxEntries_TAG) == 0)
				{
					content = IPACM_read_content_element(xml_node);
					if (content)
					{
						str_size = strlen(content);
						memset(content_buf, 0, sizeof(content_buf));
						memcpy(content_buf, (void *)content, str_size);
						config->nat_max_entries = atoi(content_buf);
						IPACMDBG_H("Nat Table Max Entries %d\n", config->nat_max_entries);
					}
				}
			}
			break;
		default:
			break;
		}
		/* go to sibling */
		xml_node = xml_node->next;
	} /* end while */
	return ret_val;
}
int IPACM_EvtDispatcher::PostEvt
(
	 ipacm_cmd_q_data *data
)
{
	Message *item = NULL;
	MessageQueue *MsgQueue = NULL;

	if(data->event < IPA_EXTERNAL_EVENT_MAX)
	{
		IPACMDBG("Insert event into external queue.\n");
		MsgQueue = MessageQueue::getInstanceExternal();
	}
	else
	{
		IPACMDBG("Insert event into internal queue.\n");
		MsgQueue = MessageQueue::getInstanceInternal();
	}
	if(MsgQueue == NULL)
	{
		IPACMERR("unable to retrieve MsgQueue instance\n");
		return IPACM_FAILURE;
	}

	item = new Message();
	if(item == NULL)
	{
		IPACMERR("unable to create new message item\n");
		return IPACM_FAILURE;
	}

	item->evt.callback_ptr = IPACM_EvtDispatcher::ProcessEvt;
	memcpy(&item->evt.data, data, sizeof(ipacm_cmd_q_data));

	if(pthread_mutex_lock(&mutex) != 0)
	{
		IPACMERR("unable to lock the mutex\n");
		return IPACM_FAILURE;
	}

	IPACMDBG("Enqueing item\n");
	MsgQueue->enqueue(item);
	IPACMDBG("Enqueued item %p\n", item);

	if(pthread_cond_signal(&cond_var) != 0)
	{
		IPACMDBG("unable to lock the mutex\n");
		/* Release the mutex before you return failure */
		if(pthread_mutex_unlock(&mutex) != 0)
		{
			IPACMERR("unable to unlock the mutex\n");
			return IPACM_FAILURE;
		}
		return IPACM_FAILURE;
	}

	if(pthread_mutex_unlock(&mutex) != 0)
	{
		IPACMERR("unable to unlock the mutex\n");
		return IPACM_FAILURE;
	}

	return IPACM_SUCCESS;
}
void IPACM_IfaceManager::event_callback(ipa_cm_event_id event, void *param)
{
	int ipa_interface_index;
	ipacm_event_data_fid *evt_data = (ipacm_event_data_fid *)param;
	ipacm_event_data_mac *StaData = (ipacm_event_data_mac *)param;
	ipacm_event_data_all *data_all = (ipacm_event_data_all *)param;
	ipacm_ifacemgr_data ifmgr_data = {0};

	switch(event)
	{
		case IPA_CFG_CHANGE_EVENT:
				IPACMDBG_H(" RESET IPACM_cfg \n");
				IPACM_Iface::ipacmcfg->Init();
			break;
		case IPA_BRIDGE_LINK_UP_EVENT:
			IPACMDBG_H(" Save the bridge0 mac info in IPACM_cfg \n");
			ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
			/* check for failure return */
			if (IPACM_FAILURE == ipa_interface_index) {
				IPACMERR("IPA_BRIDGE_LINK_UP_EVENT: not supported iface id: %d\n", data_all->if_index);
				break;
			}
			/* check if iface is bridge interface*/
			if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) == 0)
			{
				IPACM_Iface::ipacmcfg->ipa_bridge_enable = true;
				memcpy(IPACM_Iface::ipacmcfg->bridge_mac,
								data_all->mac_addr,
								sizeof(IPACM_Iface::ipacmcfg->bridge_mac));
				IPACMDBG_H("cached bridge0 MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
						 IPACM_Iface::ipacmcfg->bridge_mac[0], IPACM_Iface::ipacmcfg->bridge_mac[1], IPACM_Iface::ipacmcfg->bridge_mac[2],
						 IPACM_Iface::ipacmcfg->bridge_mac[3], IPACM_Iface::ipacmcfg->bridge_mac[4], IPACM_Iface::ipacmcfg->bridge_mac[5]);
			}
			break;
		case IPA_LINK_UP_EVENT:
			IPACMDBG_H("Recieved IPA_LINK_UP_EVENT event: link up %d: \n", evt_data->if_index);
			ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
			/* check for failure return */
			if (IPACM_FAILURE == ipa_interface_index) {
				IPACMERR("IPA_LINK_UP_EVENT: not supported iface id: %d\n", evt_data->if_index);
				break;
			}
			/* LTE-backhaul */
			if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == EMBMS_IF)
			{
				IPACMDBG("WAN-EMBMS (%s) link already up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
			}
			else if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF)
			{
				IPACMDBG_H("WAN-LTE (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
				ifmgr_data.if_index = evt_data->if_index;
				ifmgr_data.if_type = Q6_WAN;
				create_iface_instance(&ifmgr_data);
			}
			break;

		case IPA_USB_LINK_UP_EVENT:
			IPACMDBG_H("Recieved IPA_USB_LINK_UP_EVENT event: link up %d: \n", evt_data->if_index);
			ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
			/* check for failure return */
			if (IPACM_FAILURE == ipa_interface_index) {
				IPACMERR("IPA_USB_LINK_UP_EVENT: not supported iface id: %d\n", evt_data->if_index);
				break;
			}
			/* check if it's WAN_IF */
			if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF)
			{
				/* usb-backhaul using sta_mode ECM_WAN*/
				IPACMDBG_H("WAN-usb (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name, evt_data->if_index);
				ifmgr_data.if_index = evt_data->if_index;
				ifmgr_data.if_type = ECM_WAN;
				create_iface_instance(&ifmgr_data);
			}
			else
			{
				ifmgr_data.if_index = evt_data->if_index;
				ifmgr_data.if_type = Q6_WAN;
				create_iface_instance(&ifmgr_data);
			}
			break;

		case IPA_WLAN_AP_LINK_UP_EVENT:
			ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
			/* check for failure return */
			if (IPACM_FAILURE == ipa_interface_index) {
				IPACMERR("IPA_WLAN_AP_LINK_UP_EVENT: not supported iface id: %d\n", evt_data->if_index);
				break;
			}
			/* change iface category from unknown to WLAN_IF */
			if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == UNKNOWN_IF)
			{
				IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = WLAN_IF;
				IPACMDBG_H("WLAN AP (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
				ifmgr_data.if_index = evt_data->if_index;
				ifmgr_data.if_type = Q6_WAN;
				create_iface_instance(&ifmgr_data);
			}
			else
			{
				IPACMDBG_H("iface %s already up and act as %d mode: \n",IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat);
			}
			break;

		case IPA_WLAN_STA_LINK_UP_EVENT:
			ipa_interface_index = IPACM_Iface::iface_ipa_index_query(StaData->if_index);
			/* check for failure return */
			if (IPACM_FAILURE == ipa_interface_index) {
				IPACMERR("IPA_WLAN_STA_LINK_UP_EVENT: not supported iface id: %d\n", StaData->if_index);
				break;
			}
			/* change iface category from unknown to WAN_IF */
			if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == UNKNOWN_IF)
			{
				/* wlan-backhaul using sta_mode WLAN_WAN */
				IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = WAN_IF;
				IPACMDBG_H("WLAN STA (%s) link up, iface: %d: \n",
				IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name, StaData->if_index);

				ifmgr_data.if_index = StaData->if_index;
				ifmgr_data.if_type = WLAN_WAN;
				memcpy(ifmgr_data.mac_addr, StaData->mac_addr, sizeof(ifmgr_data.mac_addr));
				create_iface_instance(&ifmgr_data);
			}
			else
			{
				IPACMDBG_H("iface %s already up and act as %d mode: \n",
				IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,
						IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat);
			}
			break;

		/* Add new instance open for eMBMS iface and wan iface */
		case IPA_WAN_EMBMS_LINK_UP_EVENT:
			ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
			/* check for failure return */
			if (IPACM_FAILURE == ipa_interface_index) {
				IPACMERR("IPA_WAN_EMBMS_LINK_UP_EVENT: not supported iface id: %d\n", evt_data->if_index);
				break;
			}
			/* change iface category from unknown to EMBMS_IF */
			if ((IPACM_Iface::ipacmcfg->ipacm_odu_enable == true) && (IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable == true))
			{
				IPACMDBG(" ODU-mode enable or not (%d) \n",IPACM_Iface::ipacmcfg->ipacm_odu_enable);
				if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF)
				{
					IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat=EMBMS_IF;
					IPACMDBG("WAN eMBMS (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
					ifmgr_data.if_index = StaData->if_index;
					ifmgr_data.if_type = Q6_WAN;
					create_iface_instance(&ifmgr_data);
				}
				else
				{
					IPACMDBG("iface %s already up and act as %d mode: \n",IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat);
				}
			}
			break;

		default:
			break;
	}
	return;
}
int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param)
{
	int if_index = param->if_index;
	ipacm_wan_iface_type is_sta_mode = param->if_type;

	int ipa_interface_index;
	ipa_interface_index = IPACM_Iface::iface_ipa_index_query(if_index);

	if(ipa_interface_index == INVALID_IFACE)
	{
			IPACMDBG_H("Unhandled interface received, fid: %d\n",if_index);
			return IPACM_SUCCESS;
	}

	/* check if duplicate instance*/
	if(SearchInstance(ipa_interface_index) == IPA_INSTANCE_NOT_FOUND)
	{
		/* IPA_INSTANCE_NOT_FOUND */
		switch(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat)
		{

		case LAN_IF:
			{
				IPACMDBG_H("Creating Lan interface\n");
				IPACM_Lan *lan = new IPACM_Lan(ipa_interface_index);
				IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, lan);
				//IPACM_EvtDispatcher::registr(IPA_ROUTE_ADD_EVENT, lan);
				//IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, lan);
				IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, lan);
				IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, lan);
				IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, lan);
				IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, lan);
#ifdef FEATURE_IPA_ANDROID
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_TETHER, lan);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6_TETHER, lan);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_TETHER, lan);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6_TETHER, lan);
#else
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, lan);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, lan);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, lan);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, lan);
#endif
				IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, lan); 				// register for IPA_CFG_CHANGE event
				IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, lan); 	// register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event
#ifdef FEATURE_IPA_ANDROID
				IPACM_EvtDispatcher::registr(IPA_TETHERING_STATS_UPDATE_EVENT, lan);
#endif
				IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, lan);
				IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, lan);
				/* IPA_LAN_DELETE_SELF should be always last */
				IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, lan);
				IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", lan->dev_name, lan->ipa_if_num);
				registr(ipa_interface_index, lan);
				/* solve the new_addr comes earlier issue */
                                IPACM_Iface::iface_addr_query(if_index);
			}
			break;

		case ETH_IF:
			{
				IPACMDBG_H("Creating ETH interface in router mode\n");
				IPACM_Lan *ETH = new IPACM_Lan(ipa_interface_index);
				IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, ETH);
				IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, ETH);
				IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, ETH);
				IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, ETH);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, ETH);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, ETH);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, ETH);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, ETH);
				IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, ETH);
				IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, ETH);
				/* IPA_LAN_DELETE_SELF should be always last */
				IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, ETH);
				IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", ETH->dev_name, ETH->ipa_if_num);
				registr(ipa_interface_index, ETH);
				/* solve the new_addr comes earlier issue */
				IPACM_Iface::iface_addr_query(if_index);
			}
			break;

		case ODU_IF:
			{
				if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true)
				{
					IPACMDBG_H("Creating ODU interface in router mode\n");
					IPACM_Lan *odu = new IPACM_Lan(ipa_interface_index);
					IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, odu);
					IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, odu);
					IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, odu);
					IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, odu);
					IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, odu);
					IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, odu);
					IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, odu);
					IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, odu);
					IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, odu);
					IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, odu);
					IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, odu);
					/* IPA_LAN_DELETE_SELF should be always last */
					IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, odu);
					IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", odu->dev_name, odu->ipa_if_num);
					registr(ipa_interface_index, odu);
					/* solve the new_addr comes earlier issue */
					IPACM_Iface::iface_addr_query(if_index);
				}
				else
				{
					IPACMDBG_H("Creating ODU interface in bridge mode\n");
					IPACM_Lan *odu = new IPACM_Lan(ipa_interface_index);
					IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, odu);
					IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, odu);
					IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, odu);
					IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, odu);
					IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, odu);
					/* IPA_LAN_DELETE_SELF should be always last */
					IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, odu);
					IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", odu->dev_name, odu->ipa_if_num);
					registr(ipa_interface_index, odu);
					/* solve the new_addr comes earlier issue */
					IPACM_Iface::iface_addr_query(if_index);
				}
			}
			break;

		case WLAN_IF:
			{
				IPACMDBG_H("Creating WLan interface\n");
				IPACM_Wlan *wl = new IPACM_Wlan(ipa_interface_index);
				IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, wl);
				IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, wl);
				IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_ADD_EVENT, wl);
				IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_ADD_EVENT_EX, wl);
				IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_DEL_EVENT, wl);
				IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_POWER_SAVE_EVENT, wl);
				IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_RECOVER_EVENT, wl);
				IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, wl);
				IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, wl);
				IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, wl);
#ifdef FEATURE_IPA_ANDROID
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_TETHER, wl);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6_TETHER, wl);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_TETHER, wl);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6_TETHER, wl);
#else
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, wl);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, wl);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, wl);
				IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, wl);
#endif
				IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, wl); 	// register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event
#ifdef FEATURE_ETH_BRIDGE_LE
				IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, wl);
#endif
				IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, wl);
				IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, wl);
#ifndef FEATURE_IPA_ANDROID
				IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_SCC, wl);
				IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_MCC, wl);
#else
				IPACM_EvtDispatcher::registr(IPA_TETHERING_STATS_UPDATE_EVENT, wl);
#endif
				/* IPA_LAN_DELETE_SELF should be always last */
				IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, wl);
				IPACMDBG_H("ipa_WLAN (%s):ipa_index (%d) instance open/registr ok\n", wl->dev_name, wl->ipa_if_num);
				registr(ipa_interface_index, wl);
				/* solve the new_addr comes earlier issue */
	            IPACM_Iface::iface_addr_query(if_index);
			}
			break;

		case WAN_IF:
			{
				if((IPACM_Iface::ipacmcfg->ipacm_odu_enable == false) || (IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true))
				{
					IPACMDBG_H("Creating Wan interface\n");
					IPACM_Wan *w;
					if(is_sta_mode == WLAN_WAN)
					{
						w = new IPACM_Wan(ipa_interface_index, is_sta_mode, param->mac_addr);
					}
					else
					{
						w = new IPACM_Wan(ipa_interface_index, is_sta_mode, NULL);
					}
					IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, w);
#ifdef FEATURE_IPA_ANDROID
					IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, w);
					IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT, w);
					if(is_sta_mode == Q6_WAN)
					{
						IPACM_EvtDispatcher::registr(IPA_NETWORK_STATS_UPDATE_EVENT, w);
					};
#else/* defined(FEATURE_IPA_ANDROID) */
					IPACM_EvtDispatcher::registr(IPA_ROUTE_ADD_EVENT, w);
					IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, w);
#endif /* not defined(FEATURE_IPA_ANDROID)*/
					IPACM_EvtDispatcher::registr(IPA_FIREWALL_CHANGE_EVENT, w);
					IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, w);
					IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, w);
					IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, w);
					IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, w); 		// register for IPA_CFG_CHANGE event
					IPACM_EvtDispatcher::registr(IPA_WAN_XLAT_CONNECT_EVENT, w);
					if(is_sta_mode == WLAN_WAN)
					{
						IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, w); // for STA mode
#ifndef FEATURE_IPA_ANDROID
						IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_SCC, w);
						IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_MCC, w);
#endif
					}
					else
					{
						IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, w);
					}

					IPACMDBG_H("ipa_WAN (%s):ipa_index (%d) instance open/registr ok\n", w->dev_name, w->ipa_if_num);
					registr(ipa_interface_index, w);
					/* solve the new_addr comes earlier issue */
					IPACM_Iface::iface_addr_query(if_index);
				}
			}
			break;

	    /* WAN-eMBMS instance */
		case EMBMS_IF:
			{
				IPACMDBG("Creating Wan-eMBSM interface\n");
				IPACM_Wan *embms = new IPACM_Wan(ipa_interface_index, is_sta_mode, NULL);
				IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, embms);
				IPACMDBG("ipa_WAN (%s):ipa_index (%d) instance open/registr ok\n", embms->dev_name, embms->ipa_if_num);
				registr(ipa_interface_index, embms);
			}
			break;

		default:
			IPACMDBG_H("Unhandled interface category received iface name: %s, category: %d\n",
			            IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,
						       IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat);
			return IPACM_SUCCESS;
		}
	}
	return IPACM_SUCCESS;
}
Пример #11
0
void IPACM_LanToLan::check_cache_connection(ipa_ip_type iptype, client_info* client)
{
#ifdef CT_OPT
	connection_list::iterator it;
	if(iptype == IPA_IP_v4)
	{
		it = connection_v4_.begin();
		while(it != connection_v4_.end())
		{
			if( (it->src_ipv4_addr == client->ip.ipv4_addr && client_info_v4_.count(it->dst_ipv4_addr) > 0)
				|| (it->dst_ipv4_addr == client->ip.ipv4_addr && client_info_v4_.count(it->src_ipv4_addr) > 0) )
			{
				IPACMDBG("Found a cache connection for src client 0x%08x and dst client 0x%08x.\n", it->src_ipv4_addr, it->dst_ipv4_addr);
				ipacm_cmd_q_data evt;
				ipacm_event_connection* conn;

				conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection));
				if(conn == NULL)
				{
					IPACMERR("Failed to allocate memory for new_connection event.\n");
					return;
				}
				memcpy(conn, &(*it), sizeof(ipacm_event_connection));

				memset(&evt, 0, sizeof(evt));
				evt.event = IPA_LAN_TO_LAN_NEW_CONNECTION;
				evt.evt_data = (void*)conn;
				IPACM_EvtDispatcher::PostEvt(&evt);

				it = connection_v4_.erase(it);
				IPACMDBG_H("Now the number of cache connections is %d.\n", connection_v4_.size());
			}
			else
			{
				it++;
			}
		}
	}
	else
	{
		uint64_t src_v6_addr, dst_v6_addr;
		it = connection_v6_.begin();
		while(it != connection_v6_.end())
		{
			memcpy(&src_v6_addr, &(it->src_ipv6_addr[2]), sizeof(uint64_t));
			memcpy(&dst_v6_addr, &(it->dst_ipv6_addr[2]), sizeof(uint64_t));
			if( (memcmp(it->src_ipv6_addr, client->ip.ipv6_addr, 4*sizeof(uint32_t)) == 0 && client_info_v6_.count(dst_v6_addr) > 0)
				|| (memcmp(it->dst_ipv6_addr, client->ip.ipv6_addr, 4*sizeof(uint32_t)) == 0 && client_info_v6_.count(src_v6_addr) > 0) )
			{
				IPACMDBG("Found a cache connection with src client 0x%08x%08x%08x%08x and dst client 0x%08x%08x%08x%08x.\n", it->src_ipv6_addr[0],
							it->src_ipv6_addr[1], it->src_ipv6_addr[2], it->src_ipv6_addr[3], it->dst_ipv6_addr[0], it->dst_ipv6_addr[1],
							it->dst_ipv6_addr[2], it->dst_ipv6_addr[3]);
				ipacm_cmd_q_data evt;
				ipacm_event_connection* conn;

				conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection));
				if(conn == NULL)
				{
					IPACMERR("Failed to allocate memory for new_connection event.\n");
					return;
				}
				memcpy(conn, &(*it), sizeof(ipacm_event_connection));

				memset(&evt, 0, sizeof(evt));
				evt.event = IPA_LAN_TO_LAN_NEW_CONNECTION;
				evt.evt_data = (void*)conn;
				IPACM_EvtDispatcher::PostEvt(&evt);

				it = connection_v6_.erase(it);
				IPACMDBG_H("Now the number of cache connections is %d.\n", connection_v6_.size());
			}
			else
			{
				it++;
			}
		}
	}
#endif
	return;
}