IPACM: move NAT table on request from modem
On request from modem move NAT table to DDR only
or back to hybrid mode. send QMI indication when
transition has finished.
Change-Id: Ib2c0529a477d97155fc011f3618d3857832090c2
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 1c41dfa..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>
@@ -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/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_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;