summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChaitanya Pratapa <cpratapa@codeaurora.org>2020-09-08 23:20:38 -0700
committerChaitanya Pratapa <cpratapa@codeaurora.org>2020-09-10 10:08:42 -0700
commit72332e735e791817d73252b9464a88bfb45a6af8 (patch)
tree8fbce34b73468868de0e227d4a2e433a8afe23dc
parentbcdbbcfa0bb1fed621ad997e8e6cfaa2e5f1b50a (diff)
downloadipacfg-mgr-72332e735e791817d73252b9464a88bfb45a6af8.tar.gz
ipacm: Fix reading the conntrack dump
Framework uses UDP fd to query for the conntrack dump. Make changes to use UDP fd to read the conntrack dump. Also read using the fd provided from framework and not using dup fd. Change-Id: Iaeecfc0c4763325314d8f763797bd1fc7124e4db
-rw-r--r--ipacm/inc/IPACM_ConntrackListener.h2
-rw-r--r--ipacm/src/IPACM_ConntrackClient.cpp11
-rw-r--r--ipacm/src/IPACM_ConntrackListener.cpp99
-rw-r--r--ipacm/src/IPACM_OffloadManager.cpp24
4 files changed, 75 insertions, 61 deletions
diff --git a/ipacm/inc/IPACM_ConntrackListener.h b/ipacm/inc/IPACM_ConntrackListener.h
index 6cc4188..7831498 100644
--- a/ipacm/inc/IPACM_ConntrackListener.h
+++ b/ipacm/inc/IPACM_ConntrackListener.h
@@ -119,7 +119,7 @@ public:
void HandleSTAClientAddEvt(uint32_t);
void HandleSTAClientDelEvt(uint32_t);
int CreateConnTrackThreads(void);
- void readConntrack(void);
+ void readConntrack(int fd);
void processConntrack(void);
};
diff --git a/ipacm/src/IPACM_ConntrackClient.cpp b/ipacm/src/IPACM_ConntrackClient.cpp
index dabd8e6..f6bc9a6 100644
--- a/ipacm/src/IPACM_ConntrackClient.cpp
+++ b/ipacm/src/IPACM_ConntrackClient.cpp
@@ -421,17 +421,6 @@ void* IPACM_ConntrackClient::TCPRegisterWithConnTrack(void *)
unsigned subscrips = 0;
IPACMDBG("\n");
- /* In Android we get conntrack handles once after tethering is enabled but we
- loose connections info for embedded traffic if running before. So no NAT
- entries are added for embedded traffic due to which we see NAT exception and
- data takes S/W path which results in less throughput. Hence for embedded
- traffic info, framework sends conntrack dump before providing handles. Here
- reading ct entries before creating filter on Fd in order to have NAT entries
- for both TCP/UDP embedded traffic. */
- if(CtList != NULL && !CtList->isReadCTDone)
- {
- CtList->readConntrack();
- }
pClient = IPACM_ConntrackClient::GetInstance();
if(pClient == NULL)
diff --git a/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp
index baddb4d..9d06442 100644
--- a/ipacm/src/IPACM_ConntrackListener.cpp
+++ b/ipacm/src/IPACM_ConntrackListener.cpp
@@ -1219,25 +1219,26 @@ bool isLocalHostAddr(uint32_t src_ip_addr, uint32_t dst_ip_addr) {
return false;
}
-void IPACM_ConntrackListener::readConntrack() {
+void IPACM_ConntrackListener::readConntrack(int fd) {
- IPACM_ConntrackClient *pClient;
- int len_fil = 0, recv_bytes = -1, index = 0, len =0;
+ int recv_bytes = -1, index = 0, len =0;
char buffer[CT_ENTRIES_BUFFER_SIZE];
- char *buf = &buffer[0];
struct nf_conntrack *ct;
struct nlmsghdr *nl_header;
- static struct sockaddr_nl nlAddr = {
- .nl_family = AF_NETLINK
+ struct iovec iov = {
+ .iov_base = buffer,
+ .iov_len = CT_ENTRIES_BUFFER_SIZE,
+ };
+ struct sockaddr_nl addr;
+ struct msghdr msg = {
+ .msg_name = &addr,
+ .msg_namelen = sizeof(struct sockaddr_nl),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = NULL,
+ .msg_controllen = 0,
+ .msg_flags = 0,
};
- unsigned int addr_len = sizeof(nlAddr);
-
- pClient = IPACM_ConntrackClient::GetInstance();
- if(pClient == NULL)
- {
- IPACMERR("unable to get conntrack client instance\n");
- return;
- }
len = MAX_CONNTRACK_ENTRIES * sizeof(struct nf_conntrack **);
@@ -1249,17 +1250,18 @@ void IPACM_ConntrackListener::readConntrack() {
}
memset(ct_entries, 0, len);
- if( pClient->fd_tcp < 0)
+ if( fd < 0)
{
- IPACMDBG_H("Invalid fd %d \n",pClient->fd_tcp);
+ IPACMDBG_H("Invalid fd %d \n",fd);
free(ct_entries);
return;
}
-
IPACMDBG_H("receiving conntrack entries started.\n");
- while(len_fil < sizeof(buffer) && index < MAX_CONNTRACK_ENTRIES)
+ len = CT_ENTRIES_BUFFER_SIZE;
+ while (len > 0)
{
- recv_bytes = recvfrom( pClient->fd_tcp, buf, sizeof(buffer)-len_fil, 0, (struct sockaddr *)&nlAddr, (socklen_t *)&addr_len);
+ memset(buffer, 0, CT_ENTRIES_BUFFER_SIZE);
+ recv_bytes = recvmsg(fd, &msg, 0);
if(recv_bytes < 0)
{
IPACMDBG_H("error in receiving conntrack entries %d%s",errno, strerror(errno));
@@ -1267,42 +1269,45 @@ void IPACM_ConntrackListener::readConntrack() {
}
else
{
- nl_header = (struct nlmsghdr *)buf;
-
- if (NLMSG_OK(nl_header, recv_bytes) == 0 || nl_header->nlmsg_type == NLMSG_ERROR)
+ len -= recv_bytes;
+ nl_header = (struct nlmsghdr *)buffer;
+ IPACMDBG_H("Number of bytes:%d to parse\n", recv_bytes);
+ while(NLMSG_OK(nl_header, recv_bytes) && (index < MAX_CONNTRACK_ENTRIES))
{
- IPACMDBG_H("recv_bytes is %d\n",recv_bytes);
- break;
- }
- ct = nfct_new();
- if (ct != NULL)
- {
- int parseResult = nfct_parse_conntrack((nf_conntrack_msg_type) NFCT_T_ALL,nl_header, ct);
- if(parseResult != NFCT_T_ERROR)
+ if (nl_header->nlmsg_type == NLMSG_ERROR)
+ {
+ IPACMDBG_H("Error, recv_bytes is %d\n",recv_bytes);
+ break;
+ }
+ ct = nfct_new();
+ if (ct != NULL)
{
- ct_entries[index++] = ct;
+ int parseResult = nfct_parse_conntrack((nf_conntrack_msg_type) NFCT_T_ALL,nl_header, ct);
+ if(parseResult != NFCT_T_ERROR)
+ {
+ ct_entries[index++] = ct;
+ }
+ else
+ {
+ IPACMDBG_H("error in parsing %d%s \n", errno, strerror(errno));
+ }
}
else
{
- IPACMDBG_H("error in parsing %d%s \n", errno, strerror(errno));
+ IPACMDBG_H("ct allocation failed");
}
+ if (nl_header->nlmsg_type == NLMSG_DONE)
+ {
+ IPACMDBG_H("Message is done.\n");
+ break;
+ }
+ nl_header = NLMSG_NEXT(nl_header, recv_bytes);
}
- else
- {
- IPACMDBG_H("ct allocation failed");
- continue;
- }
-
- if((nl_header->nlmsg_type & NLM_F_MULTI) == 0)
- {
- break;
- }
- len_fil += recv_bytes;
- buf = buf + recv_bytes;
}
}
+
isReadCTDone = true;
- IPACMDBG_H("receiving conntrack entries ended.\n");
+ IPACMDBG_H("receiving conntrack entries ended. No of entries: %d\n", index);
if(isWanUp() && !isProcessCTDone)
{
IPACMDBG_H("wan is up, process ct entries \n");
@@ -1324,7 +1329,7 @@ void IPACM_ConntrackListener::processConntrack() {
while(ct_entries[index] != NULL)
{
ip_type = nfct_get_attr_u8(ct_entries[index], ATTR_REPL_L3PROTO);
- if(!(AF_INET6 == ip_type) && isLocalHostAddr(nfct_get_attr_u32(ct_entries[index], ATTR_ORIG_IPV4_SRC),
+ if((AF_INET == ip_type) && isLocalHostAddr(nfct_get_attr_u32(ct_entries[index], ATTR_ORIG_IPV4_SRC),
nfct_get_attr_u32(ct_entries[index], ATTR_ORIG_IPV4_DST)))
{
IPACMDBG_H(" loopback entry \n");
@@ -1372,6 +1377,6 @@ IGNORE:
}
isProcessCTDone = true;
free(ct_entries);
- IPACMDBG_H("process conntrack ended \n");
+ IPACMDBG_H("process conntrack ended. Number of entries:%d \n", index);
return;
}
diff --git a/ipacm/src/IPACM_OffloadManager.cpp b/ipacm/src/IPACM_OffloadManager.cpp
index 7919413..b5afda7 100644
--- a/ipacm/src/IPACM_OffloadManager.cpp
+++ b/ipacm/src/IPACM_OffloadManager.cpp
@@ -120,6 +120,7 @@ RET IPACM_OffloadManager::unregisterCtTimeoutUpdater(ConntrackTimeoutUpdater* )
RET IPACM_OffloadManager::provideFd(int fd, unsigned int groups)
{
+ struct timeval tv;
IPACM_ConntrackClient *cc;
int on = 1, rel;
struct sockaddr_nl local;
@@ -158,11 +159,30 @@ RET IPACM_OffloadManager::provideFd(int fd, unsigned int groups)
cc->fd_udp = dup(fd);
IPACMDBG_H("Received fd %d with groups %d.\n", fd, groups);
/* set netlink buf */
- rel = setsockopt(cc->fd_tcp, SOL_NETLINK, NETLINK_NO_ENOBUFS, &on, sizeof(int) );
+ rel = setsockopt(cc->fd_udp, SOL_NETLINK, NETLINK_NO_ENOBUFS, &on, sizeof(int) );
if (rel == -1)
{
- IPACMERR( "setsockopt returned error code %d ( %s )", errno, strerror( errno ) );
+ IPACMERR("setsockopt returned error code %d ( %s )\n", errno, strerror(errno));
}
+
+ /* Set receive timeout to 1s on the FD which is used to read conntrack dump. */
+ memset(&tv,0, sizeof(struct timeval));
+ tv.tv_sec = 1; /* 1s timeout */
+ rel = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&tv,sizeof(struct timeval));
+ if (rel == -1)
+ {
+ IPACMERR("setsockopt returned error code %d ( %s )\n", errno, strerror(errno));
+ }
+
+ /* In Android we get conntrack handles once after tethering is enabled but we
+ loose connections info for embedded traffic if running before. So no NAT
+ entries are added for embedded traffic due to which we see NAT exception and
+ data takes S/W path which results in less throughput. Hence for embedded
+ traffic info, framework sends conntrack dump before providing handles. Here
+ reading ct entries before creating filter on Fd in order to have NAT entries
+ for both TCP/UDP embedded traffic.
+ */
+ CtList->readConntrack(fd);
} else {
IPACMERR("Received unexpected fd with groups %d.\n", groups);
}