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; }
/* 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; }
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; }