Merge 75b51b2468e0afbbdabc11715dd856ce20d0fc92 on remote branch
Change-Id: I799d24379341d0b4a380ffb1344f46ee9e87a0ae
diff --git a/ipacm/inc/IPACM_ConntrackListener.h b/ipacm/inc/IPACM_ConntrackListener.h
index 2977af7..217761b 100644
--- a/ipacm/inc/IPACM_ConntrackListener.h
+++ b/ipacm/inc/IPACM_ConntrackListener.h
@@ -103,6 +103,7 @@
void CheckSTAClient(const nat_table_entry *, bool *);
int CheckNatIface(ipacm_event_data_all *, bool *);
void HandleNonNatIPAddr(void *, bool);
+ void HandleNatTableMove(void *in_param);
#ifdef CT_OPT
void ProcessCTV6Message(void *);
diff --git a/ipacm/inc/IPACM_Conntrack_NATApp.h b/ipacm/inc/IPACM_Conntrack_NATApp.h
index 95dcdfe..9490aa6 100644
--- a/ipacm/inc/IPACM_Conntrack_NATApp.h
+++ b/ipacm/inc/IPACM_Conntrack_NATApp.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -119,6 +119,7 @@
int AddTable(uint32_t, uint8_t mux_id);
uint32_t GetTableHdl(uint32_t);
int DeleteTable(uint32_t);
+ int MoveTable(bool to_ddr);
int AddEntry(const nat_table_entry *);
int DeleteEntry(const nat_table_entry *);
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index 20bef93..0d2a257 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -44,6 +44,7 @@
#include <fcntl.h>
#include <linux/msm_ipa.h>
#include "IPACM_Log.h"
+#include "linux/ipa_qmi_service_v01.h"
#ifdef USE_GLIB
#include <glib.h>
@@ -146,7 +147,7 @@
IPA_BRIDGE_LINK_UP_EVENT, /* ipacm_event_data_all */
IPA_WAN_EMBMS_LINK_UP_EVENT, /* ipacm_event_data_mac */
IPA_ADDR_ADD_EVENT, /* ipacm_event_data_addr */
- IPA_ADDR_DEL_EVENT, /* no use */
+ IPA_ADDR_DEL_EVENT, /* ipacm_event_data_addr */
IPA_ROUTE_ADD_EVENT, /* ipacm_event_data_addr */
IPA_ROUTE_DEL_EVENT, /* ipacm_event_data_addr */
IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, /* ipacm_event_data_fid */
@@ -213,6 +214,7 @@
IPA_LAN_DELETE_SELF, /* ipacm_event_data_fid */
IPA_WIGIG_CLIENT_ADD_EVENT, /* ipacm_event_data_mac_ep */
IPA_WIGIG_FST_SWITCH, /* ipacm_event_data_fst */
+ IPA_MOVE_NAT_TBL_EVENT, /* ipacm_event_move_nat */
IPACM_EVENT_MAX
} ipa_cm_event_id;
@@ -394,6 +396,10 @@
uint8_t xlat_mux_id;
}ipacm_event_iface_up_tehter;
+typedef struct
+{
+ ipa_move_nat_type_enum_v01 nat_move_direction;
+}ipacm_event_move_nat;
typedef struct _ipacm_ifacemgr_data
{
diff --git a/ipacm/inc/IPACM_Iface.h b/ipacm/inc/IPACM_Iface.h
index 35d12db..00c410a 100644
--- a/ipacm/inc/IPACM_Iface.h
+++ b/ipacm/inc/IPACM_Iface.h
@@ -103,7 +103,7 @@
uint32_t dft_v6fl_rule_hdl[IPV6_DEFAULT_FILTERTING_RULES + IPV6_DEFAULT_LAN_FILTERTING_RULES];
/* create additional set of v6 RT-rules in Wanv6RT table*/
uint32_t dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+2*MAX_DEFAULT_v6_ROUTE_RULES];
-
+ uint32_t dft_rt_v6_glbl_idx;
ipa_ioc_query_intf *iface_query;
ipa_ioc_query_intf_tx_props *tx_prop;
ipa_ioc_query_intf_rx_props *rx_prop;
diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h
index 77954c7..e72c2be 100644
--- a/ipacm/inc/IPACM_Wan.h
+++ b/ipacm/inc/IPACM_Wan.h
@@ -60,6 +60,7 @@
#else
#define IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6 3
#endif
+#define MAX_DEFAULT_SEC_v6_ROUTE_RULES 1
#define NETWORK_STATS "%s %llu %llu %llu %llu"
#define IPA_NETWORK_STATS_FILE_NAME "/data/misc/ipa/network_stats"
@@ -351,6 +352,8 @@
uint32_t ODU_fl_hdl[IPA_NUM_DEFAULT_WAN_FILTER_RULES];
int num_firewall_v4,num_firewall_v6;
uint32_t wan_v4_addr;
+ uint32_t sec_wan_v4_addr;
+ bool sec_wan_v4_addr_set;
uint32_t wan_v4_addr_gw;
uint32_t wan_v6_addr_gw[4];
bool wan_v4_addr_set;
@@ -364,11 +367,19 @@
bool header_partial_default_wan_v6;
uint8_t ext_router_mac_addr[IPA_MAC_ADDR_SIZE];
uint8_t netdev_mac[IPA_MAC_ADDR_SIZE];
+ /* IPACM interface secondary v6 ip-addresses */
+ uint32_t sec_ipv6_addr[MAX_DEFAULT_SEC_v6_ROUTE_RULES][4];
/* create additional set of v4 Coalesce RT-rules: tcp udp */
uint32_t dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES+ 2*MAX_DEFAULT_v6_ROUTE_RULES];
- /* create additional set of v4 low_lat RT-rules: tcp udp */
+ /* create additional set of v4 Coalesce RT-rules for secondary addresses: tcp udp */
+ uint32_t sec_dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES+ 2*MAX_DEFAULT_SEC_v6_ROUTE_RULES];
+
+ /* create additional set of v4/v6 low_lat RT-rules: tcp udp */
uint32_t dft_low_lat_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+ MAX_DEFAULT_v6_ROUTE_RULES];
+ /* create additional set of v4/v6 low_lat RT-rules for seconday addresses: */
+ uint32_t sec_dft_low_lat_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+ MAX_DEFAULT_SEC_v6_ROUTE_RULES];
+
static int num_ipv4_modem_pdn;
static int num_ipv6_modem_pdn;
@@ -417,6 +428,12 @@
uint16_t mtu_v6;
bool mtu_v6_set;
+ /* IPACM number of default route rules for secondary ipv6 address*/
+ uint32_t sec_num_dft_rt_v6;
+
+ /* create additional set of v6 RT-rules for secondary addresses in Wanv6RT table*/
+ uint32_t sec_dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*MAX_DEFAULT_SEC_v6_ROUTE_RULES];
+
inline ipa_wan_client* get_client_memptr(ipa_wan_client *param, int cnt)
{
char *ret = ((char *)param) + (wan_client_len * cnt);
@@ -605,6 +622,9 @@
/* handle new_address event */
int handle_addr_evt(ipacm_event_data_addr *data);
+ /* handle del_address event */
+ int handle_addr_del_evt(ipacm_event_data_addr *data);
+
/* handle new_address event for q6_mhi */
int handle_addr_evt_mhi_q6(ipacm_event_data_addr *data);
diff --git a/ipacm/src/IPACM_Config.cpp b/ipacm/src/IPACM_Config.cpp
index 369c7d4..41b920d 100644
--- a/ipacm/src/IPACM_Config.cpp
+++ b/ipacm/src/IPACM_Config.cpp
@@ -125,7 +125,8 @@
__stringify(IPA_LAN_DELETE_SELF), /* ipacm_event_data_fid */
__stringify(IPA_WIGIG_CLIENT_ADD_EVENT), /* ipacm_event_data_mac_ep */
__stringify(IPA_WIGIG_FST_SWITCH), /* ipacm_event_data_fst */
- __stringify(IPACM_EVENT_MAX),
+ __stringify(IPA_MOVE_NAT_TBL_EVENT), /* ipacm_event_move_nat */
+ __stringify(IPACM_EVENT_MAX)
};
IPACM_Config::IPACM_Config()
diff --git a/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp
index b991324..f0abb84 100644
--- a/ipacm/src/IPACM_ConntrackListener.cpp
+++ b/ipacm/src/IPACM_ConntrackListener.cpp
@@ -65,6 +65,7 @@
IPACM_EvtDispatcher::registr(IPA_HANDLE_LAN_UP, this);
IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, this);
IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, this);
+ IPACM_EvtDispatcher::registr(IPA_MOVE_NAT_TBL_EVENT, this);
#ifdef CT_OPT
p_lan2lan = IPACM_LanToLan::getLan2LanInstance();
@@ -144,7 +145,10 @@
IPACMDBG("Received IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT event\n");
HandleNonNatIPAddr(data, false);
break;
-
+ case IPA_MOVE_NAT_TBL_EVENT:
+ IPACMDBG_H("Received IPA_MOVE_NAT_TBL_EVENT event\n");
+ HandleNatTableMove(data);
+ break;
default:
IPACMDBG("Ignore cmd %d\n", evt);
break;
@@ -1501,3 +1505,37 @@
IPACMDBG("Exit:\n");
}
+void IPACM_ConntrackListener::HandleNatTableMove(void *in_param)
+{
+ int ret;
+ int fd_wwan_ioctl;
+ ipacm_event_move_nat *data_nat = (ipacm_event_move_nat *)in_param;
+
+ IPACMDBG_H("handling nat table move request\n");
+
+ fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
+ if(fd_wwan_ioctl < 0)
+ {
+ IPACMERR("Failed to open %s.\n", WWAN_QMI_IOCTL_DEVICE_NAME);
+ return;
+ }
+
+ if(data_nat->nat_move_direction == QMI_IPA_MOVE_NAT_TO_DDR_V01) {
+ ret = nat_inst->MoveTable(true);
+ }
+ else {
+ ret = nat_inst->MoveTable(false);
+ }
+
+ IPACMDBG_H("sending indication to Q6 about transition %s\n",
+ ret ? "failure" : "success");
+
+ ret = ioctl(fd_wwan_ioctl, WAN_IOC_NOTIFY_NAT_MOVE_RES, ret);
+ if(ret != 0)
+ {
+ IPACMERR("Failed sending NAT TABLR MOVE indication with ret %d\n ", ret);
+ }
+
+ close(fd_wwan_ioctl);
+}
+
diff --git a/ipacm/src/IPACM_Conntrack_NATApp.cpp b/ipacm/src/IPACM_Conntrack_NATApp.cpp
index 111733a..5b72cba 100644
--- a/ipacm/src/IPACM_Conntrack_NATApp.cpp
+++ b/ipacm/src/IPACM_Conntrack_NATApp.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -318,6 +318,21 @@
return 0;
}
+int NatApp::MoveTable(bool to_ddr)
+{
+ int ret;
+
+ if (to_ddr) {
+ IPACMDBG_H("direction TO_DDR - move and lock table at DDR\n");
+ ret = ipa_nat_switch_to(IPA_NAT_MEM_IN_DDR, true);
+ } else {
+ IPACMDBG_H("direction TO_SRAM - allow table transition to SRAM\n");
+ ret = ipa_nat_switch_to(IPA_NAT_MEM_IN_DDR, false);
+ }
+
+ return ret;
+}
+
/* Check for duplicate entries */
bool NatApp::ChkForDup(const nat_table_entry *rule)
{
diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp
index a2e9b66..0be4695 100644
--- a/ipacm/src/IPACM_IfaceManager.cpp
+++ b/ipacm/src/IPACM_IfaceManager.cpp
@@ -470,6 +470,7 @@
IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT, w);
if(is_sta_mode == Q6_WAN)
{
+ IPACM_EvtDispatcher::registr(IPA_ADDR_DEL_EVENT, w);
IPACM_EvtDispatcher::registr(IPA_NETWORK_STATS_UPDATE_EVENT, w);
#ifdef IPA_MTU_EVENT_MAX
IPACM_EvtDispatcher::registr(IPA_MTU_SET, w);
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index 8166329..2e41389 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -305,6 +305,9 @@
#endif
param = NULL;
+ struct ipa_move_nat_req_msg_v01 *move_nat;
+ ipacm_event_move_nat *move_nat_data;
+
fd = open(IPA_DRIVER, O_RDWR);
if (fd < 0)
{
@@ -945,6 +948,23 @@
break;
#endif
+ case IPA_MOVE_NAT_TABLE:
+ move_nat = (struct ipa_move_nat_req_msg_v01 *)(buffer + sizeof(struct ipa_msg_meta));
+ IPACMDBG_H("received IPA_MOVE_NAT_TABLE direction %s\n",
+ move_nat->nat_move_direction == QMI_IPA_MOVE_NAT_TO_DDR_V01 ? "TO_DDR" : "TO_SRAM");
+ move_nat_data = (ipacm_event_move_nat *)malloc(sizeof(ipacm_event_move_nat));
+ if(move_nat_data == NULL)
+ {
+ IPACMERR("unable to allocate memory for move_nat_tbl_evnt\n");
+ return NULL;
+ }
+
+ move_nat_data->nat_move_direction = move_nat->nat_move_direction;
+
+ evt_data.event = IPA_MOVE_NAT_TBL_EVENT;
+ evt_data.evt_data = move_nat_data;
+ 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 fa4b8b7..a32dd7f 100644
--- a/ipacm/src/IPACM_Netlink.cpp
+++ b/ipacm/src/IPACM_Netlink.cpp
@@ -878,6 +878,71 @@
}
break;
+ case RTM_DELADDR:
+ IPACMDBG("\n GOT RTM_DELADDR event\n");
+ if(IPACM_SUCCESS != ipa_nl_decode_rtm_addr(buffer, buflen, &(msg_ptr->nl_addr_info)))
+ {
+ IPACMERR("Failed to decode rtm addr message\n");
+ return IPACM_FAILURE;
+ }
+ else
+ {
+ ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_addr_info.metainfo.ifa_index);
+ if(ret_val != IPACM_SUCCESS)
+ {
+ IPACMERR("Error while getting interface name\n");
+ }
+ IPACMDBG("Interface %s \n", dev_name);
+
+ data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
+ if(data_addr == NULL)
+ {
+ IPACMERR("unable to allocate memory for event data_addr\n");
+ return IPACM_FAILURE;
+ }
+
+ if(AF_INET6 == msg_ptr->nl_addr_info.attr_info.prefix_addr.ss_family)
+ {
+ data_addr->iptype = IPA_IP_v6;
+ IPACM_NL_REPORT_ADDR( "IFA_ADDRESS:", msg_ptr->nl_addr_info.attr_info.prefix_addr );
+ IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_addr_info.attr_info.prefix_addr);
+ data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]);
+ data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]);
+ data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]);
+ data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]);
+ }
+ else
+ {
+ data_addr->iptype = IPA_IP_v4;
+ IPACM_NL_REPORT_ADDR( "IFA_ADDRESS:", msg_ptr->nl_addr_info.attr_info.prefix_addr );
+ IPACM_EVENT_COPY_ADDR_v4( data_addr->ipv4_addr, msg_ptr->nl_addr_info.attr_info.prefix_addr);
+ data_addr->ipv4_addr = ntohl(data_addr->ipv4_addr);
+
+ }
+
+ evt_data.event = IPA_ADDR_DEL_EVENT;
+ data_addr->if_index = msg_ptr->nl_addr_info.metainfo.ifa_index;
+ strlcpy(data_addr->iface_name, dev_name, sizeof(data_addr->iface_name));
+ if(AF_INET6 == msg_ptr->nl_addr_info.attr_info.prefix_addr.ss_family)
+ {
+ IPACMDBG("Posting IPA_ADDR_DEL_EVENT with if index:%d, ipv6 addr:0x%x:%x:%x:%x\n",
+ data_addr->if_index,
+ data_addr->ipv6_addr[0],
+ data_addr->ipv6_addr[1],
+ data_addr->ipv6_addr[2],
+ data_addr->ipv6_addr[3]);
+ }
+ else
+ {
+ IPACMDBG("Posting IPA_ADDR_DEL_EVENT with if index:%d, ipv4 addr:0x%x\n",
+ data_addr->if_index,
+ data_addr->ipv4_addr);
+ }
+ evt_data.evt_data = data_addr;
+ IPACM_EvtDispatcher::PostEvt(&evt_data);
+ }
+ break;
+
case RTM_NEWROUTE:
if(IPACM_SUCCESS != ipa_nl_decode_rtm_route(buffer, buflen, &(msg_ptr->nl_route_info)))
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index f0aef3c..1e01e5e 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -293,6 +293,7 @@
#ifdef FEATURE_IPACM_HAL
IPACM_OffloadManager* OffloadMng;
#endif
+ bool sec_addr = false;
memset(&hdr, 0, sizeof(hdr));
if(tx_prop == NULL || rx_prop == NULL)
@@ -306,18 +307,50 @@
if (data->iptype == IPA_IP_v6)
{
- for(num_ipv6_addr=0;num_ipv6_addr<num_dft_rt_v6;num_ipv6_addr++)
+ /* Check if Global address changed for WWAN backhaul. */
+ if ((m_is_sta_mode == Q6_WAN) && is_global_ipv6_addr(data->ipv6_addr) &&
+ (data->ipv6_addr[0] || data->ipv6_addr[1]) &&
+ (ipv6_prefix[0] || ipv6_prefix[1]) &&
+ !((ipv6_prefix[0] == data->ipv6_addr[0]) &&
+ (ipv6_prefix[1] == data->ipv6_addr[1])))
{
- if((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) &&
- (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) &&
- (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) &&
- (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3]))
+ sec_addr = true;
+ }
+
+ if (sec_addr)
+ {
+ if (sec_num_dft_rt_v6 == MAX_DEFAULT_SEC_v6_ROUTE_RULES)
{
- IPACMDBG_H("find matched ipv6 address, index:%d \n", num_ipv6_addr);
+ IPACMDBG_H("Secondary v6 addresses overflow:%d \n", sec_num_dft_rt_v6);
return IPACM_SUCCESS;
- break;
+ }
+ for(num_ipv6_addr=0;num_ipv6_addr<sec_num_dft_rt_v6;num_ipv6_addr++)
+ {
+ if((sec_ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) &&
+ (sec_ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) &&
+ (sec_ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) &&
+ (sec_ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3]))
+ {
+ IPACMDBG_H("find matched ipv6 address, index:%d \n", num_ipv6_addr);
+ return IPACM_SUCCESS;
+ }
}
}
+ else
+ {
+ for(num_ipv6_addr=0;num_ipv6_addr<num_dft_rt_v6;num_ipv6_addr++)
+ {
+ if((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) &&
+ (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) &&
+ (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) &&
+ (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3]))
+ {
+ IPACMDBG_H("find matched ipv6 address, index:%d \n", num_ipv6_addr);
+ return IPACM_SUCCESS;
+ }
+ }
+ }
+
rt_rule = (struct ipa_ioc_add_rt_rule *)
calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
NUM_RULES * sizeof(struct ipa_rt_rule_add));
@@ -345,10 +378,21 @@
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
- ipv6_addr[num_dft_rt_v6][0] = data->ipv6_addr[0];
- ipv6_addr[num_dft_rt_v6][1] = data->ipv6_addr[1];
- ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2];
- ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3];
+ if (sec_addr)
+ {
+ sec_ipv6_addr[sec_num_dft_rt_v6][0] = data->ipv6_addr[0];
+ sec_ipv6_addr[sec_num_dft_rt_v6][1] = data->ipv6_addr[1];
+ sec_ipv6_addr[sec_num_dft_rt_v6][2] = data->ipv6_addr[2];
+ sec_ipv6_addr[sec_num_dft_rt_v6][3] = data->ipv6_addr[3];
+ }
+ else
+ {
+ ipv6_addr[num_dft_rt_v6][0] = data->ipv6_addr[0];
+ ipv6_addr[num_dft_rt_v6][1] = data->ipv6_addr[1];
+ ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2];
+ ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3];
+
+ }
if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
rt_rule_entry->rule.hashable = false;
if(m_is_sta_mode == Q6_WAN)
@@ -379,7 +423,10 @@
res = rt_rule_entry->status;
goto fail;
}
- dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
+ if (sec_addr)
+ sec_dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*sec_num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
+ else
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
/* setup same rule for v6_wan table*/
strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
@@ -395,13 +442,24 @@
res = rt_rule_entry->status;
goto fail;
}
+ if (sec_addr)
+ {
+ sec_dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*sec_num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("Secondary ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, entry: %d %d\n",
+ sec_dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*sec_num_dft_rt_v6],
+ sec_dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*sec_num_dft_rt_v6+1],
+ MAX_DEFAULT_v4_ROUTE_RULES + 2*sec_num_dft_rt_v6,
+ MAX_DEFAULT_v4_ROUTE_RULES + 2*sec_num_dft_rt_v6+1);
+ }
+ else
+ {
dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl;
-
IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, entry: %d %d\n",
dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6],
dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],
MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6,
MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1);
+ }
/* RSC TCP rule*/
rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
rt_rule_entry->rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_TCP;
@@ -423,10 +481,20 @@
res = rt_rule_entry->status;
goto fail;
}
+ if (sec_addr)
+ {
+ sec_dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*sec_num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("Secondary ipv6 wan iface rsc tcp rt-rule hdll=0x%x\n enable(%d), entry %d", sec_dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*sec_num_dft_rt_v6],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable,
+ 2*MAX_DEFAULT_v4_ROUTE_RULES + 2*sec_num_dft_rt_v6);
+ }
+ else
+ {
dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
IPACMDBG_H("ipv6 wan iface rsc tcp rt-rule hdll=0x%x\n enable(%d), entry %d", dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6],
IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable,
2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6);
+ }
/* RSB UDP rule*/
rt_rule_entry->rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_UDP;
#ifdef IPA_RT_SUPPORT_COAL
@@ -446,11 +514,21 @@
IPACMERR("rsb udp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
res = rt_rule_entry->status;
goto fail;
- }
+ }
+ if (sec_addr)
+ {
+ sec_dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*sec_num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("Secondary ipv6 wan iface rsb udp rt-rule hdll=0x%x\n enable(%d) entry %d", sec_dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*sec_num_dft_rt_v6+1],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable,
+ 2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1);
+ }
+ else
+ {
dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl;
IPACMDBG_H("ipv6 wan iface rsb udp rt-rule hdll=0x%x\n enable(%d) entry %d", dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],
IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable,
2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1);
+ }
/* Low latency v6 rule*/
fd_wwan_ioctl = open(IPA_DEVICE_NAME, O_RDWR);
@@ -481,9 +559,20 @@
res = rt_rule_entry->status;
goto fail;
}
+
+ if (sec_addr)
+ {
+ sec_dft_low_lat_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("secondary ipv6 wan iface low lat udp rt-rule hdll=0x%x\n entry %d", sec_dft_low_lat_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES],
+ MAX_DEFAULT_v4_ROUTE_RULES + sec_num_dft_rt_v6);
+ }
+ else
+ {
dft_low_lat_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
IPACMDBG_H("ipv6 wan iface low lat udp rt-rule hdll=0x%x\n entry %d", dft_low_lat_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + num_dft_rt_v6],
MAX_DEFAULT_v4_ROUTE_RULES + num_dft_rt_v6);
+ }
+
}
}
else
@@ -528,7 +617,7 @@
}
/* add default filtering rules when wan-iface get global v6-prefix */
- if (num_dft_rt_v6 == 1)
+ if (!sec_addr && num_dft_rt_v6 == 1)
{
if(m_is_sta_mode == Q6_WAN)
{
@@ -619,12 +708,21 @@
}
}
}
- /* store ipv6 prefix if the ipv6 address is not link local */
- if(is_global_ipv6_addr(data->ipv6_addr))
+
+ if (sec_addr)
{
- memcpy(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix));
+ sec_num_dft_rt_v6++;
}
- num_dft_rt_v6++;
+ else
+ {
+ /* store ipv6 prefix if the ipv6 address is not link local */
+ if (is_global_ipv6_addr(data->ipv6_addr))
+ {
+ memcpy(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix));
+ dft_rt_v6_glbl_idx = num_dft_rt_v6;
+ }
+ num_dft_rt_v6++;
+ }
}
else
{
@@ -639,28 +737,19 @@
else
{
IPACMDBG_H(" device (%s) ipv4 addr is changed\n", dev_name);
- /* Delete default Coalese v4 RT rule */
if (m_is_sta_mode == Q6_WAN) {
- if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[0], IPA_IP_v4) == false)
- {
- IPACMERR("Routing old RSC TCP RT rule deletion failed!\n");
- res = IPACM_FAILURE;
- goto fail;
- }
- if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[1], IPA_IP_v4) == false)
- {
- IPACMERR("Routing old RSB UDP RT rule deletion failed!\n");
- res = IPACM_FAILURE;
- goto fail;
- }
+ sec_addr = true;
}
- /* Delete default v4 RT rule */
- IPACMDBG_H("Delete default v4 routing rules\n");
- if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
+ else
{
- IPACMERR("Routing old RT rule deletion failed!\n");
- res = IPACM_FAILURE;
- goto fail;
+ /* Delete default v4 RT rule */
+ IPACMDBG_H("Delete default v4 routing rules\n");
+ if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing old RT rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
}
}
}
@@ -716,9 +805,18 @@
IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
res = rt_rule_entry->status;
goto fail;
- }
- dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
- IPACMDBG_H("ipv4 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[0]);
+ }
+ if (sec_addr)
+ {
+ sec_dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("Secondary ipv4 wan iface rt-rule hdll=0x%x\n",
+ sec_dft_rt_rule_hdl[0]);
+ }
+ else
+ {
+ dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv4 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[0]);
+ }
/* RSC TCP rule*/
rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
rt_rule_entry->rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_TCP;
@@ -740,10 +838,19 @@
IPACMERR("rsc tcp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
res = rt_rule_entry->status;
goto fail;
- }
- dft_coalesce_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
- IPACMDBG_H("ipv4 wan iface rsc tcp rt-rule hdll=0x%x\n enable(%d)", dft_coalesce_rt_rule_hdl[0],
- IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable);
+ }
+ if (sec_addr)
+ {
+ sec_dft_coalesce_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("Secondary ipv4 wan iface rsc tcp rt-rule hdll=0x%x\n enable(%d)", sec_dft_coalesce_rt_rule_hdl[0],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable);
+ }
+ else
+ {
+ dft_coalesce_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv4 wan iface rsc tcp rt-rule hdll=0x%x\n enable(%d)", dft_coalesce_rt_rule_hdl[0],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable);
+ }
/* RSB UDP rule*/
rt_rule_entry->rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_UDP;
@@ -765,9 +872,18 @@
res = rt_rule_entry->status;
goto fail;
}
- dft_coalesce_rt_rule_hdl[1] = rt_rule_entry->rt_rule_hdl;
- IPACMDBG_H("ipv4 wan iface rsb udp rt-rule hdll=0x%x\n enable(%d)", dft_coalesce_rt_rule_hdl[1],
- IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable);
+ if (sec_addr)
+ {
+ sec_dft_coalesce_rt_rule_hdl[1] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("Secondary ipv4 wan iface rsb udp rt-rule hdll=0x%x\n enable(%d)", sec_dft_coalesce_rt_rule_hdl[1],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable);
+ }
+ else
+ {
+ dft_coalesce_rt_rule_hdl[1] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv4 wan iface rsb udp rt-rule hdll=0x%x\n enable(%d)", dft_coalesce_rt_rule_hdl[1],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable);
+ }
/* low latency v4 rule*/
fd_wwan_ioctl = open(IPA_DEVICE_NAME, O_RDWR);
@@ -798,9 +914,17 @@
res = rt_rule_entry->status;
goto fail;
}
+ if (sec_addr)
+ {
+ sec_dft_low_lat_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("secondary ipv4 low lat udp rt-rule hdll=0x%x\n", sec_dft_low_lat_rt_rule_hdl[0]);
+ }
+ else
+ {
dft_low_lat_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
IPACMDBG_H("ipv4 low lat udp rt-rule hdll=0x%x\n", dft_low_lat_rt_rule_hdl[0]);
}
+ }
}
else
{
@@ -845,13 +969,21 @@
}
}
- wan_v4_addr = data->ipv4_addr;
- wan_v4_addr_set = true;
+ if (m_is_sta_mode == Q6_WAN && sec_addr)
+ {
+ sec_wan_v4_addr = data->ipv4_addr;
+ sec_wan_v4_addr_set = true;
+ }
+ else
+ {
+ wan_v4_addr = data->ipv4_addr;
+ wan_v4_addr_set = true;
+ }
- if (m_is_sta_mode == Q6_WAN)
+ if (m_is_sta_mode == Q6_WAN && !sec_addr)
curr_wan_ip = data->ipv4_addr;
- IPACMDBG_H("Receved wan ipv4-addr:0x%x\n",wan_v4_addr);
+ IPACMDBG_H("Receved wan ipv4-addr:0x%x, sec_addr:%d\n",data->ipv4_addr, sec_addr);
}
#ifdef FEATURE_IPACM_HAL
@@ -874,6 +1006,280 @@
return res;
}
+ /* handle del_address event */
+ int IPACM_Wan::handle_addr_del_evt(ipacm_event_data_addr *data)
+ {
+ bool result;
+
+ const int NUM_RULES = 1;
+ uint32_t num_ipv6_addr, rt_idx = 0;
+ int res = IPACM_SUCCESS,len;
+#ifdef FEATURE_IPACM_HAL
+ IPACM_OffloadManager* OffloadMng;
+#endif
+ bool sec_addr = false, pri_addr = false;
+ int i = 0;
+ bool wan_active = false;
+
+ if(tx_prop == NULL || rx_prop == NULL)
+ {
+ IPACMDBG_H("Either tx or rx property is NULL, return.\n");
+ return IPACM_SUCCESS;
+ }
+
+ if (data->iptype == IPA_IP_v6)
+ {
+ /* Check if the address deleted is primary or secondary address. */
+
+ for(num_ipv6_addr=0;num_ipv6_addr<sec_num_dft_rt_v6;num_ipv6_addr++)
+ {
+ if((sec_ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) &&
+ (sec_ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) &&
+ (sec_ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) &&
+ (sec_ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3]))
+ {
+ IPACMDBG_H("find matched ipv6 address, index:%d \n", num_ipv6_addr);
+ sec_addr = true;
+ }
+ }
+
+ for(num_ipv6_addr=0;num_ipv6_addr<num_dft_rt_v6;num_ipv6_addr++)
+ {
+ if((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) &&
+ (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) &&
+ (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) &&
+ (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3]))
+ {
+ IPACMDBG_H("find matched ipv6 address, index:%d \n", num_ipv6_addr);
+ pri_addr = true;
+ rt_idx = num_ipv6_addr;
+ }
+ }
+
+ if (!sec_addr && !pri_addr)
+ {
+ IPACMDBG_H("Not matching Either Primary or Secondary addresses, return.\n");
+ return IPACM_SUCCESS;
+ }
+
+ if (sec_addr)
+ {
+ /* Clean up the rules. */
+ IPACMDBG_H("Delete Secondary v6 routing rules\n");
+ for (i = 0; i < 2; i++)
+ {
+ /* delete v6 colasce rules */
+ if (m_routing.DeleteRoutingHdl(sec_dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Colasce Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ if (m_routing.DeleteRoutingHdl(sec_dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ if (m_routing.DeleteRoutingHdl(sec_dft_low_lat_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES], IPA_IP_v6) == false)
+ {
+ IPACMERR("Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ memset(sec_ipv6_addr, 0, sizeof(sec_ipv6_addr));
+ sec_num_dft_rt_v6 = 0;
+ return IPACM_SUCCESS;
+ }
+
+ if (pri_addr)
+ {
+ /* delete v6 colasce rules and copy secondary rules into Primary if applicable. */
+ IPACMDBG_H("Delete Primary v6 routing rules\n");
+ for (i = 0; i < MAX_DEFAULT_v6_ROUTE_RULES; i++)
+ {
+ if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*rt_idx+i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Colasce Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ if (is_global_ipv6_addr(data->ipv6_addr) && sec_num_dft_rt_v6 > 0)
+ {
+ dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*rt_idx+i] =
+ sec_dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES+i];
+ sec_dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES+i] = 0;
+ IPACMDBG_H("Coalescing routing rule update, index: %d/%d, hdl:%d\n",
+ rt_idx, 2*rt_idx+i,
+ dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*rt_idx+i]);
+ }
+ if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+2*rt_idx+i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ if (is_global_ipv6_addr(data->ipv6_addr) && sec_num_dft_rt_v6 > 0)
+ {
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+2*rt_idx+i] =
+ sec_dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + i];
+ sec_dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + i] = 0;
+ IPACMDBG_H("Default routing rule update, index: %d/%d, hdl:%d\n",
+ rt_idx, 2*rt_idx+i,
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+2*rt_idx+i]);
+ }
+ }
+
+ /* Delete low lat rules. */
+ if (m_routing.DeleteRoutingHdl(dft_low_lat_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+rt_idx], IPA_IP_v6) == false)
+ {
+ IPACMERR("Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ /* Copy secondary rules into Primary. */
+ if (is_global_ipv6_addr(data->ipv6_addr) && sec_num_dft_rt_v6 > 0)
+ {
+ dft_low_lat_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+rt_idx] =
+ sec_dft_low_lat_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES];
+ }
+
+ if (is_global_ipv6_addr(data->ipv6_addr) && sec_num_dft_rt_v6 > 0)
+ {
+ if (active_v6)
+ {
+ post_wan_down_tether_evt(IPA_IP_v6, 0);
+ del_wan_firewall_rule(IPA_IP_v6);
+ handle_route_del_evt_ex(IPA_IP_v6);
+ wan_active = true;
+ }
+ /* Copy Secondary Address onto Primary. */
+ ipv6_addr[rt_idx][0] = sec_ipv6_addr[sec_num_dft_rt_v6-1][0];
+ ipv6_addr[rt_idx][1] = sec_ipv6_addr[sec_num_dft_rt_v6-1][1];
+ ipv6_addr[rt_idx][2] = sec_ipv6_addr[sec_num_dft_rt_v6-1][2];
+ ipv6_addr[rt_idx][3] = sec_ipv6_addr[sec_num_dft_rt_v6-1][3];
+ memcpy(ipv6_prefix, sec_ipv6_addr[sec_num_dft_rt_v6-1], sizeof(ipv6_prefix));
+ memset(sec_ipv6_addr[sec_num_dft_rt_v6-1], 0, sizeof(sec_ipv6_addr[sec_num_dft_rt_v6-1]));
+ sec_num_dft_rt_v6--;
+ IPACMDBG_H("Secondary v6 num %d: \n",sec_num_dft_rt_v6);
+ if (wan_active)
+ {
+ handle_route_add_evt(IPA_IP_v6);
+ }
+ }
+ else
+ {
+ num_dft_rt_v6--;
+ IPACMDBG_H("v6 num %d: \n",num_dft_rt_v6);
+ }
+ }
+ }
+ else
+ {
+ if (data->ipv4_addr == sec_wan_v4_addr)
+ {
+ IPACMDBG_H("Delete Secondary coalescing v4 routing rules\n");
+ if (m_routing.DeleteRoutingHdl(sec_dft_coalesce_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing old RSC TCP RT rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ sec_dft_coalesce_rt_rule_hdl[0] = 0;
+ if (m_routing.DeleteRoutingHdl(sec_dft_coalesce_rt_rule_hdl[1], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing old RSB UDP RT rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ sec_dft_coalesce_rt_rule_hdl[1] = 0;
+ IPACMDBG_H("Delete Secondary v4 default routing rules\n");
+ if (m_routing.DeleteRoutingHdl(sec_dft_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing old RT rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ sec_dft_rt_rule_hdl[0] = 0;
+ if (m_routing.DeleteRoutingHdl(sec_dft_low_lat_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Secondary Routing rule low lat deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ sec_dft_low_lat_rt_rule_hdl[0] = 0;
+ sec_wan_v4_addr_set = false;
+ sec_wan_v4_addr = 0;
+ return IPACM_SUCCESS;
+ }
+ else if (data->ipv4_addr == wan_v4_addr)
+ {
+
+ IPACMDBG_H("Delete default coalescing v4 routing rules\n");
+ if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing old RSC TCP RT rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ dft_coalesce_rt_rule_hdl[0] = sec_dft_coalesce_rt_rule_hdl[0];
+ sec_dft_coalesce_rt_rule_hdl[0] = 0;
+ if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[1], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing old RSB UDP RT rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ dft_coalesce_rt_rule_hdl[1] = sec_dft_coalesce_rt_rule_hdl[1];
+ sec_dft_coalesce_rt_rule_hdl[1] = 0;
+ IPACMDBG_H("New coalescing routing rule hdls:%d:%d\n",
+ dft_coalesce_rt_rule_hdl[0],dft_coalesce_rt_rule_hdl[1]);
+ IPACMDBG_H("Delete default v4 routing rules\n");
+ if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing old RT rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ dft_rt_rule_hdl[0] = sec_dft_rt_rule_hdl[0];
+ IPACMDBG_H("New default rule routing rule hdl:%d\n",
+ dft_rt_rule_hdl[0]);
+ if (m_routing.DeleteRoutingHdl(dft_low_lat_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing old RT rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ dft_low_lat_rt_rule_hdl[0] = sec_dft_low_lat_rt_rule_hdl[0];
+ IPACMDBG_H("New default rule low lat routing rule hdl:%d\n",
+ sec_dft_low_lat_rt_rule_hdl[0]);
+
+ /* Post WAN_DOWN with old ip address. */
+ if (active_v4)
+ {
+ post_wan_down_tether_evt(IPA_IP_v4, 0);
+ del_wan_firewall_rule(IPA_IP_v4);
+ handle_route_del_evt_ex(IPA_IP_v4);
+ wan_active = true;
+ }
+ wan_v4_addr = sec_wan_v4_addr;
+ IPACMDBG_H("WAN IPv4 address:0x%x\n",
+ wan_v4_addr);
+ sec_wan_v4_addr_set = false;
+ sec_wan_v4_addr = 0;
+ /* Post WAN_UP with new ip address. */
+ if (wan_active)
+ {
+ handle_route_add_evt(IPA_IP_v4);
+ }
+ }
+ }
+fail:
+ return res;
+ }
+
+
/* handle new_address event */
int IPACM_Wan::handle_addr_evt_mhi_q6(ipacm_event_data_addr *data)
{
@@ -1305,9 +1711,11 @@
if (ipa_interface_index == ipa_if_num)
{
IPACMDBG_H("Get IPA_ADDR_ADD_EVENT: IF ip type %d, incoming ip type %d\n", ip_type, data->iptype);
- /* check v4 not setup before, v6 can have 2 iface ip */
+ /* check v4 not setup before, v6 can have 2 iface ip or secondary ipv6 address. */
if( (data->iptype == IPA_IP_v4)
- || ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES)))
+ || ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES))
+ || ((data->iptype==IPA_IP_v6) && is_global_ipv6_addr(data->ipv6_addr)
+ && (m_is_sta_mode == Q6_WAN) && sec_num_dft_rt_v6 != MAX_DEFAULT_SEC_v6_ROUTE_RULES) )
{
if (m_is_sta_mode == Q6_MHI_WAN)
{
@@ -1335,9 +1743,31 @@
handle_software_routing_enable(false);
}
}
-
+ }
}
}
+ break;
+
+ case IPA_ADDR_DEL_EVENT:
+ {
+ ipacm_event_data_addr *data = (ipacm_event_data_addr *)param;
+ ipa_interface_index = iface_ipa_index_query(data->if_index);
+
+ if ( (data->iptype == IPA_IP_v4 && data->ipv4_addr == 0) ||
+ (data->iptype == IPA_IP_v6 &&
+ data->ipv6_addr[0] == 0 && data->ipv6_addr[1] == 0 &&
+ data->ipv6_addr[2] == 0 && data->ipv6_addr[3] == 0) )
+ {
+ IPACMDBG_H("Invalid address, ignore IPA_ADDR_DEL_EVENT event\n");
+ return;
+ }
+
+ if (ipa_interface_index == ipa_if_num)
+ {
+ IPACMDBG_H("Get IPA_ADDR_DEL_EVENT: IF ip type %d, incoming ip type %d\n", ip_type, data->iptype);
+ IPACMDBG_H("v6 num %d: \n",num_dft_rt_v6);
+ handle_addr_del_evt(data);
+ }
}
break;
@@ -5891,6 +6321,41 @@
res = IPACM_FAILURE;
goto fail;
}
+
+ if (sec_wan_v4_addr_set)
+ {
+ IPACMDBG_H("Delete Secondary v4 coalesce routing rules\n");
+ if (m_routing.DeleteRoutingHdl(sec_dft_coalesce_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Secondary Routing rule RSC TCP deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ if (m_routing.DeleteRoutingHdl(sec_dft_coalesce_rt_rule_hdl[1], IPA_IP_v4) == false)
+ {
+ IPACMERR("Secondary Routing rule RSB UDP deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ if (m_routing.DeleteRoutingHdl(sec_dft_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Secondary Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ if (m_routing.DeleteRoutingHdl(sec_dft_low_lat_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Secondary Routing rule low lat deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ sec_wan_v4_addr_set = false;
+ sec_wan_v4_addr = 0;
+ }
}
else if(ip_type == IPA_IP_v6)
{
@@ -5957,6 +6422,7 @@
goto fail;
}
}
+
/* Delete v6 low lat rules */
for (i = 0; i < num_dft_rt_v6; i++)
{
@@ -5967,6 +6433,36 @@
goto fail;
}
}
+
+ if (sec_num_dft_rt_v6)
+ {
+ /* Clean up the rules. */
+ IPACMDBG_H("Delete Secondary v6 routing rules\n");
+ for (i = 0; i < 2; i++)
+ {
+ /* delete v6 colasce rules */
+ if (m_routing.DeleteRoutingHdl(sec_dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Colasce Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ if (m_routing.DeleteRoutingHdl(sec_dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ if (m_routing.DeleteRoutingHdl(sec_dft_low_lat_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES], IPA_IP_v6) == false)
+ {
+ IPACMERR("Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ memset(sec_ipv6_addr, 0, sizeof(sec_ipv6_addr));
+ sec_num_dft_rt_v6 = 0;
+ }
}
else
{
@@ -6073,6 +6569,41 @@
goto fail;
}
+ if (sec_wan_v4_addr_set)
+ {
+ IPACMDBG_H("Delete Secondary v4 coalesce routing rules\n");
+ if (m_routing.DeleteRoutingHdl(sec_dft_coalesce_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Secondary Routing rule RSC TCP deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ if (m_routing.DeleteRoutingHdl(sec_dft_coalesce_rt_rule_hdl[1], IPA_IP_v4) == false)
+ {
+ IPACMERR("Secondary Routing rule RSB UDP deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ if (m_routing.DeleteRoutingHdl(sec_dft_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Secondary Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ if (m_routing.DeleteRoutingHdl(sec_dft_low_lat_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ sec_wan_v4_addr_set = false;
+ sec_wan_v4_addr = 0;
+ }
+
for (i = 0; i < 2*num_dft_rt_v6; i++)
{
/* delete v6 colasce rules */
@@ -6089,6 +6620,7 @@
goto fail;
}
}
+
for (i = 0; i < num_dft_rt_v6; i++)
{
if (m_routing.DeleteRoutingHdl(dft_low_lat_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
@@ -6098,6 +6630,36 @@
goto fail;
}
}
+
+ if (sec_num_dft_rt_v6)
+ {
+ /* Clean up the rules. */
+ IPACMDBG_H("Delete Secondary v6 routing rules\n");
+ for (i = 0; i < 2; i++)
+ {
+ /* delete v6 colasce rules */
+ if (m_routing.DeleteRoutingHdl(sec_dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Colasce Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ if (m_routing.DeleteRoutingHdl(sec_dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ if (m_routing.DeleteRoutingHdl(sec_dft_low_lat_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES], IPA_IP_v6) == false)
+ {
+ IPACMERR("Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ memset(sec_ipv6_addr, 0, sizeof(sec_ipv6_addr));
+ sec_num_dft_rt_v6 = 0;
+ }
}
// /* check software routing fl rule hdl */
@@ -7642,6 +8204,136 @@
fail:
free(rt_rule);
}
+
+ if(sec_wan_v4_addr_set)
+ {
+ /* Delete secondary default RSC v4 RT rule */
+ if (m_routing.DeleteRoutingHdl(sec_dft_coalesce_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Sec Routing old RSC TCP RT rule deletion failed!\n");
+ return IPACM_FAILURE;
+ }
+ if (m_routing.DeleteRoutingHdl(sec_dft_coalesce_rt_rule_hdl[1], IPA_IP_v4) == false)
+ {
+ IPACMERR("Sec Routing old RSB UDP RT rule deletion failed!\n");
+ return IPACM_FAILURE;
+ }
+ /* Delete secondary default v4 RT rule */
+ IPACMDBG_H("Delete Secondary default v4 routing rules\n");
+ if (m_routing.DeleteRoutingHdl(sec_dft_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing old RT rule deletion failed!\n");
+ return IPACM_FAILURE;
+ }
+
+ /* apply the new coalesce configuration for secondary address. */
+ rt_rule = (struct ipa_ioc_add_rt_rule *)
+ calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
+ NUM_RULES * 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 = NUM_RULES;
+ rt_rule->ip = IPA_IP_v4;
+ rt_rule_entry = &rt_rule->rules[0];
+ rt_rule_entry->at_rear = true;
+ rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
+ /* still need setup v4 default routing rule to APPs*/
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name));
+ rt_rule_entry->rule.attrib.u.v4.dst_addr = sec_wan_v4_addr;
+ rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
+ if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
+ rt_rule_entry->rule.hashable = false;
+ /* query qmap header*/
+ memset(&hdr, 0, sizeof(hdr));
+ strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
+ hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
+ if(m_header.GetHeaderHandle(&hdr) == false)
+ {
+ IPACMERR("Failed to get QMAP header.\n");
+ res = IPACM_FAILURE;
+ goto fail1;
+ }
+ rt_rule_entry->rule.hdr_hdl = hdr.hdl;
+ rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS;
+
+ /* RSB UDP rule*/
+ rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
+ rt_rule_entry->rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_UDP;
+#ifdef IPA_RT_SUPPORT_COAL
+ if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable)
+ rt_rule_entry->rule.coalesce = true;
+ else
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail1;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("secondary rsb udp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail1;
+ }
+ sec_dft_coalesce_rt_rule_hdl[1] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("secondary ipv4 wan iface rsb udp rt-rule hdll=0x%x enable(%d)\n", sec_dft_coalesce_rt_rule_hdl[1],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable);
+
+ /* RSC TCP rule*/
+ rt_rule_entry->rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_TCP;
+#ifdef IPA_RT_SUPPORT_COAL
+ if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable)
+ rt_rule_entry->rule.coalesce = true;
+ else
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail1;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("secondary rsc tcp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail1;
+ }
+ sec_dft_coalesce_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("secondary ipv4 wan iface rsc tcp rt-rule hdll=0x%x\n enable(%d)", sec_dft_coalesce_rt_rule_hdl[0],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable);
+
+ /* secondary default v4 rt-rule */
+ rt_rule_entry->rule.attrib.attrib_mask &= ~IPA_FLT_PROTOCOL;
+#ifdef IPA_RT_SUPPORT_COAL
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ /* Secondary default v4 rt-rule */
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail1;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("secondary rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail1;
+ }
+ sec_dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("secondary ipv4 wan iface rt-rule hdll=0x%x\n", sec_dft_rt_rule_hdl[0]);
+
+fail1:
+ free(rt_rule);
+ }
+
/* v6 */
if (num_dft_rt_v6 !=0)
{
@@ -7793,6 +8485,159 @@
fail2:
free(rt_rule);
}
+
+ /* Secondary v6 */
+ if (sec_num_dft_rt_v6 !=0)
+ {
+ for (i = 0; i < 2*sec_num_dft_rt_v6; i++)
+ {
+ /* delete secondary v6 colasce rules */
+ if (m_routing.DeleteRoutingHdl(sec_dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Colasce Routing rule deletion failed!\n");
+ return IPACM_FAILURE;
+ }
+ /* delete secondary v6 default rules */
+ if (m_routing.DeleteRoutingHdl(sec_dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Routing rule deletion failed!\n");
+ return IPACM_FAILURE;
+ }
+ }
+
+ rt_rule = (struct ipa_ioc_add_rt_rule *)
+ calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
+ NUM_RULES * 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 = NUM_RULES;
+ rt_rule->ip = IPA_IP_v6;
+
+ for (i = 0; i < sec_num_dft_rt_v6; i++)
+ {
+ /* setup same rule for v6_wan table */
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name));
+ rt_rule_entry = &rt_rule->rules[0];
+ rt_rule_entry->at_rear = true;
+ rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = sec_ipv6_addr[i][0];
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = sec_ipv6_addr[i][1];
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = sec_ipv6_addr[i][2];
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = sec_ipv6_addr[i][3];
+ rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
+ if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
+ rt_rule_entry->rule.hashable = false;
+ strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
+ hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
+ if(m_header.GetHeaderHandle(&hdr) == false)
+ {
+ IPACMERR("Failed to get QMAP header.\n");
+ return IPACM_FAILURE;
+ }
+ rt_rule_entry->rule.hdr_hdl = hdr.hdl;
+ rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS;
+
+ /* Secondary RSB UDP rule*/
+ rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
+ rt_rule_entry->rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_UDP;
+#ifdef IPA_RT_SUPPORT_COAL
+ if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable)
+ rt_rule_entry->rule.coalesce = true;
+ else
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail3;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("secondary rsb udp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail3;
+ }
+ sec_dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*i+1] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("secondary ipv6 wan iface rsb udp rt-rule hdll=0x%x\n enable(%d)", sec_dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*i+1],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable);
+
+ /* Secondary RSC TCP rule*/
+ rt_rule_entry->rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_TCP;
+#ifdef IPA_RT_SUPPORT_COAL
+ if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable)
+ rt_rule_entry->rule.coalesce = true;
+ else
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail3;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("secondary rsc tcp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail3;
+ }
+ sec_dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*i] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("secondary ipv6 wan iface rsc tcp rt-rule hdll=0x%x\n enable(%d)", sec_dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*i],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable);
+
+ /* legacy default secondary v6 rt-rule */
+ rt_rule_entry->rule.attrib.attrib_mask &= ~IPA_FLT_NEXT_HDR;
+#ifdef IPA_RT_SUPPORT_COAL
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ /* legacy default secondary v6 rt-rule */
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail3;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("secondary rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail3;
+ }
+ sec_dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*i] = rt_rule_entry->rt_rule_hdl;
+
+ /* setup same rule for v6_lan table*/
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail3;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail3;
+ }
+ sec_dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*i+1] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("secondary ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, entry: %d %d\n",
+ sec_dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*i],
+ sec_dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*i+1],
+ MAX_DEFAULT_v4_ROUTE_RULES + 2*i,
+ MAX_DEFAULT_v4_ROUTE_RULES + 2*i+1);
+ }
+fail3:
+ free(rt_rule);
+ }
+
return res;
}
diff --git a/ipanat/inc/ipa_nat_drv.h b/ipanat/inc/ipa_nat_drv.h
index 9be97f3..739230a 100644
--- a/ipanat/inc/ipa_nat_drv.h
+++ b/ipanat/inc/ipa_nat_drv.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -246,8 +246,16 @@
int ipa_nat_vote_clock(
enum ipa_app_clock_vote_type vote_type );
+/**
+ * ipa_nat_switch_to() - While in HYBRID mode only, used for switching
+ * from SRAM to DDR or the reverse.
+ * @nmi: memory type to switch to
+ * @hold_state: Will the new memory type get locked in (ie. no more
+ * oscilation between the memory types)
+ */
int ipa_nat_switch_to(
- enum ipa3_nat_mem_in nmi );
+ enum ipa3_nat_mem_in nmi,
+ bool hold_state );
#endif
diff --git a/ipanat/inc/ipa_nat_statemach.h b/ipanat/inc/ipa_nat_statemach.h
index a86dd87..94b86ed 100644
--- a/ipanat/inc/ipa_nat_statemach.h
+++ b/ipanat/inc/ipa_nat_statemach.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -29,6 +29,8 @@
#if !defined(_IPA_NAT_STATEMACH_H_)
# define _IPA_NAT_STATEMACH_H_
+#define MAKE_AS_STR_CASE(v) case v: return #v
+
/******************************************************************************/
/**
* The following enum represents the states that a nati object can be
@@ -44,6 +46,26 @@
NATI_STATE_LAST
} ipa_nati_state;
+/* KEEP THE FOLLOWING IN SYNC WITH ABOVE. */
+static inline const char* ipa_nati_state_as_str(
+ ipa_nati_state s )
+{
+ switch ( s )
+ {
+ MAKE_AS_STR_CASE(NATI_STATE_NULL);
+ MAKE_AS_STR_CASE(NATI_STATE_DDR_ONLY);
+ MAKE_AS_STR_CASE(NATI_STATE_SRAM_ONLY);
+ MAKE_AS_STR_CASE(NATI_STATE_HYBRID);
+ MAKE_AS_STR_CASE(NATI_STATE_HYBRID_DDR);
+ MAKE_AS_STR_CASE(NATI_STATE_LAST);
+
+ default:
+ break;
+ }
+
+ return "???";
+}
+
# undef strcasesame
# define strcasesame(a, b) (!strcasecmp(a, b))
@@ -114,6 +136,8 @@
{
ipa_nati_state prev_state;
ipa_nati_state curr_state;
+ bool hold_state;
+ ipa_nati_state state_to_hold;
uint32_t ddr_tbl_hdl;
uint32_t sram_tbl_hdl;
uint32_t tot_slots_in_sram;
@@ -144,11 +168,32 @@
#define DDR_SUB 0
#define SRAM_SUB 1
+#undef BACK2_UNSTARTED_STATE
+#define BACK2_UNSTARTED_STATE() \
+ nati_obj.prev_state = nati_obj.curr_state = NATI_STATE_NULL;
+
+#undef IN_UNSTARTED_STATE
+#define IN_UNSTARTED_STATE() \
+ ( nati_obj.prev_state == NATI_STATE_NULL )
+
#undef IN_HYBRID_STATE
#define IN_HYBRID_STATE() \
( nati_obj.curr_state == NATI_STATE_HYBRID || \
nati_obj.curr_state == NATI_STATE_HYBRID_DDR )
+#undef COMPATIBLE_NMI_4SWITCH
+#define COMPATIBLE_NMI_4SWITCH(n) \
+ ( (n) == IPA_NAT_MEM_IN_SRAM && nati_obj.curr_state == NATI_STATE_HYBRID_DDR ) || \
+ ( (n) == IPA_NAT_MEM_IN_DDR && nati_obj.curr_state == NATI_STATE_HYBRID ) || \
+ ( (n) == IPA_NAT_MEM_IN_DDR && nati_obj.curr_state == NATI_STATE_DDR_ONLY ) || \
+ ( (n) == IPA_NAT_MEM_IN_SRAM && nati_obj.curr_state == NATI_STATE_SRAM_ONLY )
+
+#undef GEN_HOLD_STATE
+#define GEN_HOLD_STATE() \
+ ( ! IN_HYBRID_STATE() ) ? nati_obj.curr_state : \
+ (nati_obj.curr_state == NATI_STATE_HYBRID) ? NATI_STATE_SRAM_ONLY : \
+ NATI_STATE_DDR_ONLY
+
#undef SRAM_CURRENTLY_ACTIVE
#define SRAM_CURRENTLY_ACTIVE() \
( nati_obj.curr_state == NATI_STATE_SRAM_ONLY || \
@@ -256,6 +301,7 @@
uint32_t public_ip_addr;
uint16_t number_of_entries;
uint32_t* tbl_hdl;
+ const char* mem_type_ptr;
} table_add_args;
typedef struct
diff --git a/ipanat/src/ipa_nat_statemach.c b/ipanat/src/ipa_nat_statemach.c
index c65f88a..b6cf284 100644
--- a/ipanat/src/ipa_nat_statemach.c
+++ b/ipanat/src/ipa_nat_statemach.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -111,7 +111,9 @@
*/
static ipa_nati_obj nati_obj = {
.prev_state = NATI_STATE_NULL,
- .curr_state = NATI_STATE_DDR_ONLY,
+ .curr_state = NATI_STATE_NULL,
+ .hold_state = false,
+ .state_to_hold = NATI_STATE_NULL,
.ddr_tbl_hdl = 0,
.sram_tbl_hdl = 0,
.tot_slots_in_sram = 0,
@@ -187,6 +189,53 @@
}
/*
+ * Function for taking/locking the mutex...
+ */
+static int take_mutex()
+{
+ int ret;
+
+ if ( nat_mutex_init )
+ {
+again:
+ ret = pthread_mutex_lock(&nat_mutex);
+ }
+ else
+ {
+ ret = mutex_init();
+
+ if ( ret == 0 )
+ {
+ goto again;
+ }
+ }
+
+ if ( ret != 0 )
+ {
+ IPAERR("Unable to lock the %s nat mutex\n",
+ (nat_mutex_init) ? "initialized" : "uninitialized");
+ }
+
+ return ret;
+}
+
+/*
+ * Function for giving/unlocking the mutex...
+ */
+static int give_mutex()
+{
+ int ret = (nat_mutex_init) ? pthread_mutex_unlock(&nat_mutex) : -1;
+
+ if ( ret != 0 )
+ {
+ IPAERR("Unable to unlock the %s nat mutex\n",
+ (nat_mutex_init) ? "initialized" : "uninitialized");
+ }
+
+ return ret;
+}
+
+/*
* ****************************************************************************
*
* HIJACKED API FUNCTIONS START HERE
@@ -203,22 +252,13 @@
.public_ip_addr = public_ip_addr,
.number_of_entries = number_of_entries,
.tbl_hdl = tbl_hdl,
+ .mem_type_ptr = mem_type_ptr,
};
int ret;
IPADBG("In\n");
- /*
- * If first time in here, then let XML drive initial state...
- */
- if (nati_obj.prev_state == NATI_STATE_NULL)
- {
- SET_NATIOBJ_STATE(
- &nati_obj,
- mem_type_str_to_ipa_nati_state(mem_type_ptr));
- }
-
ret = ipa_nati_statemach(&nati_obj, NATI_TRIG_ADD_TABLE, (void*) &args);
if ( ret == 0 )
@@ -388,27 +428,142 @@
}
int ipa_nat_switch_to(
- enum ipa3_nat_mem_in nmi )
+ enum ipa3_nat_mem_in nmi,
+ bool hold_state )
{
- int ret = 0;
+ int ret = -1;
- IPADBG("In\n");
+ IPADBG("In - current state %s\n",
+ ipa_nati_state_as_str(nati_obj.curr_state));
- if ( ! IPA_VALID_NAT_MEM_IN(nmi) || ! IN_HYBRID_STATE() )
+ if ( ! IPA_VALID_NAT_MEM_IN(nmi) )
{
- IPAERR("Bad nmi(%s) and/or not in hybrid state\n",
- ipa3_nat_mem_in_as_str(nmi));
+ IPAERR("Bad nmi(%s)\n", ipa3_nat_mem_in_as_str(nmi));
+
ret = -1;
+
goto bail;
}
- if ( (nmi == IPA_NAT_MEM_IN_SRAM && nati_obj.curr_state == NATI_STATE_HYBRID_DDR)
- ||
- (nmi == IPA_NAT_MEM_IN_DDR && nati_obj.curr_state == NATI_STATE_HYBRID) )
+ ret = take_mutex();
+
+ if ( ret != 0 )
{
- ret = ipa_nati_statemach(&nati_obj, NATI_TRIG_TBL_SWITCH, 0);
+ goto bail;
}
+ /*
+ * Are we here before the state machine has been started?
+ */
+ if ( IN_UNSTARTED_STATE() )
+ {
+ nati_obj.hold_state = hold_state;
+
+ nati_obj.state_to_hold =
+ (nmi == IPA_NAT_MEM_IN_DDR) ?
+ NATI_STATE_DDR_ONLY :
+ NATI_STATE_SRAM_ONLY;
+
+ IPADBG(
+ "Initial state will be %s before table init and it %s be held\n",
+ ipa_nati_state_as_str(nati_obj.state_to_hold),
+ (hold_state) ? "will" : "will not");
+
+ ret = 0;
+
+ goto unlock;
+ }
+
+ /*
+ * Are we here after we've already started in hybrid state?
+ */
+ if ( IN_HYBRID_STATE() )
+ {
+ ret = 0;
+
+ if ( COMPATIBLE_NMI_4SWITCH(nmi) )
+ {
+ ret = ipa_nati_statemach(&nati_obj, NATI_TRIG_TBL_SWITCH, 0);
+ }
+
+ if ( ret == 0 )
+ {
+ nati_obj.hold_state = hold_state;
+
+ if ( hold_state )
+ {
+ nati_obj.state_to_hold = GEN_HOLD_STATE();
+ }
+
+ IPADBG(
+ "Current state is %s and it %s be held\n",
+ ipa_nati_state_as_str(nati_obj.curr_state),
+ (hold_state) ? "will" : "will not");
+ }
+
+ goto unlock;
+ }
+
+ /*
+ * We've gotten here because we're not in an unstarted state, nor
+ * are we in hybrid state. This means we're either in
+ * NATI_STATE_DDR_ONLY or NATI_STATE_SRAM_ONLY
+ *
+ * Let's see what's being attempted and if it's OK...
+ */
+ if ( hold_state )
+ {
+ if ( COMPATIBLE_NMI_4SWITCH(nmi) )
+ {
+ /*
+ * If we've gotten here, it means that the requested nmi,
+ * the current state, and the hold are compatible...
+ */
+ nati_obj.state_to_hold = GEN_HOLD_STATE();
+ nati_obj.hold_state = hold_state;
+
+ IPADBG(
+ "Requesting to hold memory type %s at "
+ "current state %s will be done\n",
+ ipa3_nat_mem_in_as_str(nmi),
+ ipa_nati_state_as_str(nati_obj.curr_state));
+
+ ret = 0;
+
+ goto unlock;
+ }
+ else
+ {
+ /*
+ * The requested nmi, the current state, and the hold are
+ * not compatible...
+ */
+ IPAERR(
+ "Requesting to hold memory type %s and "
+ "current state %s are incompatible\n",
+ ipa3_nat_mem_in_as_str(nmi),
+ ipa_nati_state_as_str(nati_obj.curr_state));
+
+ ret = -1;
+
+ goto unlock;
+ }
+ }
+
+ /*
+ * If we've gotten here, it's because the holding of state is no
+ * longer desired...
+ */
+ nati_obj.state_to_hold = NATI_STATE_NULL;
+ nati_obj.hold_state = hold_state;
+
+ IPADBG("Holding of state is no longer desired\n");
+
+ ret = 0;
+
+unlock:
+ ret = give_mutex();
+
bail:
IPADBG("Out\n");
@@ -671,6 +826,69 @@
ret = ipa_NATI_del_ipv4_table(tbl_hdl);
+ if ( ret == 0 && ! IN_HYBRID_STATE() )
+ {
+ /*
+ * The following will create the preferred "initial state" for
+ * restart...
+ */
+ BACK2_UNSTARTED_STATE();
+ }
+
+ IPADBG("Out\n");
+
+ return ret;
+}
+
+/******************************************************************************/
+/*
+ * FUNCTION: _smFirstTbl
+ *
+ * PARAMS:
+ *
+ * nati_obj_ptr (IN) A pointer to an initialized nati object
+ *
+ * trigger (IN) The trigger to run through the state machine
+ *
+ * arb_data_ptr (IN) Whatever you like
+ *
+ * DESCRIPTION:
+ *
+ * The following will cause the creation of the very first NAT table(s)
+ * before any others have ever been created...
+ *
+ * RETURNS:
+ *
+ * zero on success, otherwise non-zero
+ */
+static int _smFirstTbl(
+ ipa_nati_obj* nati_obj_ptr,
+ ipa_nati_trigger trigger,
+ void* arb_data_ptr )
+{
+ table_add_args* args = (table_add_args*) arb_data_ptr;
+
+ uint32_t public_ip_addr = args->public_ip_addr;
+ uint16_t number_of_entries = args->number_of_entries;
+ uint32_t* tbl_hdl_ptr = args->tbl_hdl;
+ const char* mem_type_ptr = args->mem_type_ptr;
+
+ int ret;
+
+ IPADBG("In\n");
+
+ /*
+ * This is the first time in here. Let the ipacm's XML config (or
+ * state_to_hold) drive initial state...
+ */
+ SET_NATIOBJ_STATE(
+ nati_obj_ptr,
+ (nati_obj_ptr->hold_state && nati_obj_ptr->state_to_hold) ?
+ nati_obj_ptr->state_to_hold :
+ mem_type_str_to_ipa_nati_state(mem_type_ptr));
+
+ ret = ipa_nati_statemach(nati_obj_ptr, NATI_TRIG_ADD_TABLE, arb_data_ptr);
+
IPADBG("Out\n");
return ret;
@@ -987,6 +1205,15 @@
ret = _smDelTbl(nati_obj_ptr, trigger, (void*) &new_args);
}
+ if ( ret == 0 )
+ {
+ /*
+ * The following will create the preferred "initial state" for
+ * restart...
+ */
+ BACK2_UNSTARTED_STATE();
+ }
+
IPADBG("Out\n");
return ret;
@@ -1514,7 +1741,9 @@
}
else
{
- if ( nati_obj_ptr->curr_state == NATI_STATE_HYBRID )
+ if ( nati_obj_ptr->curr_state == NATI_STATE_HYBRID
+ &&
+ ! nati_obj_ptr->hold_state )
{
/*
* In hybrid mode, we always start in SRAM...hence
@@ -1645,7 +1874,9 @@
*/
uint32_t* cnt_ptr = CHOOSE_CNTR();
- if ( *cnt_ptr <= nati_obj_ptr->back_to_sram_thresh )
+ if ( *cnt_ptr <= nati_obj_ptr->back_to_sram_thresh
+ &&
+ ! nati_obj_ptr->hold_state )
{
/*
* The following will focus us on SRAM and cause the copy
@@ -1807,7 +2038,9 @@
uint64_t start, stop;
- int stats_ret, ret;
+ int stats_ret, ret;
+
+ bool collect_stats = (bool) arb_data_ptr;
UNUSED(cnt_ptr);
UNUSED(trigger);
@@ -1815,8 +2048,10 @@
IPADBG("In\n");
- stats_ret = ipa_NATI_ipv4_tbl_stats(
- nati_obj_ptr->ddr_tbl_hdl, &nat_stats, &idx_stats);
+ stats_ret = (collect_stats) ?
+ ipa_NATI_ipv4_tbl_stats(
+ nati_obj_ptr->ddr_tbl_hdl, &nat_stats, &idx_stats) :
+ -1;
currTimeAs(TimeAsNanSecs, &start);
@@ -1979,7 +2214,9 @@
uint64_t start, stop;
- int stats_ret, ret;
+ int stats_ret, ret;
+
+ bool collect_stats = (bool) arb_data_ptr;
UNUSED(cnt_ptr);
UNUSED(trigger);
@@ -1987,8 +2224,10 @@
IPADBG("In\n");
- stats_ret = ipa_NATI_ipv4_tbl_stats(
- nati_obj_ptr->sram_tbl_hdl, &nat_stats, &idx_stats);
+ stats_ret = (collect_stats) ?
+ ipa_NATI_ipv4_tbl_stats(
+ nati_obj_ptr->sram_tbl_hdl, &nat_stats, &idx_stats) :
+ -1;
currTimeAs(TimeAsNanSecs, &start);
@@ -2243,7 +2482,7 @@
{
{
SM_ROW( NATI_STATE_NULL, NATI_TRIG_NULL, _smUndef ),
- SM_ROW( NATI_STATE_NULL, NATI_TRIG_ADD_TABLE, _smUndef ),
+ SM_ROW( NATI_STATE_NULL, NATI_TRIG_ADD_TABLE, _smFirstTbl ),
SM_ROW( NATI_STATE_NULL, NATI_TRIG_DEL_TABLE, _smUndef ),
SM_ROW( NATI_STATE_NULL, NATI_TRIG_CLR_TABLE, _smUndef ),
SM_ROW( NATI_STATE_NULL, NATI_TRIG_WLK_TABLE, _smUndef ),
@@ -2259,7 +2498,7 @@
{
SM_ROW( NATI_STATE_DDR_ONLY, NATI_TRIG_NULL, _smUndef ),
- SM_ROW( NATI_STATE_DDR_ONLY, NATI_TRIG_ADD_TABLE, _smAddDdrTbl),
+ SM_ROW( NATI_STATE_DDR_ONLY, NATI_TRIG_ADD_TABLE, _smAddDdrTbl ),
SM_ROW( NATI_STATE_DDR_ONLY, NATI_TRIG_DEL_TABLE, _smDelTbl ),
SM_ROW( NATI_STATE_DDR_ONLY, NATI_TRIG_CLR_TABLE, _smClrTbl ),
SM_ROW( NATI_STATE_DDR_ONLY, NATI_TRIG_WLK_TABLE, _smWalkTbl ),
@@ -2275,7 +2514,7 @@
{
SM_ROW( NATI_STATE_SRAM_ONLY, NATI_TRIG_NULL, _smUndef ),
- SM_ROW( NATI_STATE_SRAM_ONLY, NATI_TRIG_ADD_TABLE, _smAddSramTbl),
+ SM_ROW( NATI_STATE_SRAM_ONLY, NATI_TRIG_ADD_TABLE, _smAddSramTbl ),
SM_ROW( NATI_STATE_SRAM_ONLY, NATI_TRIG_DEL_TABLE, _smDelTbl ),
SM_ROW( NATI_STATE_SRAM_ONLY, NATI_TRIG_CLR_TABLE, _smClrTbl ),
SM_ROW( NATI_STATE_SRAM_ONLY, NATI_TRIG_WLK_TABLE, _smWalkTbl ),
@@ -2415,20 +2654,10 @@
IPADBG("In\n");
- if ( ! nat_mutex_init )
- {
- ret = mutex_init();
+ ret = take_mutex();
- if ( ret != 0 )
- {
- goto bail;
- }
- }
-
- if ( pthread_mutex_lock(&nat_mutex) )
+ if ( ret != 0 )
{
- IPAERR("Unable to lock the nat mutex\n");
- ret = -EINVAL;
goto bail;
}
@@ -2464,11 +2693,7 @@
}
unlock:
- if ( pthread_mutex_unlock(&nat_mutex) )
- {
- IPAERR("Unable to unlock the nat mutex\n");
- ret = (ret) ? ret : -EPERM;
- }
+ ret = give_mutex();
bail:
IPADBG("Out\n");