summaryrefslogtreecommitdiff
path: root/ipanat
diff options
context:
space:
mode:
authorUtkarsh Saxena <usaxena@codeaurora.org>2016-08-22 23:10:42 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2016-09-05 22:23:30 -0700
commite4aebe9d4c98463d485ef224d8f9a32d25c36830 (patch)
tree1c1736d91cf2908e742d48852466b2f99d3e88bd /ipanat
parent7b7d16a11a6777b0ade69b6dc8fb33915ec03d67 (diff)
downloadipacfg-mgr-e4aebe9d4c98463d485ef224d8f9a32d25c36830.tar.gz
ipacm: Fix race condition between nat delete and update timestamp
NAT delete functionality and Update timestamp can run in two separate threads in parallel. Add pthread mutex lock around this two functions to avoid race condition while accessing the NAT table memory. Change-Id: I6d40ae6dbe3aa9ed840c2daae8555701baa91ef2
Diffstat (limited to 'ipanat')
-rw-r--r--ipanat/inc/ipa_nat_drvi.h1
-rw-r--r--ipanat/src/ipa_nat_drvi.c52
2 files changed, 47 insertions, 6 deletions
diff --git a/ipanat/inc/ipa_nat_drvi.h b/ipanat/inc/ipa_nat_drvi.h
index 002c025..6f9b1bd 100644
--- a/ipanat/inc/ipa_nat_drvi.h
+++ b/ipanat/inc/ipa_nat_drvi.h
@@ -39,6 +39,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <netinet/in.h>
#include <sys/inotify.h>
#include <errno.h>
+#include <pthread.h>
#include "ipa_nat_logi.h"
diff --git a/ipanat/src/ipa_nat_drvi.c b/ipanat/src/ipa_nat_drvi.c
index cfda3e3..faa8c8c 100644
--- a/ipanat/src/ipa_nat_drvi.c
+++ b/ipanat/src/ipa_nat_drvi.c
@@ -36,6 +36,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
struct ipa_nat_cache ipv4_nat_cache;
+pthread_mutex_t nat_mutex = PTHREAD_MUTEX_INITIALIZER;
/* ------------------------------------------
UTILITY FUNCTIONS START
@@ -904,7 +905,13 @@ int ipa_nati_del_ipv4_table(uint32_t tbl_hdl)
if (!ipv4_nat_cache.ip4_tbl[index].valid) {
IPAERR("invalid table handle passed\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (pthread_mutex_lock(&nat_mutex) != 0) {
+ ret = -1;
+ goto lock_mutex_fail;
}
/* unmap the device memory from user space */
@@ -918,7 +925,10 @@ int ipa_nati_del_ipv4_table(uint32_t tbl_hdl)
/* close the file descriptor of nat device */
if (close(ipv4_nat_cache.ip4_tbl[index].nat_fd)) {
IPAERR("unable to close the file descriptor\n");
- return -EINVAL;
+ ret = -EINVAL;
+ if (pthread_mutex_unlock(&nat_mutex) != 0)
+ goto unlock_mutex_fail;
+ goto fail;
}
del_cmd.table_index = index;
@@ -928,9 +938,12 @@ int ipa_nati_del_ipv4_table(uint32_t tbl_hdl)
perror("ipa_nati_del_ipv4_table(): ioctl error value");
IPAERR("unable to post nat del command init Error: %d\n", ret);
IPADBG("ipa fd %d\n", ipv4_nat_cache.ipa_fd);
- return -EINVAL;
+ ret = -EINVAL;
+ if (pthread_mutex_unlock(&nat_mutex) != 0)
+ goto unlock_mutex_fail;
+ goto fail;
}
- IPADBG("posted IPA_IOC_V4_DEL_NAT to kernel successfully\n");
+ IPAERR("posted IPA_IOC_V4_DEL_NAT to kernel successfully\n");
free(ipv4_nat_cache.ip4_tbl[index].index_expn_table_meta);
free(ipv4_nat_cache.ip4_tbl[index].rule_id_array);
@@ -942,7 +955,22 @@ int ipa_nati_del_ipv4_table(uint32_t tbl_hdl)
/* Decrease the table count by 1*/
ipv4_nat_cache.table_cnt--;
+ if (pthread_mutex_unlock(&nat_mutex) != 0) {
+ ret = -1;
+ goto unlock_mutex_fail;
+ }
+
return 0;
+
+lock_mutex_fail:
+ IPAERR("unable to lock the nat mutex\n");
+ return ret;
+
+unlock_mutex_fail:
+ IPAERR("unable to unlock the nat mutex\n");
+
+fail:
+ return ret;
}
int ipa_nati_query_timestamp(uint32_t tbl_hdl,
@@ -959,6 +987,11 @@ int ipa_nati_query_timestamp(uint32_t tbl_hdl,
return -EINVAL;
}
+ if (pthread_mutex_lock(&nat_mutex) != 0) {
+ IPAERR("unable to lock the nat mutex\n");
+ return -1;
+ }
+
ipa_nati_parse_ipv4_rule_hdl(tbl_index, (uint16_t)rule_hdl,
&expn_tbl, &tbl_entry);
@@ -969,8 +1002,15 @@ int ipa_nati_query_timestamp(uint32_t tbl_hdl,
(struct ipa_nat_rule *)ipv4_nat_cache.ip4_tbl[tbl_index].ipv4_expn_rules_addr;
}
- *time_stamp = Read32BitFieldValue(tbl_ptr[tbl_entry].ts_proto,
- TIME_STAMP_FIELD);
+ if (tbl_ptr)
+ *time_stamp = Read32BitFieldValue(tbl_ptr[tbl_entry].ts_proto,
+ TIME_STAMP_FIELD);
+
+ if (pthread_mutex_unlock(&nat_mutex) != 0) {
+ IPAERR("unable to unlock the nat mutex\n");
+ return -1;
+ }
+
return 0;
}