/* This function read IPACM XML and populate the IPA CM Cfg */ int ipacm_read_cfg_xml(char *xml_file, IPACM_conf_t *config) { xmlDocPtr doc = NULL; xmlNode* root = NULL; int ret_val = IPACM_SUCCESS; /* Invoke the XML parser and obtain the parse tree */ doc = xmlReadFile(xml_file, "UTF-8", XML_PARSE_NOBLANKS); if (doc == NULL) { IPACMDBG_H("IPACM_xml_parse: libxml returned parse error!\n"); return IPACM_FAILURE; } /*Get the root of the tree*/ root = xmlDocGetRootElement(doc); memset(config, 0, sizeof(IPACM_conf_t)); /* parse the xml tree returned by libxml */ ret_val = ipacm_cfg_xml_parse_tree(root, config); if (ret_val != IPACM_SUCCESS) { IPACMDBG_H("IPACM_xml_parse: ipacm_cfg_xml_parse_tree returned parse error!\n"); } /* Free up the libxml's parse tree */ xmlFreeDoc(doc); return ret_val; }
void IPACM_LanToLan::handle_client_add(ipacm_event_eth_bridge *data) { list<IPACM_LanToLan_Iface>::iterator it_iface; IPACMDBG_H("Incoming client MAC: 0x%02x%02x%02x%02x%02x%02x, interface: %s\n", data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], data->p_iface->dev_name); for(it_iface = m_iface.begin(); it_iface != m_iface.end(); it_iface++) { if(it_iface->get_iface_pointer() == data->p_iface) //find the interface { IPACMDBG_H("Found the interface.\n"); it_iface->handle_client_add(data->mac_addr); break; } } /* if the iface was not found, cache the client add event */ if(it_iface == m_iface.end()) { IPACMDBG_H("The interface is not found.\n"); if(m_cached_client_add_event.size() < MAX_NUM_CACHED_CLIENT_ADD_EVENT) { IPACMDBG_H("Cached the client information.\n"); m_cached_client_add_event.push_front(*data); } else { IPACMDBG_H("Cached client add event has reached maximum number.\n"); } } return; }
/* This function read QCMAP CM Firewall XML and populate the QCMAP CM Cfg */ int IPACM_read_firewall_xml(char *xml_file, IPACM_firewall_conf_t *config) { xmlDocPtr doc = NULL; xmlNode* root = NULL; int ret_val; IPACM_ASSERT(xml_file != NULL); IPACM_ASSERT(config != NULL); /* invoke the XML parser and obtain the parse tree */ doc = xmlReadFile(xml_file, "UTF-8", XML_PARSE_NOBLANKS); if (doc == NULL) { IPACMDBG_H("IPACM_xml_parse: libxml returned parse error\n"); return IPACM_FAILURE; } /*get the root of the tree*/ root = xmlDocGetRootElement(doc); /* parse the xml tree returned by libxml*/ ret_val = IPACM_firewall_xml_parse_tree(root, config); if (ret_val != IPACM_SUCCESS) { IPACMDBG_H("IPACM_xml_parse: ipacm_firewall_xml_parse_tree returned parse error!\n"); } /* free the tree */ xmlFreeDoc(doc); return ret_val; }
void IPACM_LanToLan_Iface::del_client_flt_rule(peer_iface_info *peer, client_info *client) { list<flt_rule_info>::iterator it_flt; for(it_flt = peer->flt_rule.begin(); it_flt != peer->flt_rule.end(); it_flt++) { if(it_flt->p_client == client) //found the client in flt info list { IPACMDBG_H("Found the client in flt info list.\n"); if(m_is_ip_addr_assigned[IPA_IP_v4]) { m_p_iface->eth_bridge_del_flt_rule(it_flt->flt_rule_hdl[IPA_IP_v4], IPA_IP_v4); IPACMDBG_H("IPv4 flt rule %d is deleted.\n", it_flt->flt_rule_hdl[IPA_IP_v4]); } if(m_is_ip_addr_assigned[IPA_IP_v6]) { m_p_iface->eth_bridge_del_flt_rule(it_flt->flt_rule_hdl[IPA_IP_v6], IPA_IP_v6); IPACMDBG_H("IPv6 flt rule %d is deleted.\n", it_flt->flt_rule_hdl[IPA_IP_v6]); } peer->flt_rule.erase(it_flt); break; } } return; }
void IPACM_LanToLan::handle_iface_down(ipacm_event_eth_bridge *data) { list<IPACM_LanToLan_Iface>::iterator it_target_iface; IPACMDBG_H("Interface name: %s\n", data->p_iface->dev_name); for(it_target_iface = m_iface.begin(); it_target_iface != m_iface.end(); it_target_iface++) { if(it_target_iface->get_iface_pointer() == data->p_iface) { IPACMDBG_H("Found the interface.\n"); break; } } if(it_target_iface == m_iface.end()) { IPACMDBG_H("The interface has not been found.\n"); /* clear cached client add event for the unfound interface*/ clear_cached_client_add_event(data->p_iface); return; } it_target_iface->handle_down_event(); m_iface.erase(it_target_iface); return; }
void IPACM_LanToLan::cache_new_connection(ipacm_event_connection* new_conn) { if(is_potential_lan2lan_connection(new_conn) == true) { if(new_conn->iptype == IPA_IP_v4) { if(connection_v4_.size() == max_cache_connection) { IPACMDBG_H("Cached ipv4 connections already reach maximum, clear up the list.\n"); connection_v4_.clear(); } connection_v4_.push_back(*new_conn); IPACMDBG_H("Cache an ipv4 connection, now the number of ipv4 cache connection is %d.\n", connection_v4_.size()); } else { if(connection_v6_.size() == max_cache_connection) { IPACMDBG_H("Cached ipv6 connections already reach maximum, clear up the list.\n"); connection_v6_.clear(); } connection_v6_.push_back(*new_conn); IPACMDBG_H("Cache an ipv6 connection, now the number of ipv6 cache connection is %d.\n", connection_v6_.size()); } } return; }
IPACM_LanToLan_Iface::IPACM_LanToLan_Iface(IPACM_Lan *p_iface) { int i; m_p_iface = p_iface; memset(m_is_ip_addr_assigned, 0, sizeof(m_is_ip_addr_assigned)); m_support_inter_iface_offload = true; m_support_intra_iface_offload = false; for(i = 0; i < IPA_HDR_L2_MAX; i++) { ref_cnt_peer_l2_hdr_type[i] = 0; hdr_proc_ctx_for_inter_interface[i] = 0; } hdr_proc_ctx_for_intra_interface = 0; if(p_iface->ipa_if_cate == WLAN_IF) { IPACMDBG_H("Interface %s is WLAN interface.\n", p_iface->dev_name); m_support_intra_iface_offload = true; if( ((IPACM_Wlan*)p_iface)->is_guest_ap() ) { IPACMDBG_H("Interface %s is guest AP.\n", p_iface->dev_name); m_support_inter_iface_offload = false; } } return; }
void IPACM_LanToLan_Iface::handle_intra_interface_info() { uint32_t hdr_proc_ctx_hdl; if(m_p_iface->tx_prop == NULL) { IPACMERR("No tx prop.\n"); return; } m_intra_interface_info.peer = this; snprintf(m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX, "eth_v4_intra_interface"); IPACMDBG_H("IPv4 routing table for flt name: %s\n", m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v4]); snprintf(m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX, "eth_v6_intra_interface"); IPACMDBG_H("IPv6 routing table for flt name: %s\n", m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v6]); memcpy(m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v4], m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX); IPACMDBG_H("IPv4 routing table for rt name: %s\n", m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v4]); memcpy(m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v6], m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX); IPACMDBG_H("IPv6 routing table for rt name: %s\n", m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v6]); m_p_iface->eth_bridge_add_hdr_proc_ctx(m_p_iface->tx_prop->tx[0].hdr_l2_type, &hdr_proc_ctx_hdl); hdr_proc_ctx_for_intra_interface = hdr_proc_ctx_hdl; IPACMDBG_H("Hdr proc ctx for intra-interface communication: hdl %d\n", hdr_proc_ctx_hdl); return; }
void IPACM_LanToLan::print_data_structure_info() { list<IPACM_LanToLan_Iface>::iterator it; list<ipacm_event_eth_bridge>::iterator it_event; int i; IPACMDBG_H("There are %d interfaces in total.\n", m_iface.size()); for(it = m_iface.begin(); it != m_iface.end(); it++) { it->print_data_structure_info(); } IPACMDBG_H("There are %d cached client add events in total.\n", m_cached_client_add_event.size()); i = 1; for(it_event = m_cached_client_add_event.begin(); it_event != m_cached_client_add_event.end(); it_event++) { IPACMDBG_H("Client %d MAC: 0x%02x%02x%02x%02x%02x%02x, interface: %s\n", i, it_event->mac_addr[0], it_event->mac_addr[1], it_event->mac_addr[2], it_event->mac_addr[3], it_event->mac_addr[4], it_event->mac_addr[5], it_event->p_iface->dev_name); i++; } return; }
void IPACM_LanToLan::handle_client_power_save(ipacm_event_lan_client* data) { if(data == NULL) { IPACMERR("No client info is found.\n"); return; } if(data->mac_addr == NULL || data->ipv6_addr == NULL || data->p_iface == NULL) { IPACMERR("Event data is not populated properly.\n"); return; } if(data->iptype != IPA_IP_v4 && data->iptype != IPA_IP_v6) { IPACMERR("IP type is not expected: %d.\n", data->iptype); return; } IPACMDBG_H("Client power save info: iface %s, iptype: %d, mac: 0x%02x%02x%02x%02x%02x%02x, v4_addr: 0x%08x, v6_addr: 0x%08x%08x%08x%08x \n", data->p_iface->dev_name, data->iptype, data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], data->ipv4_addr, data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); client_info* client_ptr; uint64_t v6_addr; if(data->iptype == IPA_IP_v4) { if(client_info_v4_.count(data->ipv4_addr) == 0)//if not found the client, return { IPACMERR("The client is not found the client, return.\n"); return; } IPACMDBG_H("The client is found.\n"); client_info& client = client_info_v4_[data->ipv4_addr]; client_ptr = &client; } else { memcpy(&v6_addr, &(data->ipv6_addr[2]), sizeof(uint64_t)); if(client_info_v6_.count(v6_addr) == 0) //if not found the client, insert it in table { IPACMERR("The client is not found the client, return.\n"); return; } IPACMDBG_H("The client is found.\n"); client_info& client = client_info_v6_[v6_addr]; client_ptr = &client; } if(remove_flt_rules(data->iptype, client_ptr) == IPACM_FAILURE) { IPACMERR("Failed to remove flt rules when power save.\n"); return; } client_ptr->is_active = false; client_ptr->is_powersave = true; return; }
int IPACM_Config::Init(void) { /* Read IPACM Config file */ char IPACM_config_file[IPA_MAX_FILE_LEN]; IPACM_conf_t *cfg; cfg = (IPACM_conf_t *)malloc(sizeof(IPACM_conf_t)); if(cfg == NULL) { IPACMERR("Unable to allocate cfg memory.\n"); return IPACM_FAILURE; } uint32_t subnet_addr; uint32_t subnet_mask; int i, ret = IPACM_SUCCESS; struct in_addr in_addr_print; m_fd = open(DEVICE_NAME, O_RDWR); if (0 > m_fd) { IPACMERR("Failed opening %s.\n", DEVICE_NAME); } strncpy(IPACM_config_file, "/etc/IPACM_cfg.xml", sizeof(IPACM_config_file)); IPACMDBG_H("\n IPACM XML file is %s \n", IPACM_config_file); if (IPACM_SUCCESS == ipacm_read_cfg_xml(IPACM_config_file, cfg)) { IPACMDBG_H("\n IPACM XML read OK \n"); } else { IPACMERR("\n IPACM XML read failed \n"); ret = IPACM_FAILURE; goto fail; } /* Check wlan AP-AP access mode configuration */ if (cfg->num_wlan_guest_ap == 2) { IPACMDBG_H("IPACM_Config::Both wlan APs can not be configured in guest ap mode. \n"); IPACMDBG_H("IPACM_Config::configure both APs in full access mode or at least one in guest ap mode. \n"); ret = IPACM_FAILURE; goto fail; } /* Construct IPACM Iface table */ ipa_num_ipa_interfaces = cfg->iface_config.num_iface_entries; if (iface_table != NULL) { free(iface_table); iface_table = NULL; IPACMDBG_H("RESET IPACM_Config::iface_table\n"); } iface_table = (ipa_ifi_dev_name_t *)calloc(ipa_num_ipa_interfaces, sizeof(ipa_ifi_dev_name_t)); if(iface_table == NULL) { IPACMERR("Unable to allocate iface_table memory.\n"); ret = IPACM_FAILURE; <<<<<<< HEAD
int IPACM_LanToLan::turnoff_offload_links(ipa_ip_type iptype, client_info* client) { if(client == NULL) { IPACMERR("Client is NULL.\n"); return IPACM_FAILURE; } bool err_flag; offload_link_info_list::iterator client_it; offload_link_info_list::iterator peer_it; client_info* peer; for(client_it = client->link.begin(); client_it != client->link.end(); client_it++) { peer = client_it->peer_pointer; if(del_offload_link(iptype, client->p_iface, peer->p_iface, &(*client_it)) == IPACM_FAILURE) { IPACMERR("Failed to delete client's offload link.\n"); return IPACM_FAILURE; } err_flag = true; for(peer_it = peer->link.begin(); peer_it != peer->link.end(); peer_it++) { if(peer_it->peer_pointer == client) { if(del_offload_link(iptype, peer->p_iface, client->p_iface, &(*peer_it)) == IPACM_FAILURE) { IPACMERR("Failed to delete peer's offload link.\n"); return IPACM_FAILURE; } peer->link.erase(peer_it); err_flag = false; break; } } if(err_flag) { IPACMERR("Unable to find corresponding offload link in peer's entry.\n"); return IPACM_FAILURE; } if(iptype == IPA_IP_v4) { num_offload_pair_v4_ --; IPACMDBG_H("Now the number of v4 offload pair is %d\n", num_offload_pair_v4_); } else { num_offload_pair_v6_ --; IPACMDBG_H("Now the number of v6 offload pair is %d\n", num_offload_pair_v6_); } } client->link.clear(); return IPACM_SUCCESS; }
//If need to remove an entry in peer list, return true, otherwise return false bool IPACM_LanToLan::remove_connection(client_info* src_client, client_info* dst_client) { if(src_client == NULL || dst_client == NULL) { IPACMERR("Either source or dest client is NULL.\n"); return false; } peer_info_list::iterator it; bool ret = false; for(it = src_client->peer.begin(); it != src_client->peer.end(); it++) { if(it->peer_pointer == dst_client) { it->num_connection--; IPACMDBG_H("Find dst client entry in src peer list, connection count: %d\n", it->num_connection); if(it->num_connection == 0) { IPACMDBG_H("Need to remove dst entry in src peer list.\n"); ret = true; } break; } } if(ret == true) { src_client->peer.erase(it); } ret = false; for(it = dst_client->peer.begin(); it != dst_client->peer.end(); it++) { if(it->peer_pointer == src_client) { it->num_connection--; IPACMDBG_H("Find src client entry in dst peer list, connection count: %d\n", it->num_connection); if(it->num_connection == 0) { IPACMDBG_H("Need to remove src entry in dst peer list.\n"); ret = true; } break; } } if(ret == true) { dst_client->peer.erase(it); } return ret; }
void IPACM_LanToLan::erase_offload_link(ipa_ip_type iptype, client_info* src_client, client_info* dst_client) { if(src_client == NULL || dst_client == NULL) { IPACMERR("Either source or dest client is NULL.\n"); return; } offload_link_info_list::iterator it; int res_src = IPACM_FAILURE, res_dst = IPACM_FAILURE; for(it = src_client->link.begin(); it != src_client->link.end(); it++) { if(it->peer_pointer == dst_client) { res_src = IPACM_SUCCESS; IPACMDBG_H("Find dst client entry in src link list\n"); res_src = del_offload_link(iptype, src_client->p_iface, dst_client->p_iface, &(*it)); src_client->link.erase(it); break; } } for(it = dst_client->link.begin(); it != dst_client->link.end(); it++) { if(it->peer_pointer == src_client) { res_dst = IPACM_SUCCESS; IPACMDBG_H("Find src client entry in dst link list\n"); res_dst = del_offload_link(iptype, dst_client->p_iface, src_client->p_iface, &(*it)); dst_client->link.erase(it); break; } } if(res_src == IPACM_SUCCESS && res_dst == IPACM_SUCCESS) { if(iptype == IPA_IP_v4) { num_offload_pair_v4_ --; IPACMDBG_H("Decrease num of v4 offload pairs to %d\n", num_offload_pair_v4_); } else { num_offload_pair_v6_ --; IPACMDBG_H("Decrease num of v6 offload pairs to %d\n", num_offload_pair_v6_); } } return; }
//If need to insert an entry in peer list, return true, otherwise return false bool IPACM_LanToLan::add_connection(client_info* src_client, client_info* dst_client) { if(src_client == NULL || dst_client == NULL) { IPACMERR("Either source or dest client is NULL.\n"); return false; } peer_info_list::iterator it; peer_info new_peer; bool ret = false; for(it = src_client->peer.begin(); it != src_client->peer.end(); it++) { if(it->peer_pointer == dst_client) { it->num_connection++; IPACMDBG_H("Find dst client entry in peer list, connection count: %d\n", it->num_connection); break; } } if(it == src_client->peer.end()) { IPACMDBG_H("Not finding dst client entry, insert a new one in peer list.\n"); new_peer.peer_pointer = dst_client; new_peer.num_connection = 1; src_client->peer.push_back(new_peer); ret = true; } for(it = dst_client->peer.begin(); it != dst_client->peer.end(); it++) { if(it->peer_pointer == src_client) { it->num_connection++; IPACMDBG_H("Find dst client entry in peer list, connection count: %d\n", it->num_connection); break; } } if(it == dst_client->peer.end()) { IPACMDBG_H("Not finding src client entry, insert a new one in peer list.\n"); new_peer.peer_pointer = src_client; new_peer.num_connection = 1; dst_client->peer.push_back(new_peer); ret = true; } return ret; }
bool IPACM_Routing::ModifyRoutingRule(struct ipa_ioc_mdfy_rt_rule *mdfyRules) { int retval = 0, cnt; if (!DeviceNodeIsOpened()) { IPACMERR("Device is not opened\n"); return false; } retval = ioctl(m_fd, IPA_IOC_MDFY_RT_RULE, mdfyRules); if (retval) { IPACMERR("Failed modifying routing rules %p\n", mdfyRules); return false; } for(cnt=0; cnt<mdfyRules->num_rules; cnt++) { if(mdfyRules->rules[cnt].status != 0) { IPACMERR("Unable to modify rule: %d\n", cnt); } } IPACMDBG_H("Modified routing rules %p\n", mdfyRules); return true; }
int IPACM_LanToLan::del_offload_link(ipa_ip_type iptype, IPACM_Lan* client, IPACM_Lan* peer, offload_link_info* link) { if(client == NULL || peer == NULL || link == NULL) { IPACMERR("Either iface or link is NULL.\n"); return IPACM_FAILURE; } IPACMDBG_H("Delete an offload link for IP type: %d\n", iptype); int res = IPACM_SUCCESS; if(client->del_lan2lan_flt_rule(iptype, link->flt_rule_hdl) == IPACM_FAILURE) { IPACMERR("Failed to delete flt rule.\n"); res = IPACM_FAILURE; } if(peer->del_lan2lan_rt_rule(iptype, link->rt_rule_hdl) == IPACM_FAILURE) { IPACMERR("Failed to delete rt rules.\n"); res = IPACM_FAILURE; } if(peer->del_lan2lan_hdr(iptype, link->hdr_hdl) == IPACM_FAILURE) { IPACMERR("Failed to delete header.\n"); res = IPACM_FAILURE; } return res; }
void IPACM_LanToLan_Iface::decrement_ref_cnt_peer_l2_hdr_type(ipa_hdr_l2_type peer_l2_type) { ref_cnt_peer_l2_hdr_type[peer_l2_type]--; IPACMDBG_H("Now the ref_cnt of peer l2 hdr type %s is %d.\n", ipa_l2_hdr_type[peer_l2_type], ref_cnt_peer_l2_hdr_type[peer_l2_type]); return; }
void IPACM_LanToLan_Iface::del_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_type) { if(ref_cnt_peer_l2_hdr_type[peer_l2_type] == 0) { m_p_iface->eth_bridge_del_hdr_proc_ctx(hdr_proc_ctx_for_inter_interface[peer_l2_type]); IPACMDBG_H("Hdr proc ctx with hdl %d is deleted.\n", hdr_proc_ctx_for_inter_interface[peer_l2_type]); } return; }
void IPACM_LanToLan::handle_del_connection(ipacm_event_connection* new_conn) { #ifdef CT_OPT if(new_conn == NULL) { IPACMERR("No connection info is found.\n"); return; } if(new_conn->iptype != IPA_IP_v4 && new_conn->iptype != IPA_IP_v6) { IPACMERR("IP type is not expected: %d.\n", new_conn->iptype); return; } IPACMDBG_H("Del connection info: IP type: %d, src_v4_addr: 0x%08x, dst_v4_addr: 0x%08x\n", new_conn->iptype, new_conn->src_ipv4_addr, new_conn->dst_ipv4_addr); IPACMDBG_H("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x", new_conn->src_ipv6_addr[0], new_conn->src_ipv6_addr[1], new_conn->src_ipv6_addr[2], new_conn->src_ipv6_addr[3], new_conn->dst_ipv6_addr[0], new_conn->dst_ipv6_addr[1], new_conn->dst_ipv6_addr[2], new_conn->dst_ipv6_addr[3]); if(is_lan2lan_connection(new_conn) == false) { IPACMDBG_H("The connection is not lan2lan connection.\n"); remove_cache_connection(new_conn); return; } 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 del_connection event.\n"); return; } memcpy(conn, new_conn, sizeof(ipacm_event_connection)); memset(&evt, 0, sizeof(evt)); evt.event = IPA_LAN_TO_LAN_DEL_CONNECTION; evt.evt_data = (void*)conn; IPACM_EvtDispatcher::PostEvt(&evt); #endif return; }
void IPACM_LanToLan_Iface::add_client_flt_rule(peer_iface_info *peer, client_info *client, ipa_ip_type iptype) { list<flt_rule_info>::iterator it_flt; uint32_t flt_rule_hdl; flt_rule_info new_flt_info; ipa_ioc_get_rt_tbl rt_tbl; rt_tbl.ip = iptype; memcpy(rt_tbl.name, peer->rt_tbl_name_for_flt[iptype], sizeof(rt_tbl.name)); IPACMDBG_H("This flt rule points to rt tbl %s.\n", rt_tbl.name); if(IPACM_Iface::m_routing.GetRoutingTable(&rt_tbl) == false) { IPACMERR("Failed to get routing table.\n"); return; } m_p_iface->eth_bridge_add_flt_rule(client->mac_addr, rt_tbl.hdl, iptype, &flt_rule_hdl); IPACMDBG_H("Installed flt rule for IP type %d: handle %d\n", iptype, flt_rule_hdl); for(it_flt = peer->flt_rule.begin(); it_flt != peer->flt_rule.end(); it_flt++) { if(it_flt->p_client == client) //the client is already in the flt info list { IPACMDBG_H("The client is found in flt info list.\n"); it_flt->flt_rule_hdl[iptype] = flt_rule_hdl; break; } } if(it_flt == peer->flt_rule.end()) //the client is not in the flt info list { IPACMDBG_H("The client is not found in flt info list, insert a new one.\n"); memset(&new_flt_info, 0, sizeof(new_flt_info)); new_flt_info.p_client = client; new_flt_info.flt_rule_hdl[iptype] = flt_rule_hdl; peer->flt_rule.push_front(new_flt_info); } return; }
void IPACM_LanToLan_Iface::clear_all_flt_rule_for_one_peer_iface(peer_iface_info *peer) { list<flt_rule_info>::iterator it; for(it = peer->flt_rule.begin(); it != peer->flt_rule.end(); it++) { if(m_is_ip_addr_assigned[IPA_IP_v4]) { m_p_iface->eth_bridge_del_flt_rule(it->flt_rule_hdl[IPA_IP_v4], IPA_IP_v4); IPACMDBG_H("IPv4 flt rule %d is deleted.\n", it->flt_rule_hdl[IPA_IP_v4]); } if(m_is_ip_addr_assigned[IPA_IP_v6]) { m_p_iface->eth_bridge_del_flt_rule(it->flt_rule_hdl[IPA_IP_v6], IPA_IP_v6); IPACMDBG_H("IPv6 flt rule %d is deleted.\n", it->flt_rule_hdl[IPA_IP_v6]); } } peer->flt_rule.clear(); return; }
void IPACM_LanToLan::check_potential_link(ipa_ip_type iptype, client_info* client) { if(client == NULL) { IPACMERR("Client is NULL.\n"); return; } IPACMDBG_H("Check client's peer list.\n"); IPACMDBG_H("Client: IP type: %d, IPv4 addr: 0x%08x, IPv6 addr: 0x%08x%08x%08x%08x\n", iptype, client->ip.ipv4_addr, client->ip.ipv6_addr[0], client->ip.ipv6_addr[1], client->ip.ipv6_addr[2], client->ip.ipv6_addr[3]); peer_info_list::iterator peer_it; int res, num = 0; for(peer_it = client->peer.begin(); peer_it != client->peer.end(); peer_it++) { if(peer_it->peer_pointer->is_active == true && peer_it->num_connection > 0) { res = IPACM_SUCCESS; res = add_offload_link(iptype, client, peer_it->peer_pointer); res = add_offload_link(iptype, peer_it->peer_pointer, client); if(res == IPACM_SUCCESS) { if(iptype == IPA_IP_v4) { num_offload_pair_v4_ ++; IPACMDBG_H("Now the number of v4 offload links is %d.\n", num_offload_pair_v4_); } else { num_offload_pair_v6_ ++; IPACMDBG_H("Now the number of v6 offload links is %d.\n", num_offload_pair_v6_); } num++; } } } IPACMDBG_H("Added %d offload links in total.\n", num); return; }
int IPACM_IfaceManager::SearchInstance(int ipa_if_index) { iface_instances *tmp = head; while(tmp != NULL) { if(ipa_if_index == tmp->ipa_if_index) { IPACMDBG_H("Find existed iface-instance name: %s\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_index].iface_name); return IPA_INSTANCE_FOUND; } tmp = tmp->next; } IPACMDBG_H("No existed iface-instance name: %s,\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_index].iface_name); return IPA_INSTANCE_NOT_FOUND; }
void IPACM_LanToLan_Iface::add_all_intra_interface_client_flt_rule(ipa_ip_type iptype) { list<client_info>::iterator it_client; IPACMDBG_H("Add flt rules for own clients.\n"); for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++) { add_client_flt_rule(&m_intra_interface_info, &(*it_client), iptype); } return; }
void IPACM_LanToLan_Iface::add_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_type) { uint32_t hdr_proc_ctx_hdl; if(ref_cnt_peer_l2_hdr_type[peer_l2_type] == 1) { m_p_iface->eth_bridge_add_hdr_proc_ctx(peer_l2_type, &hdr_proc_ctx_hdl); hdr_proc_ctx_for_inter_interface[peer_l2_type] = hdr_proc_ctx_hdl; IPACMDBG_H("Installed inter-interface hdr proc ctx on iface %s: handle %d\n", m_p_iface->dev_name, hdr_proc_ctx_hdl); } return; }
void IPACM_LanToLan_Iface::handle_client_del(uint8_t *mac) { list<client_info>::iterator it_client; list<peer_iface_info>::iterator it_peer_info; bool flag[IPA_HDR_L2_MAX]; for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++) { if(memcmp(it_client->mac_addr, mac, sizeof(it_client->mac_addr)) == 0) //found the client { IPACMDBG_H("Found the client.\n"); break; } } if(it_client != m_client_info.end()) //if we found the client { /* uninstall inter-interface rules */ if(m_support_inter_iface_offload) { memset(flag, 0, sizeof(flag)); for(it_peer_info = m_peer_iface_info.begin(); it_peer_info != m_peer_iface_info.end(); it_peer_info++) { IPACMDBG_H("Delete client filtering rule on peer interface.\n"); it_peer_info->peer->del_one_client_flt_rule(this, &(*it_client)); /* make sure to delete routing rule only once for each peer l2 header type */ if(flag[it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type] == false) { IPACMDBG_H("Delete client routing rule for peer interface.\n"); del_client_rt_rule(&(*it_peer_info), &(*it_client)); flag[it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type] = true; } } } /* uninstall intra-interface rules */ if(m_support_intra_iface_offload) { /* delete filtering rule first */ IPACMDBG_H("Delete client filtering rule for intra-interface communication.\n"); del_client_flt_rule(&m_intra_interface_info, &(*it_client)); /* delete routing rule */ IPACMDBG_H("Delete client routing rule for intra-interface communication.\n"); del_client_rt_rule(&m_intra_interface_info, &(*it_client)); } /* erase the client from client info list */ m_client_info.erase(it_client); } else { IPACMDBG_H("The client is not found.\n"); } return; }
void IPACM_LanToLan_Iface::print_peer_info(peer_iface_info *peer_info) { list<flt_rule_info>::iterator it_flt; list<rt_rule_info>::iterator it_rt; IPACMDBG_H("Printing peer info for iface %s:\n", peer_info->peer->m_p_iface->dev_name); IPACMDBG_H("There are %d flt info in total.\n", peer_info->flt_rule.size()); for(it_flt = peer_info->flt_rule.begin(); it_flt != peer_info->flt_rule.end(); it_flt++) { IPACMDBG_H("Flt rule handle for client 0x%08x:\n", it_flt->p_client); if(m_is_ip_addr_assigned[IPA_IP_v4]) { IPACMDBG_H("IPv4 %d\n", it_flt->flt_rule_hdl[IPA_IP_v4]); } if(m_is_ip_addr_assigned[IPA_IP_v6]) { IPACMDBG_H("IPv6 %d\n", it_flt->flt_rule_hdl[IPA_IP_v6]); } } 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; }
void IPACM_LanToLan_Iface::del_one_client_flt_rule(IPACM_LanToLan_Iface *peer_iface, client_info *client) { list<peer_iface_info>::iterator it; for(it = m_peer_iface_info.begin(); it != m_peer_iface_info.end(); it++) { if(it->peer == peer_iface) { IPACMDBG_H("Found the peer iface info.\n"); del_client_flt_rule(&(*it), client); break; } } return; }