IPACM: support ODU project in LE
Enable odu router/bridge mode in ipa-HW for
eMBMS traffic to home router
Change-Id: Icdad38ad8cc8d32a96a05b5512453e539358a5f7
diff --git a/ipacm/inc/IPACM_Config.h b/ipacm/inc/IPACM_Config.h
index c6bb06c..92d4f72 100644
--- a/ipacm/inc/IPACM_Config.h
+++ b/ipacm/inc/IPACM_Config.h
@@ -109,6 +109,10 @@
int ipa_nat_max_entries;
+ bool ipacm_odu_router_mode;
+
+ bool ipacm_odu_enable;
+
int ipa_nat_iface_entries;
/* Store SW-enable or not */
@@ -119,6 +123,8 @@
struct ipa_ioc_get_rt_tbl rt_tbl_wan_dl;
struct ipa_ioc_get_rt_tbl rt_tbl_lan2lan_v4, rt_tbl_lan2lan_v6;
+ struct ipa_ioc_get_rt_tbl rt_tbl_odu_v4, rt_tbl_odu_v6;
+
/* To return the instance */
static IPACM_Config* GetInstance();
@@ -257,6 +263,8 @@
}
#endif /* defined(FEATURE_IPA_ANDROID)*/
+ static const char *DEVICE_NAME_ODU;
+
private:
static IPACM_Config *pInstance;
static const char *DEVICE_NAME;
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index d225f4c..20cde8d 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -58,12 +58,16 @@
#define IPA_WLAN_PARTIAL_HDR_OFFSET 0 // dst mac first then src mac
//#define IPA_ETH_PARTIAL_HDR_OFFSET 8 // dst mac first then src mac
+#define IPA_ODU_PARTIAL_HDR_OFFSET 8 // dst mac first then src mac
#define IPA_WLAN_PARTIAL_HDR_NAME_v4 "IEEE802_3_v4"
#define IPA_WLAN_PARTIAL_HDR_NAME_v6 "IEEE802_3_v6"
#define IPA_WAN_PARTIAL_HDR_NAME_v4 "IEEE802_3_STA_v4"
#define IPA_WAN_PARTIAL_HDR_NAME_v6 "IEEE802_3_STA_v6"
#define IPA_ETH_HDR_NAME_v4 "IPACM_ETH_v4"
#define IPA_ETH_HDR_NAME_v6 "IPACM_ETH_v6"
+#define IPA_ODU_HDR_NAME_v4 "IPACM_ODU_v4"
+#define IPA_ODU_HDR_NAME_v6 "IPACM_ODU_v6"
+
#define IPA_MAX_IFACE_ENTRIES 15
#define IPA_MAX_PRIVATE_SUBNET_ENTRIES 3
@@ -78,6 +82,8 @@
#define V6_WAN_ROUTE_TABLE_NAME "WANRTBLv6"
#define V4_LAN_TO_LAN_ROUTE_TABLE_NAME "LANTOLANRTBLv4"
#define V6_LAN_TO_LAN_ROUTE_TABLE_NAME "LANTOLANRTBLv6"
+#define V4_ODU_ROUTE_TABLE_NAME "ODURTBLv4"
+#define V6_ODU_ROUTE_TABLE_NAME "ODURTBLv6"
#define WWAN_QMI_IOCTL_DEVICE_NAME "/dev/wwan_ioctl"
#define IPA_DEVICE_NAME "/dev/ipa"
@@ -157,8 +163,9 @@
IPA_USB_LINK_UP_EVENT, /* 38 ipacm_event_data_fid */
IPA_PROCESS_CT_MESSAGE_V6, /* 39 ipacm_ct_evt_data */
IPA_PRIVATE_SUBNET_CHANGE_EVENT, /* 40 ipacm_event_data_fid */
- IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, /* 41 ipacm_event_data_fid */
- IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT, /* 42 ipacm_event_data_fid */
+ IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, /* 41 ipacm_event_data_fid */
+ IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT, /* 42 ipacm_event_data_fid */
+ IPA_WAN_EMBMS_LINK_UP_EVENT, /* 43 ipacm_event_data_mac */
IPACM_EVENT_MAX
} ipa_cm_event_id;
@@ -175,6 +182,8 @@
WAN_IF,
VIRTUAL_IF,
ETH_IF,
+ EMBMS_IF,
+ ODU_IF,
UNKNOWN_IF
} ipacm_iface_type;
diff --git a/ipacm/inc/IPACM_Lan.h b/ipacm/inc/IPACM_Lan.h
index 64ae9e9..32b135c 100644
--- a/ipacm/inc/IPACM_Lan.h
+++ b/ipacm/inc/IPACM_Lan.h
@@ -52,6 +52,7 @@
#define IPA_WAN_DEFAULT_FILTER_RULE_HANDLES 1
#define IPA_PRIV_SUBNET_FILTER_RULE_HANDLES 3
+#define IPA_NUM_ODU_ROUTE_RULES 2
#define MAX_WAN_UL_FILTER_RULES 20
#define NUM_IPV6_PREFIX_FLT_RULE 1
@@ -136,6 +137,10 @@
/* handle new_address event*/
int handle_addr_evt(ipacm_event_data_addr *data);
+ int handle_addr_evt_odu_bridge(ipacm_event_data_addr* data);
+
+ static bool odu_up;
+
/* install UL filter rule from Q6 */
virtual int handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype);
@@ -214,6 +219,18 @@
NatApp *Nat_App;
+ int ipv6_set;
+
+ uint32_t ODU_hdr_hdl_v4, ODU_hdr_hdl_v6;
+
+ uint32_t *odu_route_rule_v4_hdl;
+
+ uint32_t *odu_route_rule_v6_hdl;
+
+ bool ipv4_header_set;
+
+ bool ipv6_header_set;
+
inline ipa_eth_client* get_client_memptr(ipa_eth_client *param, int cnt)
{
char *ret = ((char *)param) + (eth_client_len * cnt);
@@ -326,6 +343,15 @@
/*handle eth client del mode*/
int handle_eth_client_down_evt(uint8_t *mac_addr);
+ /* handle odu client initial, construct full headers (tx property) */
+ int handle_odu_hdr_init(uint8_t *mac_addr);
+
+ /* handle odu default route rule configuration */
+ int handle_odu_route_add();
+
+ /* handle odu default route rule deletion */
+ int handle_odu_route_del();
+
/*handle lan iface down event*/
int handle_down_evt();
diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h
index 7923316..7888791 100644
--- a/ipacm/inc/IPACM_Wan.h
+++ b/ipacm/inc/IPACM_Wan.h
@@ -115,6 +115,8 @@
static bool is_ext_prop_set;
static uint32_t backhaul_ipv6_prefix[2];
+ static bool embms_is_on;
+
private:
uint32_t *wan_route_rule_v4_hdl;
uint32_t *wan_route_rule_v6_hdl;
@@ -126,6 +128,7 @@
uint32_t dft_wan_fl_hdl[IPA_NUM_DEFAULT_WAN_FILTER_RULES];
uint32_t ipv6_dest_flt_rule_hdl[MAX_DEFAULT_v6_ROUTE_RULES];
int num_ipv6_dest_flt_rule;
+ uint32_t ODU_fl_hdl[IPA_NUM_DEFAULT_WAN_FILTER_RULES];
int num_firewall_v4,num_firewall_v6;
uint32_t wan_v4_addr;
bool active_v4;
@@ -274,6 +277,9 @@
int config_dft_firewall_rules(ipa_ip_type iptype);
+ /* configure the initial firewall filter rules */
+ int config_dft_embms_rules(ipa_ioc_add_flt_rule *pFilteringTable_v4, ipa_ioc_add_flt_rule *pFilteringTable_v6);
+
int handle_route_del_evt(ipa_ip_type iptype);
int del_dft_firewall_rules(ipa_ip_type iptype);
diff --git a/ipacm/inc/IPACM_Xml.h b/ipacm/inc/IPACM_Xml.h
index dfeebbb..90e0289 100644
--- a/ipacm/inc/IPACM_Xml.h
+++ b/ipacm/inc/IPACM_Xml.h
@@ -75,6 +75,10 @@
/* IPA Config Entries */
#define system_TAG "system"
+#define ODU_TAG "ODUCFG"
+#define ODUMODE_TAG "Mode"
+#define ODU_ROUTER_TAG "router"
+#define ODU_BRIDGE_TAG "bridge"
#define IPACMCFG_TAG "IPACM"
#define IPACMIFACECFG_TAG "IPACMIface"
#define IFACE_TAG "Iface"
@@ -89,6 +93,8 @@
#define WLANIF_TAG "WLAN"
#define VIRTUALIF_TAG "VIRTUAL"
#define UNKNOWNIF_TAG "UNKNOWN"
+#define ODUIF_TAG "ODU"
+#define EMBMSIF_TAG "EMBMS"
#define ETHIF_TAG "ETH"
#define IPACMALG_TAG "IPACMALG"
#define ALG_TAG "ALG"
@@ -259,6 +265,8 @@
ipacm_private_subnet_conf_t private_subnet_config;
ipacm_alg_conf_t alg_config;
int nat_max_entries;
+ bool odu_enable;
+ bool router_mode_enable;
} IPACM_conf_t;
/* This function read IPACM XML configuration*/
diff --git a/ipacm/src/IPACM_Config.cpp b/ipacm/src/IPACM_Config.cpp
index a934e97..997f64e 100644
--- a/ipacm/src/IPACM_Config.cpp
+++ b/ipacm/src/IPACM_Config.cpp
@@ -45,6 +45,7 @@
IPACM_Config *IPACM_Config::pInstance = NULL;
const char *IPACM_Config::DEVICE_NAME = "/dev/ipa";
+const char *IPACM_Config::DEVICE_NAME_ODU = "/dev/odu_ipa_bridge";
IPACM_Config::IPACM_Config()
{
@@ -52,7 +53,9 @@
alg_table = NULL;
memset(&ipa_client_rm_map_tbl, 0, sizeof(ipa_client_rm_map_tbl));
memset(&ipa_rm_tbl, 0, sizeof(ipa_rm_tbl));
- ipa_rm_a2_check=0;
+ ipa_rm_a2_check=0;
+ ipacm_odu_enable = false;
+ ipacm_odu_router_mode = false;
ipa_num_ipa_interfaces = 0;
ipa_num_private_subnet = 0;
@@ -67,6 +70,8 @@
memset(&rt_tbl_v6, 0, sizeof(rt_tbl_v6));
memset(&rt_tbl_wan_v6, 0, sizeof(rt_tbl_wan_v6));
memset(&rt_tbl_wan_dl, 0, sizeof(rt_tbl_wan_dl));
+ memset(&rt_tbl_odu_v4, 0, sizeof(rt_tbl_odu_v4));
+ memset(&rt_tbl_odu_v6, 0, sizeof(rt_tbl_odu_v6));
memset(&ext_prop_v4, 0, sizeof(ext_prop_v4));
memset(&ext_prop_v6, 0, sizeof(ext_prop_v6));
@@ -194,6 +199,12 @@
ipa_nat_max_entries = cfg->nat_max_entries;
IPACMDBG_H("Nat Maximum Entries %d\n", ipa_nat_max_entries);
+ /* Find ODU is either router mode or bridge mode*/
+ ipacm_odu_enable = cfg->odu_enable;
+ ipacm_odu_router_mode = cfg->router_mode_enable;
+ IPACMDBG_H("ipacm_odu_enable %d\n", ipacm_odu_enable);
+ IPACMDBG_H("ipacm_odu_mode %d\n", ipacm_odu_router_mode);
+
/* Allocate more non-nat entries if the monitored iface dun have Tx/Rx properties */
if (pNatIfaces != NULL)
{
@@ -227,6 +238,12 @@
rt_tbl_wan_v6.ip = IPA_IP_v6;
strncpy(rt_tbl_wan_v6.name, V6_WAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_v6.name));
+ rt_tbl_odu_v4.ip = IPA_IP_v4;
+ strncpy(rt_tbl_odu_v4.name, V4_ODU_ROUTE_TABLE_NAME, sizeof(rt_tbl_odu_v4.name));
+
+ rt_tbl_odu_v6.ip = IPA_IP_v6;
+ strncpy(rt_tbl_odu_v6.name, V6_ODU_ROUTE_TABLE_NAME, sizeof(rt_tbl_odu_v6.name));
+
rt_tbl_wan_dl.ip = IPA_IP_MAX;
strncpy(rt_tbl_wan_dl.name, WAN_DL_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_dl.name));
diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp
index af9811c..d38a58e 100644
--- a/ipacm/src/IPACM_IfaceManager.cpp
+++ b/ipacm/src/IPACM_IfaceManager.cpp
@@ -60,6 +60,7 @@
IPACM_EvtDispatcher::registr(IPA_WLAN_STA_LINK_UP_EVENT, this); // register for wlan STA-iface
#endif /* not defined(FEATURE_IPA_ANDROID)*/
IPACM_EvtDispatcher::registr(IPA_USB_LINK_UP_EVENT, this); // register for wlan STA-iface
+ IPACM_EvtDispatcher::registr(IPA_WAN_EMBMS_LINK_UP_EVENT, this); // register for wan eMBMS-iface
return;
}
@@ -77,10 +78,14 @@
IPACMDBG_H("link up %d: \n", evt_data->if_index);
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
/* LTE-backhaul */
- if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF)
+ 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);
- create_iface_instance(evt_data->if_index, Q6_WAN);
+ create_iface_instance(evt_data->if_index, Q6_WAN);
}
break;
@@ -90,7 +95,7 @@
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);
+ IPACMDBG_H("WAN-usb (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
create_iface_instance(evt_data->if_index, ECM_WAN);
}
else
@@ -104,13 +109,13 @@
/* 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);
- create_iface_instance(evt_data->if_index, Q6_WAN);
+ 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);
+ create_iface_instance(evt_data->if_index, Q6_WAN);
}
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);
+ 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;
@@ -120,13 +125,33 @@
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,evt_data->if_index);
+ 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,evt_data->if_index);
create_iface_instance(evt_data->if_index, WLAN_WAN);
}
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);
+ 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);
+ /* change iface category from unknown to EMBMS_IF */
+ if (IPACM_Iface::ipacmcfg->ipacm_odu_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);
+ create_iface_instance(evt_data->if_index, Q6_WAN);
+ }
+ 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;
@@ -186,9 +211,14 @@
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_LINK_DOWN_EVENT, ETH);
+ 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 */
@@ -196,6 +226,45 @@
}
break;
+ case ODU_IF:
+ {
+ if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true)
+ {
+ IPACMDBG("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_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_LINK_DOWN_EVENT, odu);
+ IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, odu);
+ IPACMDBG("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("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);
+ IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, odu);
+ IPACMDBG("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");
@@ -226,32 +295,46 @@
case WAN_IF:
{
- IPACMDBG_H("Creating Wan interface\n");
- IPACM_Wan *w = new IPACM_Wan(ipa_interface_index, is_sta_mode);
- IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, w);
+ 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 = new IPACM_Wan(ipa_interface_index, is_sta_mode);
+ IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, w);
#ifdef FEATURE_IPA_ANDROID
IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_ADD_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
- if(is_sta_mode == WLAN_WAN)
- {
- IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, w); // for STA mode
+ 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
+ if(is_sta_mode == WLAN_WAN)
+ {
+ IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, w); // for STA mode
+ }
+ 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);
}
- 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);
+ 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;
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 5e1c36a..fc1b4f6 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -50,12 +50,19 @@
#include "linux/ipa_qmi_service_v01.h"
#include "linux/msm_ipa.h"
#include "IPACM_ConntrackListener.h"
+#include <sys/ioctl.h>
+#include <fcntl.h>
+bool IPACM_Lan::odu_up = false;
IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index)
{
num_eth_client = 0;
header_name_count = 0;
+ ipv6_set = 0;
+ ipv4_header_set = false;
+ ipv6_header_set = false;
+ int m_fd_odu, ret = IPACM_SUCCESS;
Nat_App = NatApp::GetInstance();
if (Nat_App == NULL)
@@ -102,6 +109,44 @@
if_ipv4_subnet =0;
memset(private_fl_rule_hdl, 0, IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(uint32_t));
memset(ipv6_prefix_flt_rule_hdl, 0, NUM_IPV6_PREFIX_FLT_RULE * sizeof(uint32_t));
+
+ /* ODU routing table initilization */
+ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF)
+ {
+ odu_route_rule_v4_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t));
+ odu_route_rule_v6_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t));
+
+ /* only do one time ioctl to odu-driver to infrom in router or bridge mode*/
+ if (IPACM_Lan::odu_up != true)
+ {
+ m_fd_odu = open(IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU, O_RDWR);
+ if (0 == m_fd_odu)
+ {
+ IPACMERR("Failed opening %s.\n", IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU);
+ return ;
+ }
+
+ if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true)
+ {
+ ret = ioctl(m_fd_odu, ODU_BRIDGE_IOC_SET_MODE, ODU_BRIDGE_MODE_ROUTER);
+ IPACM_Iface::ipacmcfg->ipacm_odu_enable = true;
+ }
+ else
+ {
+ ret = ioctl(m_fd_odu, ODU_BRIDGE_IOC_SET_MODE, ODU_BRIDGE_MODE_BRIDGE);
+ IPACM_Iface::ipacmcfg->ipacm_odu_enable = true;
+ }
+
+ if (ret)
+ {
+ IPACMERR("Failed tell odu-driver the mode\n");
+ }
+ IPACMDBG("Tell odu-driver in router-mode(%d)\n", IPACM_Iface::ipacmcfg->ipacm_odu_router_mode);
+ close(m_fd_odu);
+ IPACM_Lan::odu_up = true;
+ }
+ }
+
return;
}
@@ -231,14 +276,13 @@
{
IPACMDBG_H("Received IPA_ADDR_ADD_EVENT\n");
- /* check v4 not setup before, v6 can have 2 iface ip */
- if( ((data->iptype != ip_type) && (ip_type != IPA_IP_MAX))
- || ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES)))
+ /* only call ioctl for ODU iface with bridge mode */
+ if((IPACM_Iface::ipacmcfg->ipacm_odu_enable == true) && (IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false)
+ && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF))
{
- IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6);
- if(handle_addr_evt(data) == IPACM_FAILURE)
+ if((data->iptype == IPA_IP_v6) && (num_dft_rt_v6 == 0))
{
- return;
+ handle_addr_evt_odu_bridge(data);
}
#ifdef FEATURE_IPA_ANDROID
add_dummy_private_subnet_flt_rule(data->iptype);
@@ -246,67 +290,84 @@
#else
handle_private_subnet(data->iptype);
#endif
+ }
+ else
+ {
- if (IPACM_Wan::isWanUP())
+ /* check v4 not setup before, v6 can have 2 iface ip */
+ if( ((data->iptype != ip_type) && (ip_type != IPA_IP_MAX))
+ || ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES)))
{
- if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX)
+ IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6);
+ if(handle_addr_evt(data) == IPACM_FAILURE)
{
- if(IPACM_Wan::backhaul_is_sta_mode == false)
- {
- ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
- handle_wan_up_ex(ext_prop, IPA_IP_v4);
- }
- else
- {
- handle_wan_up(IPA_IP_v4);
- }
- }
- }
-
- if(IPACM_Wan::isWanUP_V6())
- {
- if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1)
- {
- install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
- if(IPACM_Wan::backhaul_is_sta_mode == false)
- {
- ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
- handle_wan_up_ex(ext_prop, IPA_IP_v6);
- }
- else
- {
- handle_wan_up(IPA_IP_v6);
- }
- }
- }
-
- /* Post event to NAT */
- if (data->iptype == IPA_IP_v4)
- {
- ipacm_cmd_q_data evt_data;
- ipacm_event_iface_up *info;
-
- info = (ipacm_event_iface_up *)
- malloc(sizeof(ipacm_event_iface_up));
- if (info == NULL)
- {
- IPACMERR("Unable to allocate memory\n");
return;
}
+ handle_private_subnet(data->iptype);
- memcpy(info->ifname, dev_name, IF_NAME_LEN);
- info->ipv4_addr = data->ipv4_addr;
- info->addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[0].subnet_mask;
+ if (IPACM_Wan::isWanUP())
+ {
+ if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX)
+ {
+ if(IPACM_Wan::backhaul_is_sta_mode == false)
+ {
+ ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
+ handle_wan_up_ex(ext_prop, IPA_IP_v4);
+ }
+ else
+ {
+ handle_wan_up(IPA_IP_v4);
+ }
+ }
+ }
- evt_data.event = IPA_HANDLE_LAN_UP;
- evt_data.evt_data = (void *)info;
+ if(IPACM_Wan::isWanUP_V6())
+ {
+ if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1)
+ {
+ install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
+ if(IPACM_Wan::backhaul_is_sta_mode == false)
+ {
+ ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
+ handle_wan_up_ex(ext_prop, IPA_IP_v6);
+ }
+ else
+ {
+ handle_wan_up(IPA_IP_v6);
+ }
+ }
+ }
- /* Insert IPA_HANDLE_LAN_UP to command queue */
- IPACMDBG_H("posting IPA_HANDLE_LAN_UP for IPv4 with below information\n");
- IPACMDBG_H("IPv4 address:0x%x, IPv4 address mask:0x%x\n",
- info->ipv4_addr, info->addr_mask);
- IPACM_EvtDispatcher::PostEvt(&evt_data);
+ /* Post event to NAT */
+ if (data->iptype == IPA_IP_v4)
+ {
+ ipacm_cmd_q_data evt_data;
+ ipacm_event_iface_up *info;
+
+ info = (ipacm_event_iface_up *)
+ malloc(sizeof(ipacm_event_iface_up));
+ if (info == NULL)
+ {
+ IPACMERR("Unable to allocate memory\n");
+ return;
+ }
+
+ memcpy(info->ifname, dev_name, IF_NAME_LEN);
+ info->ipv4_addr = data->ipv4_addr;
+ info->addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[0].subnet_mask;
+
+ evt_data.event = IPA_HANDLE_LAN_UP;
+ evt_data.evt_data = (void *)info;
+
+ /* Insert IPA_HANDLE_LAN_UP to command queue */
+ IPACMDBG_H("posting IPA_HANDLE_LAN_UP for IPv4 with below information\n");
+ IPACMDBG_H("IPv4 address:0x%x, IPv4 address mask:0x%x\n",
+ info->ipv4_addr, info->addr_mask);
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ }
+ IPACMDBG_H("Finish handling IPA_ADDR_ADD_EVENT for ip-family(%d)\n", data->iptype);
}
+
IPACMDBG_H("Finish handling IPA_ADDR_ADD_EVENT for ip-family(%d)\n", data->iptype);
/* checking if SW-RT_enable */
if (IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true)
@@ -315,6 +376,7 @@
IPACMDBG_H("IPA_SW_ROUTING_ENABLE for iface: %s \n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
handle_software_routing_enable();
}
+
}
}
}
@@ -409,6 +471,25 @@
ipacm_event_data_all *data = (ipacm_event_data_all *)param;
ipa_interface_index = iface_ipa_index_query(data->if_index);
IPACMDBG_H("check iface %s category: %d\n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat);
+
+ if ((ipa_interface_index == ipa_if_num) && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF))
+ {
+ IPACMDBG("ODU iface got v4-ip \n");
+ /* first construc ODU full header */
+ if ((ipv4_header_set == false) && (ipv6_header_set == false))
+ {
+ handle_odu_hdr_init(data->mac_addr);
+ handle_odu_route_add(); /* construct ODU RT tbl*/
+ IPACMDBG("construct ODU header and route rules \n");
+ }
+ /* if ODU in bridge mode, directly return */
+ if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false)
+ {
+ return;
+ }
+
+ }
+
if (ipa_interface_index == ipa_if_num)
{
IPACMDBG_H("ETH iface got client \n");
@@ -1449,6 +1530,10 @@
rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(eth_client, eth_index)->v4_addr;
rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
+ /* Replace the v4 header in ODU interface */
+ if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF)
+ rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v4;
+
if (false == m_routing.AddRoutingRule(rt_rule))
{
IPACMERR("Routing rule addition failed!\n");
@@ -1475,6 +1560,10 @@
IPACM_Iface::ipacmcfg->rt_tbl_v6.name,
sizeof(rt_rule->rt_tbl_name));
+ /* Replace v6 header in ODU interface */
+ if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF)
+ rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v6;
+
/* Support QCMAP LAN traffic feature, send to A5 */
rt_rule_entry->rule.dst = iface_query->excp_pipe;
memset(&rt_rule_entry->rule.attrib, 0, sizeof(rt_rule_entry->rule.attrib));
@@ -1551,6 +1640,325 @@
return IPACM_SUCCESS;
}
+/* handle odu client initial, construct full headers (tx property) */
+int IPACM_Lan::handle_odu_hdr_init(uint8_t *mac_addr)
+{
+ int res = IPACM_SUCCESS, len = 0;
+ struct ipa_ioc_copy_hdr sCopyHeader;
+ struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL;
+ uint32_t cnt;
+
+ IPACMDBG("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+ mac_addr[0], mac_addr[1], mac_addr[2],
+ mac_addr[3], mac_addr[4], mac_addr[5]);
+
+ /* add header to IPA */
+ if(tx_prop != NULL)
+ {
+ len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add));
+ pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len);
+ if (pHeaderDescriptor == NULL)
+ {
+ IPACMERR("calloc failed to allocate pHeaderDescriptor\n");
+ return IPACM_FAILURE;
+ }
+
+ /* copy partial header for v4*/
+ for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
+ {
+ if(tx_prop->tx[cnt].ip==IPA_IP_v4)
+ {
+ IPACMDBG("Got partial v4-header name from %d tx props\n", cnt);
+ memset(&sCopyHeader, 0, sizeof(sCopyHeader));
+ memcpy(sCopyHeader.name,
+ tx_prop->tx[cnt].hdr_name,
+ sizeof(sCopyHeader.name));
+ IPACMDBG("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
+ if (m_header.CopyHeader(&sCopyHeader) == false)
+ {
+ PERROR("ioctl copy header failed");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ IPACMDBG("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
+ if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
+ {
+ IPACMERR("header oversize\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else
+ {
+ memcpy(pHeaderDescriptor->hdr[0].hdr,
+ sCopyHeader.hdr,
+ sCopyHeader.hdr_len);
+ }
+ /* copy client mac_addr to partial header */
+ if (sCopyHeader.is_eth2_ofst_valid)
+ {
+ memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
+ mac_addr,
+ IPA_MAC_ADDR_SIZE);
+ }
+
+
+ pHeaderDescriptor->commit = true;
+ pHeaderDescriptor->num_hdrs = 1;
+
+ memset(pHeaderDescriptor->hdr[0].name, 0,
+ sizeof(pHeaderDescriptor->hdr[0].name));
+
+ strncat(pHeaderDescriptor->hdr[0].name,
+ IPA_ODU_HDR_NAME_v4,
+ sizeof(IPA_ODU_HDR_NAME_v4));
+
+ pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
+ pHeaderDescriptor->hdr[0].hdr_hdl = -1;
+ pHeaderDescriptor->hdr[0].is_partial = 0;
+ pHeaderDescriptor->hdr[0].status = -1;
+
+ if (m_header.AddHeader(pHeaderDescriptor) == false ||
+ pHeaderDescriptor->hdr[0].status != 0)
+ {
+ IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ ODU_hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl;
+ ipv4_header_set = true ;
+ IPACMDBG(" ODU v4 full header name:%s header handle:(0x%x)\n",
+ pHeaderDescriptor->hdr[0].name,
+ ODU_hdr_hdl_v4);
+ break;
+ }
+ }
+
+
+ /* copy partial header for v6*/
+ for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
+ {
+ if(tx_prop->tx[cnt].ip==IPA_IP_v6)
+ {
+
+ IPACMDBG("Got partial v6-header name from %d tx props\n", cnt);
+ memset(&sCopyHeader, 0, sizeof(sCopyHeader));
+ memcpy(sCopyHeader.name,
+ tx_prop->tx[cnt].hdr_name,
+ sizeof(sCopyHeader.name));
+
+ IPACMDBG("header name: %s in tx:%d\n", sCopyHeader.name,cnt);
+ if (m_header.CopyHeader(&sCopyHeader) == false)
+ {
+ PERROR("ioctl copy header failed");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ IPACMDBG("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
+ if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE)
+ {
+ IPACMERR("header oversize\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else
+ {
+ memcpy(pHeaderDescriptor->hdr[0].hdr,
+ sCopyHeader.hdr,
+ sCopyHeader.hdr_len);
+ }
+
+ /* copy client mac_addr to partial header */
+ if (sCopyHeader.is_eth2_ofst_valid)
+ {
+ memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst],
+ mac_addr,
+ IPA_MAC_ADDR_SIZE);
+ }
+
+ pHeaderDescriptor->commit = true;
+ pHeaderDescriptor->num_hdrs = 1;
+
+ memset(pHeaderDescriptor->hdr[0].name, 0,
+ sizeof(pHeaderDescriptor->hdr[0].name));
+
+ strncat(pHeaderDescriptor->hdr[0].name,
+ IPA_ODU_HDR_NAME_v6,
+ sizeof(IPA_ODU_HDR_NAME_v6));
+
+ pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len;
+ pHeaderDescriptor->hdr[0].hdr_hdl = -1;
+ pHeaderDescriptor->hdr[0].is_partial = 0;
+ pHeaderDescriptor->hdr[0].status = -1;
+
+ if (m_header.AddHeader(pHeaderDescriptor) == false ||
+ pHeaderDescriptor->hdr[0].status != 0)
+ {
+ IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status);
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ ODU_hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl;
+ ipv6_header_set = true ;
+ IPACMDBG(" ODU v4 full header name:%s header handle:(0x%x)\n",
+ pHeaderDescriptor->hdr[0].name,
+ ODU_hdr_hdl_v6);
+ break;
+ }
+ }
+ }
+fail:
+ free(pHeaderDescriptor);
+
+ return res;
+}
+
+
+/* handle odu default route rule configuration */
+int IPACM_Lan::handle_odu_route_add()
+{
+ /* add default WAN route */
+ struct ipa_ioc_add_rt_rule *rt_rule;
+ struct ipa_rt_rule_add *rt_rule_entry;
+ uint32_t tx_index;
+ const int NUM = 1;
+
+ if(tx_prop == NULL)
+ {
+ IPACMDBG("No tx properties, ignore default route setting\n");
+ return IPACM_SUCCESS;
+ }
+
+ rt_rule = (struct ipa_ioc_add_rt_rule *)
+ calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
+ NUM * sizeof(struct ipa_rt_rule_add));
+
+ if (!rt_rule)
+ {
+ IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
+ return IPACM_FAILURE;
+ }
+
+ rt_rule->commit = 1;
+ rt_rule->num_rules = (uint8_t)NUM;
+
+
+ IPACMDBG(" WAN table created %s \n", rt_rule->rt_tbl_name);
+ rt_rule_entry = &rt_rule->rules[0];
+ rt_rule_entry->at_rear = true;
+
+ for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
+ {
+
+ if (IPA_IP_v4 == tx_prop->tx[tx_index].ip)
+ {
+ strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name);
+ rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v4;
+ rt_rule->ip = IPA_IP_v4;
+ }
+ else
+ {
+ strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name);
+ rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v6;
+ rt_rule->ip = IPA_IP_v6;
+ }
+
+ rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
+ memcpy(&rt_rule_entry->rule.attrib,
+ &tx_prop->tx[tx_index].attrib,
+ sizeof(rt_rule_entry->rule.attrib));
+
+ rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
+ if (IPA_IP_v4 == tx_prop->tx[tx_index].ip)
+ {
+ rt_rule_entry->rule.attrib.u.v4.dst_addr = 0;
+ rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0;
+
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ free(rt_rule);
+ return IPACM_FAILURE;
+ }
+ odu_route_rule_v4_hdl[tx_index] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG("Got ipv4 ODU-route rule hdl:0x%x,tx:%d,ip-type: %d \n",
+ odu_route_rule_v4_hdl[tx_index],
+ tx_index,
+ IPA_IP_v4);
+ }
+ else
+ {
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = 0;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0;
+
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ free(rt_rule);
+ return IPACM_FAILURE;
+ }
+ odu_route_rule_v6_hdl[tx_index] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG("Set ipv6 ODU-route rule hdl for v6_lan_table:0x%x,tx:%d,ip-type: %d \n",
+ odu_route_rule_v6_hdl[tx_index],
+ tx_index,
+ IPA_IP_v6);
+ }
+
+ }
+ free(rt_rule);
+ return IPACM_SUCCESS;
+}
+
+/* handle odu default route rule deletion */
+int IPACM_Lan::handle_odu_route_del()
+{
+ uint32_t tx_index;
+
+ if(tx_prop == NULL)
+ {
+ IPACMDBG("No tx properties, ignore delete default route setting\n");
+ return IPACM_SUCCESS;
+ }
+
+ for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
+ {
+ if (tx_prop->tx[tx_index].ip == IPA_IP_v4)
+ {
+ IPACMDBG("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n",
+ tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v4);
+
+ if (m_routing.DeleteRoutingHdl(odu_route_rule_v4_hdl[tx_index], IPA_IP_v4)
+ == false)
+ {
+ IPACMDBG("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v4, odu_route_rule_v4_hdl[tx_index], tx_index);
+ return IPACM_FAILURE;
+ }
+ }
+ else
+ {
+ IPACMDBG("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n",
+ tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v6);
+
+ if (m_routing.DeleteRoutingHdl(odu_route_rule_v6_hdl[tx_index], IPA_IP_v6)
+ == false)
+ {
+ IPACMDBG("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v6, odu_route_rule_v6_hdl[tx_index], tx_index);
+ return IPACM_FAILURE;
+ }
+ }
+ }
+
+ return IPACM_SUCCESS;
+}
+
/*handle eth client del mode*/
int IPACM_Lan::handle_eth_client_down_evt(uint8_t *mac_addr)
{
@@ -1677,6 +2085,37 @@
int i;
int res = IPACM_SUCCESS;
+ if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF)
+ {
+ /* delete ODU default RT rules */
+ handle_odu_route_del();
+
+ /* delete full header */
+ if (ipv4_header_set)
+ {
+ if (m_header.DeleteHeaderHdl(ODU_hdr_hdl_v4)
+ == false)
+ {
+ IPACMDBG("ODU ipv4 header delete fail\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ IPACMDBG("ODU ipv4 header delete success\n");
+ }
+
+ if (ipv6_header_set)
+ {
+ if (m_header.DeleteHeaderHdl(ODU_hdr_hdl_v6)
+ == false)
+ {
+ IPACMDBG("ODU ipv6 header delete fail\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ IPACMDBG("ODU ipv6 header delete success\n");
+ }
+ }
+
/* no iface address up, directly close iface*/
if (ip_type == IPACM_IP_NULL)
{
@@ -1889,6 +2328,14 @@
}
#endif /* defined(FEATURE_IPA_ANDROID)*/
fail:
+ if (odu_route_rule_v4_hdl != NULL)
+ {
+ free(odu_route_rule_v4_hdl);
+ }
+ if (odu_route_rule_v6_hdl != NULL)
+ {
+ free(odu_route_rule_v6_hdl);
+ }
/* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
if (rx_prop != NULL)
{
@@ -3603,3 +4050,35 @@
return IPACM_SUCCESS;
}
+int IPACM_Lan::handle_addr_evt_odu_bridge(ipacm_event_data_addr* data)
+{
+ int fd, res = IPACM_SUCCESS;
+ struct in6_addr ipv6_addr;
+ if(data == NULL)
+ {
+ IPACMERR("Failed to get interface IP address.\n");
+ return IPACM_FAILURE;
+ }
+
+ if(data->iptype == IPA_IP_v6)
+ {
+ fd = open(IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU, O_RDWR);
+ if(fd == 0)
+ {
+ IPACMERR("Failed to open %s.\n", IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU);
+ return IPACM_FAILURE;
+ }
+
+ memcpy(&ipv6_addr, data->ipv6_addr, sizeof(struct in6_addr));
+
+ if( ioctl(fd, ODU_BRIDGE_IOC_SET_LLV6_ADDR, &ipv6_addr) )
+ {
+ IPACMERR("Failed to write IPv6 address to odu driver.\n");
+ res = IPACM_FAILURE;
+ }
+ num_dft_rt_v6++;
+ close(fd);
+ }
+
+ return res;
+}
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index 201334e..9341ec7 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -571,6 +571,21 @@
break;
/* End of adding for 8994 Android case */
+ /* Add for embms case */
+ case WAN_EMBMS_CONNECT:
+ memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
+ IPACMDBG("Received WAN_EMBMS_CONNECT name: %s\n",event_wan.upstream_ifname);
+ data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
+ if(data_fid == NULL)
+ {
+ IPACMERR("unable to allocate memory for event data_fid\n");
+ return NULL;
+ }
+ ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
+ evt_data.event = IPA_WAN_EMBMS_LINK_UP_EVENT;
+ evt_data.evt_data = data_fid;
+ break;
+
default:
IPACMDBG_H("Unhandled message type: %d\n", event_hdr.msg_type);
continue;
diff --git a/ipacm/src/IPACM_Netlink.cpp b/ipacm/src/IPACM_Netlink.cpp
index a82a904..9db578c 100644
--- a/ipacm/src/IPACM_Netlink.cpp
+++ b/ipacm/src/IPACM_Netlink.cpp
@@ -680,10 +680,8 @@
IPACMDBG_H("Posting IPA_LINK_DOWN_EVENT with if index: %d\n",
data_fid->if_index);
}
-
evt_data.evt_data = data_fid;
IPACM_EvtDispatcher::PostEvt(&evt_data);
-
}
/* Add IPACM support for ECM plug-in/plug_out */
@@ -746,8 +744,8 @@
IPACM_EvtDispatcher::PostEvt(&evt_data);
IPACMDBG_H("Posting usb IPA_LINK_DOWN_EVENT with if index: %d\n",
data_fid->if_index);
- }
+ }
}
break;
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index 1791cee..c410702 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -65,6 +65,8 @@
int IPACM_Wan::num_ipv4_modem_pdn = 0;
int IPACM_Wan::num_ipv6_modem_pdn = 0;
+bool IPACM_Wan::embms_is_on = false;
+
uint32_t IPACM_Wan::backhaul_ipv6_prefix[2];
IPACM_Wan::IPACM_Wan(int iface_index, ipacm_wan_iface_type is_sta_mode) : IPACM_Iface(iface_index)
@@ -126,6 +128,20 @@
{
IPACMERR("Failed to open %s\n",IPA_DEVICE_NAME);
}
+
+ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == EMBMS_IF)
+ {
+ IPACMDBG(" IPACM->IPACM_Wan_eMBMS(%d) constructor: Tx:%d\n", ipa_if_num, iface_query->num_tx_props);
+ embms_is_on = true;
+ install_wan_filtering_rule(false);
+ /* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
+ IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
+ }
+ else
+ {
+ IPACMDBG(" IPACM->IPACM_Wan(%d) constructor: Tx:%d\n", ipa_if_num, iface_query->num_tx_props);
+ }
+
return;
}
@@ -3407,6 +3423,126 @@
return IPACM_SUCCESS;
}
+/* configure the initial embms filter rules */
+int IPACM_Wan::config_dft_embms_rules(ipa_ioc_add_flt_rule *pFilteringTable_v4, ipa_ioc_add_flt_rule *pFilteringTable_v6)
+{
+ struct ipa_flt_rule_add flt_rule_entry;
+ struct ipa_ioc_get_rt_tbl_indx rt_tbl_idx;
+ struct ipa_ioc_generate_flt_eq flt_eq;
+
+ if (rx_prop == NULL)
+ {
+ IPACMDBG("No rx properties registered for iface %s\n", dev_name);
+ return IPACM_SUCCESS;
+ }
+
+ if(pFilteringTable_v4 == NULL || pFilteringTable_v6 == NULL)
+ {
+ IPACMERR("Either v4 or v6 filtering table is empty.\n");
+ return IPACM_FAILURE;
+ }
+
+ /* set up ipv4 odu rule*/
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
+
+ /* get eMBMS ODU tbl index*/
+ memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
+ strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name, IPA_RESOURCE_NAME_MAX);
+ rt_tbl_idx.ip = IPA_IP_v4;
+ if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx))
+ {
+ IPACMERR("Failed to get routing table index from name\n");
+ return IPACM_FAILURE;
+ }
+ IPACMDBG_H("Odu routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx);
+
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
+ flt_rule_entry.flt_rule_hdl = -1;
+ flt_rule_entry.status = -1;
+ flt_rule_entry.at_rear = false;
+
+ flt_rule_entry.rule.retain_hdr = 0;
+ flt_rule_entry.rule.to_uc = 0;
+ flt_rule_entry.rule.eq_attrib_type = 1;
+ flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
+ flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
+
+ memcpy(&flt_rule_entry.rule.attrib,
+ &rx_prop->rx[0].attrib,
+ sizeof(struct ipa_rule_attrib));
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
+ flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000;
+ flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000;
+
+ memset(&flt_eq, 0, sizeof(flt_eq));
+ memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
+ flt_eq.ip = IPA_IP_v4;
+ if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
+ {
+ IPACMERR("Failed to get eq_attrib\n");
+ return IPACM_FAILURE;
+ }
+ memcpy(&flt_rule_entry.rule.eq_attrib,
+ &flt_eq.eq_attrib,
+ sizeof(flt_rule_entry.rule.eq_attrib));
+
+ memcpy(&(pFilteringTable_v4->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+
+ /* construc v6 rule */
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
+ /* get eMBMS ODU tbl*/
+ memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
+ strncpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name, IPA_RESOURCE_NAME_MAX);
+ rt_tbl_idx.ip = IPA_IP_v6;
+ if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx))
+ {
+ IPACMERR("Failed to get routing table index from name\n");
+ return IPACM_FAILURE;
+ }
+ IPACMDBG_H("Odu routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx);
+
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
+ flt_rule_entry.flt_rule_hdl = -1;
+ flt_rule_entry.status = -1;
+ flt_rule_entry.at_rear = false;
+
+ flt_rule_entry.rule.retain_hdr = 0;
+ flt_rule_entry.rule.to_uc = 0;
+ flt_rule_entry.rule.eq_attrib_type = 1;
+ flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
+ flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
+
+ memcpy(&flt_rule_entry.rule.attrib,
+ &rx_prop->rx[0].attrib,
+ sizeof(struct ipa_rule_attrib));
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
+ flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000;
+ flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
+ flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
+ flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
+ flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000;
+ flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
+ flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
+ flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
+
+ memset(&flt_eq, 0, sizeof(flt_eq));
+ memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
+ flt_eq.ip = IPA_IP_v6;
+ if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
+ {
+ IPACMERR("Failed to get eq_attrib\n");
+ return IPACM_FAILURE;
+ }
+ memcpy(&flt_rule_entry.rule.eq_attrib,
+ &flt_eq.eq_attrib,
+ sizeof(flt_rule_entry.rule.eq_attrib));
+
+ memcpy(&(pFilteringTable_v6->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+
+ return IPACM_SUCCESS;
+}
+
+
/*for STA mode: handle wan-iface down event */
int IPACM_Wan::handle_down_evt()
{
@@ -3634,6 +3770,21 @@
goto fail;
}
+ /* free ODU filter rule handlers */
+ if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == EMBMS_IF)
+ {
+ embms_is_on = false;
+ /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */
+ IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
+
+ if (rx_prop != NULL)
+ {
+ install_wan_filtering_rule(false);
+ IPACMDBG("finished delete embms filtering rule\n ");
+ }
+ goto fail;
+ }
+
if(ip_type == IPA_IP_v4)
{
num_ipv4_modem_pdn--;
@@ -3956,13 +4107,57 @@
}
else
{
- if(IPACM_Wan::num_v4_flt_rule > 0)
+ if(embms_is_on == false)
{
- len = sizeof(struct ipa_ioc_add_flt_rule) + IPACM_Wan::num_v4_flt_rule * sizeof(struct ipa_flt_rule_add);
+ if(IPACM_Wan::num_v4_flt_rule > 0)
+ {
+ len = sizeof(struct ipa_ioc_add_flt_rule) + IPACM_Wan::num_v4_flt_rule * sizeof(struct ipa_flt_rule_add);
+ pFilteringTable_v4 = (struct ipa_ioc_add_flt_rule*)malloc(len);
+
+ IPACMDBG_H("Total number of WAN DL filtering rule for IPv4 is %d\n", IPACM_Wan::num_v4_flt_rule);
+
+ if (pFilteringTable_v4 == NULL)
+ {
+ IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
+ return IPACM_FAILURE;
+ }
+ pFilteringTable_v4->commit = 1;
+ pFilteringTable_v4->ep = rx_prop->rx[0].src_pipe;
+ pFilteringTable_v4->global = false;
+ pFilteringTable_v4->ip = IPA_IP_v4;
+ pFilteringTable_v4->num_rules = (uint8_t)IPACM_Wan::num_v4_flt_rule;
+
+ memcpy(pFilteringTable_v4->rules, IPACM_Wan::flt_rule_v4, IPACM_Wan::num_v4_flt_rule * sizeof(ipa_flt_rule_add));
+ }
+
+ if(IPACM_Wan::num_v6_flt_rule > 0)
+ {
+ len = sizeof(struct ipa_ioc_add_flt_rule) + IPACM_Wan::num_v6_flt_rule * sizeof(struct ipa_flt_rule_add);
+ pFilteringTable_v6 = (struct ipa_ioc_add_flt_rule*)malloc(len);
+
+ IPACMDBG_H("Total number of WAN DL filtering rule for IPv6 is %d\n", IPACM_Wan::num_v6_flt_rule);
+
+ if (pFilteringTable_v6 == NULL)
+ {
+ IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
+ free(pFilteringTable_v4);
+ return IPACM_FAILURE;
+ }
+ pFilteringTable_v6->commit = 1;
+ pFilteringTable_v6->ep = rx_prop->rx[0].src_pipe;
+ pFilteringTable_v6->global = false;
+ pFilteringTable_v6->ip = IPA_IP_v6;
+ pFilteringTable_v6->num_rules = (uint8_t)IPACM_Wan::num_v6_flt_rule;
+
+ memcpy(pFilteringTable_v6->rules, IPACM_Wan::flt_rule_v6, IPACM_Wan::num_v6_flt_rule * sizeof(ipa_flt_rule_add));
+ }
+ }
+ else //embms is on, always add 1 embms rule on top of WAN DL flt table
+ {
+ /* allocate ipv4 filtering table */
+ len = sizeof(struct ipa_ioc_add_flt_rule) + (1 + IPACM_Wan::num_v4_flt_rule) * sizeof(struct ipa_flt_rule_add);
pFilteringTable_v4 = (struct ipa_ioc_add_flt_rule*)malloc(len);
-
- IPACMDBG_H("Total number of WAN DL filtering rule for IPv4 is %d\n", IPACM_Wan::num_v4_flt_rule);
-
+ IPACMDBG_H("Total number of WAN DL filtering rule for IPv4 is %d\n", IPACM_Wan::num_v4_flt_rule + 1);
if (pFilteringTable_v4 == NULL)
{
IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
@@ -3972,18 +4167,12 @@
pFilteringTable_v4->ep = rx_prop->rx[0].src_pipe;
pFilteringTable_v4->global = false;
pFilteringTable_v4->ip = IPA_IP_v4;
- pFilteringTable_v4->num_rules = (uint8_t)IPACM_Wan::num_v4_flt_rule;
+ pFilteringTable_v4->num_rules = (uint8_t)IPACM_Wan::num_v4_flt_rule + 1;
- memcpy(pFilteringTable_v4->rules, IPACM_Wan::flt_rule_v4, IPACM_Wan::num_v4_flt_rule * sizeof(ipa_flt_rule_add));
- }
-
- if(IPACM_Wan::num_v6_flt_rule > 0)
- {
- len = sizeof(struct ipa_ioc_add_flt_rule) + IPACM_Wan::num_v6_flt_rule * sizeof(struct ipa_flt_rule_add);
+ /* allocate ipv6 filtering table */
+ len = sizeof(struct ipa_ioc_add_flt_rule) + (1 + IPACM_Wan::num_v6_flt_rule) * sizeof(struct ipa_flt_rule_add);
pFilteringTable_v6 = (struct ipa_ioc_add_flt_rule*)malloc(len);
-
- IPACMDBG_H("Total number of WAN DL filtering rule for IPv6 is %d\n", IPACM_Wan::num_v6_flt_rule);
-
+ IPACMDBG_H("Total number of WAN DL filtering rule for IPv6 is %d\n", IPACM_Wan::num_v6_flt_rule + 1);
if (pFilteringTable_v6 == NULL)
{
IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
@@ -3994,9 +4183,18 @@
pFilteringTable_v6->ep = rx_prop->rx[0].src_pipe;
pFilteringTable_v6->global = false;
pFilteringTable_v6->ip = IPA_IP_v6;
- pFilteringTable_v6->num_rules = (uint8_t)IPACM_Wan::num_v6_flt_rule;
+ pFilteringTable_v6->num_rules = (uint8_t)IPACM_Wan::num_v6_flt_rule + 1;
- memcpy(pFilteringTable_v6->rules, IPACM_Wan::flt_rule_v6, IPACM_Wan::num_v6_flt_rule * sizeof(ipa_flt_rule_add));
+ config_dft_embms_rules(pFilteringTable_v4, pFilteringTable_v6);
+ if(IPACM_Wan::num_v4_flt_rule > 0)
+ {
+ memcpy(&(pFilteringTable_v4->rules[1]), IPACM_Wan::flt_rule_v4, IPACM_Wan::num_v4_flt_rule * sizeof(ipa_flt_rule_add));
+ }
+
+ if(IPACM_Wan::num_v6_flt_rule > 0)
+ {
+ memcpy(&(pFilteringTable_v6->rules[1]), IPACM_Wan::flt_rule_v6, IPACM_Wan::num_v6_flt_rule * sizeof(ipa_flt_rule_add));
+ }
}
}
diff --git a/ipacm/src/IPACM_Xml.cpp b/ipacm/src/IPACM_Xml.cpp
index 0a1d156..6ef4cc0 100644
--- a/ipacm/src/IPACM_Xml.cpp
+++ b/ipacm/src/IPACM_Xml.cpp
@@ -169,6 +169,8 @@
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 ||
@@ -210,6 +212,28 @@
config);
}
else if (IPACM_util_icmp_string((char*)xml_node->name,
+ ODUMODE_TAG) == 0)
+ {
+ IPACMDBG("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("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("router-mode enable %d\n", config->router_mode_enable);
+ }
+ }
+ }
+ else if (IPACM_util_icmp_string((char*)xml_node->name,
NAME_TAG) == 0)
{
content = IPACM_read_content_element(xml_node);
@@ -261,6 +285,11 @@
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,
diff --git a/ipacm/src/IPACM_cfg.xml b/ipacm/src/IPACM_cfg.xml
index 7a7de58..95a7796 100644
--- a/ipacm/src/IPACM_cfg.xml
+++ b/ipacm/src/IPACM_cfg.xml
@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<system xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ipacm_cfg.xsd">
+ <ODUCFG>
+ <Mode>router</Mode>
+ </ODUCFG>
<IPACM>
<IPACMIface>
<Iface>
@@ -49,10 +52,10 @@
<Iface>
<Name>wlan1</Name>
<Category>UNKNOWN</Category>
- </Iface>
+ </Iface>
<Iface>
<Name>eth0</Name>
- <Category>ETH</Category>
+ <Category>ODU</Category>
</Iface>
<Iface>
<Name>bridge0</Name>