1 /*
2 Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 		* Redistributions of source code must retain the above copyright
8 			notice, this list of conditions and the following disclaimer.
9 		* Redistributions in binary form must reproduce the above
10 			copyright notice, this list of conditions and the following
11 			disclaimer in the documentation and/or other materials provided
12 			with the distribution.
13 		* Neither the name of The Linux Foundation nor the names of its
14 			contributors may be used to endorse or promote products derived
15 			from this software without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 #include "IPACM_Conntrack_NATApp.h"
30 #include "IPACM_ConntrackClient.h"
31 #ifdef FEATURE_IPACM_HAL
32 #include "IPACM_OffloadManager.h"
33 #endif
34 #include "IPACM_Iface.h"
35 
36 #define INVALID_IP_ADDR 0x0
37 
38 #define HDR_METADATA_MUX_ID_BMASK 0x00FF0000
39 #define HDR_METADATA_MUX_ID_SHFT 0x10
40 
41 /* NatApp class Implementation */
42 NatApp *NatApp::pInstance = NULL;
NatApp()43 NatApp::NatApp()
44 {
45 	max_entries = 0;
46 	cache = NULL;
47 
48 	nat_table_hdl = 0;
49 	pub_ip_addr = 0;
50 
51 	curCnt = 0;
52 
53 	pALGPorts = NULL;
54 	nALGPort = 0;
55 
56 	ct = NULL;
57 	ct_hdl = NULL;
58 
59 	memset(temp, 0, sizeof(temp));
60 }
61 
Init(void)62 int NatApp::Init(void)
63 {
64 	IPACM_Config *pConfig;
65 	int size = 0;
66 
67 	pConfig = IPACM_Config::GetInstance();
68 	if(pConfig == NULL)
69 	{
70 		IPACMERR("Unable to get Config instance\n");
71 		return -1;
72 	}
73 
74 	max_entries = pConfig->GetNatMaxEntries();
75 
76 	size = (sizeof(nat_table_entry) * max_entries);
77 	cache = (nat_table_entry *)malloc(size);
78 	if(cache == NULL)
79 	{
80 		IPACMERR("Unable to allocate memory for cache\n");
81 		goto fail;
82 	}
83 	IPACMDBG("Allocated %d bytes for config manager nat cache\n", size);
84 	memset(cache, 0, size);
85 
86 	nALGPort = pConfig->GetAlgPortCnt();
87 	if(nALGPort > 0)
88 	{
89 		pALGPorts = (ipacm_alg *)malloc(sizeof(ipacm_alg) * nALGPort);
90 		if(pALGPorts == NULL)
91 		{
92 			IPACMERR("Unable to allocate memory for alg prots\n");
93 			goto fail;
94 		}
95 		memset(pALGPorts, 0, sizeof(ipacm_alg) * nALGPort);
96 
97 		pConfig->GetAlgPorts(nALGPort, pALGPorts);
98 
99 		IPACMDBG("Printing %d alg ports information\n", nALGPort);
100 		for(int cnt=0; cnt<nALGPort; cnt++)
101 		{
102 			IPACMDBG("%d: Proto[%d], port[%d]\n", cnt, pALGPorts[cnt].protocol, pALGPorts[cnt].port);
103 		}
104 	}
105 	else
106 	{
107 		IPACMERR("Unable to retrieve ALG prot count\n");
108 		goto fail;
109 	}
110 
111 	return 0;
112 
113 fail:
114 	if(cache != NULL)
115 	{
116 		free(cache);
117 	}
118 	if(pALGPorts != NULL)
119 	{
120 		free(pALGPorts);
121 	}
122 	return -1;
123 }
124 
GetInstance()125 NatApp* NatApp::GetInstance()
126 {
127 	if(pInstance == NULL)
128 	{
129 		pInstance = new NatApp();
130 
131 		if(pInstance->Init())
132 		{
133 			delete pInstance;
134 			return NULL;
135 		}
136 	}
137 
138 	return pInstance;
139 }
140 
GenerateMetdata(uint8_t mux_id)141 uint32_t NatApp::GenerateMetdata(uint8_t mux_id)
142 {
143 	return (mux_id << HDR_METADATA_MUX_ID_SHFT) & HDR_METADATA_MUX_ID_BMASK;
144 }
145 
146 /* NAT APP related object function definitions */
147 
AddTable(uint32_t pub_ip,uint8_t mux_id)148 int NatApp::AddTable(uint32_t pub_ip, uint8_t mux_id)
149 {
150 	int ret;
151 	int cnt = 0;
152 	ipa_nat_ipv4_rule nat_rule;
153 	IPACMDBG_H("%s() %d\n", __FUNCTION__, __LINE__);
154 
155 	/* Not reset the cache wait it timeout by destroy event */
156 #if 0
157 	if (pub_ip != pub_ip_addr_pre)
158 	{
159 		IPACMDBG("Reset the cache because NAT-ipv4 different\n");
160 		memset(cache, 0, sizeof(nat_table_entry) * max_entries);
161 		curCnt = 0;
162 	}
163 #endif
164 	ret = ipa_nat_add_ipv4_tbl(pub_ip, max_entries, &nat_table_hdl);
165 	if(ret)
166 	{
167 		IPACMERR("unable to create nat table Error:%d\n", ret);
168 		return ret;
169 	}
170 	if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_v4_0) {
171 		/* modify PDN 0 so it will hold the mux ID in the src metadata field */
172 		ipa_nat_pdn_entry entry;
173 
174 		entry.dst_metadata = 0;
175 		entry.src_metadata = GenerateMetdata(mux_id);
176 		entry.public_ip = pub_ip;
177 		ret = ipa_nat_modify_pdn(nat_table_hdl, 0, &entry);
178 		if(ret)
179 		{
180 			IPACMERR("unable to modify PDN 0 entry Error:%d INIT_HDR_METADATA register values will be used!\n", ret);
181 		}
182 	}
183 
184 	/* Add back the cached NAT-entry */
185 	if (pub_ip == pub_ip_addr_pre)
186 	{
187 		IPACMDBG("Restore the cache to ipa NAT-table\n");
188 		for(cnt = 0; cnt < max_entries; cnt++)
189 		{
190 			if(cache[cnt].private_ip !=0)
191 			{
192 				memset(&nat_rule, 0 , sizeof(nat_rule));
193 				nat_rule.private_ip = cache[cnt].private_ip;
194 				nat_rule.target_ip = cache[cnt].target_ip;
195 				nat_rule.target_port = cache[cnt].target_port;
196 				nat_rule.private_port = cache[cnt].private_port;
197 				nat_rule.public_port = cache[cnt].public_port;
198 				nat_rule.protocol = cache[cnt].protocol;
199 
200 				if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0)
201 				{
202 					IPACMERR("unable to add the rule delete from cache\n");
203 					memset(&cache[cnt], 0, sizeof(cache[cnt]));
204 					curCnt--;
205 					continue;
206 				}
207 				cache[cnt].enabled = true;
208 
209 				IPACMDBG("On wan-iface reset added below rule successfully\n");
210 				iptodot("Private IP", nat_rule.private_ip);
211 				iptodot("Target IP", nat_rule.target_ip);
212 				IPACMDBG("Private Port:%d \t Target Port: %d\t", nat_rule.private_port, nat_rule.target_port);
213 				IPACMDBG("Public Port:%d\n", nat_rule.public_port);
214 				IPACMDBG("protocol: %d\n", nat_rule.protocol);
215 			}
216 		}
217 	}
218 
219 	pub_ip_addr = pub_ip;
220 	return 0;
221 }
222 
Reset()223 void NatApp::Reset()
224 {
225 	int cnt = 0;
226 
227 	nat_table_hdl = 0;
228 	pub_ip_addr = 0;
229 	/* NAT tbl deleted, reset enabled bit */
230 	for(cnt = 0; cnt < max_entries; cnt++)
231 	{
232 		cache[cnt].enabled = false;
233 	}
234 }
235 
DeleteTable(uint32_t pub_ip)236 int NatApp::DeleteTable(uint32_t pub_ip)
237 {
238 	int ret;
239 	IPACMDBG_H("%s() %d\n", __FUNCTION__, __LINE__);
240 
241 	CHK_TBL_HDL();
242 
243 	if(pub_ip_addr != pub_ip)
244 	{
245 		IPACMDBG("Public ip address is not matching\n");
246 		IPACMERR("unable to delete the nat table\n");
247 		return -1;
248 	}
249 
250 	ret = ipa_nat_del_ipv4_tbl(nat_table_hdl);
251 	if(ret)
252 	{
253 		IPACMERR("unable to delete nat table Error: %d\n", ret);;
254 		return ret;
255 	}
256 
257 	pub_ip_addr_pre = pub_ip_addr;
258 	Reset();
259 	return 0;
260 }
261 
262 /* Check for duplicate entries */
ChkForDup(const nat_table_entry * rule)263 bool NatApp::ChkForDup(const nat_table_entry *rule)
264 {
265 	int cnt = 0;
266 	IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
267 
268 	for(; cnt < max_entries; cnt++)
269 	{
270 		if(cache[cnt].private_ip == rule->private_ip &&
271 			 cache[cnt].target_ip == rule->target_ip &&
272 			 cache[cnt].private_port ==  rule->private_port  &&
273 			 cache[cnt].target_port == rule->target_port &&
274 			 cache[cnt].protocol == rule->protocol)
275 		{
276 			log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
277 			rule->target_port,"Duplicate Rule\n");
278 			return true;
279 		}
280 	}
281 
282 	return false;
283 }
284 
285 /* Delete the entry from Nat table on connection close */
DeleteEntry(const nat_table_entry * rule)286 int NatApp::DeleteEntry(const nat_table_entry *rule)
287 {
288 	int cnt = 0;
289 	IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
290 
291 	log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
292 	rule->target_port,"for deletion\n");
293 
294 
295 	for(; cnt < max_entries; cnt++)
296 	{
297 		if(cache[cnt].private_ip == rule->private_ip &&
298 			 cache[cnt].target_ip == rule->target_ip &&
299 			 cache[cnt].private_port ==  rule->private_port  &&
300 			 cache[cnt].target_port == rule->target_port &&
301 			 cache[cnt].protocol == rule->protocol)
302 		{
303 
304 			if(cache[cnt].enabled == true)
305 			{
306 				if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
307 				{
308 					IPACMERR("%s() %d deletion failed\n", __FUNCTION__, __LINE__);
309 				}
310 
311 				IPACMDBG_H("Deleted Nat entry(%d) Successfully\n", cnt);
312 			}
313 			else
314 			{
315 				IPACMDBG_H("Deleted Nat entry(%d) only from cache\n", cnt);
316 			}
317 
318 			memset(&cache[cnt], 0, sizeof(cache[cnt]));
319 			curCnt--;
320 			break;
321 		}
322 	}
323 
324 	return 0;
325 }
326 
327 /* Add new entry to the nat table on new connection */
AddEntry(const nat_table_entry * rule)328 int NatApp::AddEntry(const nat_table_entry *rule)
329 {
330 	int cnt = 0;
331 	ipa_nat_ipv4_rule nat_rule;
332 
333 	IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
334 
335 	CHK_TBL_HDL();
336 	log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
337 	rule->target_port,"for addition\n");
338 	if(isAlgPort(rule->protocol, rule->private_port) ||
339 		 isAlgPort(rule->protocol, rule->target_port))
340 	{
341 		IPACMERR("connection using ALG Port, ignore\n");
342 		return -1;
343 	}
344 
345 	if(rule->private_ip == 0 ||
346 		 rule->target_ip == 0 ||
347 		 rule->private_port == 0  ||
348 		 rule->target_port == 0 ||
349 		 rule->protocol == 0)
350 	{
351 		IPACMERR("Invalid Connection, ignoring it\n");
352 		return 0;
353 	}
354 
355 	if(!ChkForDup(rule))
356 	{
357 		for(; cnt < max_entries; cnt++)
358 		{
359 			if(cache[cnt].private_ip == 0 &&
360 				 cache[cnt].target_ip == 0 &&
361 				 cache[cnt].private_port == 0  &&
362 				 cache[cnt].target_port == 0 &&
363 				 cache[cnt].protocol == 0)
364 			{
365 				break;
366 			}
367 		}
368 
369 		if(max_entries == cnt)
370 		{
371 			IPACMERR("Error: Unable to add, reached maximum rules\n");
372 			return -1;
373 		}
374 		else
375 		{
376 			memset(&nat_rule, 0, sizeof(nat_rule));
377 			nat_rule.private_ip = rule->private_ip;
378 			nat_rule.target_ip = rule->target_ip;
379 			nat_rule.target_port = rule->target_port;
380 			nat_rule.private_port = rule->private_port;
381 			nat_rule.public_port = rule->public_port;
382 			nat_rule.protocol = rule->protocol;
383 
384 			if(isPwrSaveIf(rule->private_ip) ||
385 				 isPwrSaveIf(rule->target_ip))
386 			{
387 				IPACMDBG("Device is Power Save mode: Dont insert into nat table but cache\n");
388 				cache[cnt].enabled = false;
389 				cache[cnt].rule_hdl = 0;
390 			}
391 			else
392 			{
393 
394 				if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0)
395 				{
396 					IPACMERR("unable to add the rule\n");
397 					return -1;
398 				}
399 
400 				cache[cnt].enabled = true;
401 			}
402 
403 			cache[cnt].private_ip = rule->private_ip;
404 			cache[cnt].target_ip = rule->target_ip;
405 			cache[cnt].target_port = rule->target_port;
406 			cache[cnt].private_port = rule->private_port;
407 			cache[cnt].protocol = rule->protocol;
408 			cache[cnt].timestamp = 0;
409 			cache[cnt].public_port = rule->public_port;
410 			cache[cnt].dst_nat = rule->dst_nat;
411 			curCnt++;
412 		}
413 
414 	}
415 	else
416 	{
417 		IPACMERR("Duplicate rule. Ignore it\n");
418 		return -1;
419 	}
420 
421 	if(cache[cnt].enabled == true)
422 	{
423 		IPACMDBG_H("Added rule(%d) successfully\n", cnt);
424 	}
425   else
426   {
427     IPACMDBG_H("Cached rule(%d) successfully\n", cnt);
428   }
429 
430 	return 0;
431 }
432 
UpdateCTUdpTs(nat_table_entry * rule,uint32_t new_ts)433 void NatApp::UpdateCTUdpTs(nat_table_entry *rule, uint32_t new_ts)
434 {
435 #ifdef FEATURE_IPACM_HAL
436 	IOffloadManager::ConntrackTimeoutUpdater::natTimeoutUpdate_t entry;
437 	IPACM_OffloadManager* OffloadMng;
438 #endif
439 	iptodot("Private IP:", rule->private_ip);
440 	iptodot("Target IP:",  rule->target_ip);
441 	IPACMDBG("Private Port: %d, Target Port: %d\n", rule->private_port, rule->target_port);
442 
443 #ifndef FEATURE_IPACM_HAL
444 	int ret;
445 	if(!ct_hdl)
446 	{
447 		ct_hdl = nfct_open(CONNTRACK, 0);
448 		if(!ct_hdl)
449 		{
450 			PERROR("nfct_open");
451 			return;
452 		}
453 	}
454 
455 	if(!ct)
456 	{
457 		ct = nfct_new();
458 		if(!ct)
459 		{
460 			PERROR("nfct_new");
461 			return;
462 		}
463 	}
464 
465 	nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET);
466 	if(rule->protocol == IPPROTO_UDP)
467 	{
468 		nfct_set_attr_u8(ct, ATTR_L4PROTO, rule->protocol);
469 		nfct_set_attr_u32(ct, ATTR_TIMEOUT, udp_timeout);
470 	}
471 	else
472 	{
473 		nfct_set_attr_u8(ct, ATTR_L4PROTO, rule->protocol);
474 		nfct_set_attr_u32(ct, ATTR_TIMEOUT, tcp_timeout);
475 	}
476 
477 	if(rule->dst_nat == false)
478 	{
479 		nfct_set_attr_u32(ct, ATTR_IPV4_SRC, htonl(rule->private_ip));
480 		nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(rule->private_port));
481 
482 		nfct_set_attr_u32(ct, ATTR_IPV4_DST, htonl(rule->target_ip));
483 		nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(rule->target_port));
484 
485 		IPACMDBG("dst nat is not set\n");
486 	}
487 	else
488 	{
489 		nfct_set_attr_u32(ct, ATTR_IPV4_SRC, htonl(rule->target_ip));
490 		nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(rule->target_port));
491 
492 		nfct_set_attr_u32(ct, ATTR_IPV4_DST, htonl(pub_ip_addr));
493 		nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(rule->public_port));
494 
495 		IPACMDBG("dst nat is set\n");
496 	}
497 
498 	iptodot("Source IP:", nfct_get_attr_u32(ct, ATTR_IPV4_SRC));
499 	iptodot("Destination IP:",  nfct_get_attr_u32(ct, ATTR_IPV4_DST));
500 	IPACMDBG("Source Port: %d, Destination Port: %d\n",
501 					 nfct_get_attr_u16(ct, ATTR_PORT_SRC), nfct_get_attr_u16(ct, ATTR_PORT_DST));
502 
503 	IPACMDBG("updating %d connection with time: %d\n",
504 					 rule->protocol, nfct_get_attr_u32(ct, ATTR_TIMEOUT));
505 
506 	ret = nfct_query(ct_hdl, NFCT_Q_UPDATE, ct);
507 	if(ret == -1)
508 	{
509 		IPACMERR("unable to update time stamp");
510 		DeleteEntry(rule);
511 	}
512 	else
513 	{
514 		rule->timestamp = new_ts;
515 		IPACMDBG("Updated time stamp successfully\n");
516 	}
517 #else
518 	if(rule->protocol == IPPROTO_UDP)
519 	{
520 		entry.proto = IOffloadManager::ConntrackTimeoutUpdater::UDP;;
521 	}
522 	else
523 	{
524 		entry.proto = IOffloadManager::ConntrackTimeoutUpdater::TCP;
525 	}
526 
527 	if(rule->dst_nat == false)
528 	{
529 		entry.src.ipAddr = htonl(rule->private_ip);
530 		entry.src.port = rule->private_port;
531 		entry.dst.ipAddr = htonl(rule->target_ip);
532 		entry.dst.port = rule->target_port;
533 		IPACMDBG("dst nat is not set\n");
534 	}
535 	else
536 	{
537 		entry.src.ipAddr = htonl(rule->target_ip);
538 		entry.src.port = rule->target_port;
539 		entry.dst.ipAddr = htonl(pub_ip_addr);
540 		entry.dst.port = rule->public_port;
541 		IPACMDBG("dst nat is set\n");
542 	}
543 
544 	iptodot("Source IP:", entry.src.ipAddr);
545 	iptodot("Destination IP:",  entry.dst.ipAddr);
546 	IPACMDBG("Source Port: %d, Destination Port: %d\n",
547 					entry.src.port, entry.dst.port);
548 
549 	OffloadMng = IPACM_OffloadManager::GetInstance();
550 	if (OffloadMng->touInstance == NULL) {
551 		IPACMERR("OffloadMng->touInstance is NULL, can't forward to framework!\n");
552 	} else {
553 		OffloadMng->touInstance->updateTimeout(entry);
554 		IPACMDBG("Updated time stamp successfully\n");
555 		rule->timestamp = new_ts;
556 	}
557 #endif
558 	return;
559 }
560 
UpdateUDPTimeStamp()561 void NatApp::UpdateUDPTimeStamp()
562 {
563 	int cnt;
564 	uint32_t ts;
565 	bool read_to = false;
566 
567 	for(cnt = 0; cnt < max_entries; cnt++)
568 	{
569 		ts = 0;
570 		if(cache[cnt].enabled == true &&
571 		   (cache[cnt].private_ip != cache[cnt].public_ip))
572 		{
573 			IPACMDBG("\n");
574 			if(ipa_nat_query_timestamp(nat_table_hdl, cache[cnt].rule_hdl, &ts) < 0)
575 			{
576 				IPACMERR("unable to retrieve timeout for rule hanle: %d\n", cache[cnt].rule_hdl);
577 				continue;
578 			}
579 
580 			if(cache[cnt].timestamp == ts)
581 			{
582 				IPACMDBG("No Change in Time Stamp: cahce:%d, ipahw:%d\n",
583 								                  cache[cnt].timestamp, ts);
584 				continue;
585 			}
586 
587 			if (read_to == false) {
588 				read_to = true;
589 				Read_TcpUdp_Timeout();
590 			}
591 
592 			UpdateCTUdpTs(&cache[cnt], ts);
593 		} /* end of outer if */
594 
595 	} /* end of for loop */
596 
597 }
598 
isAlgPort(uint8_t proto,uint16_t port)599 bool NatApp::isAlgPort(uint8_t proto, uint16_t port)
600 {
601 	int cnt;
602 	for(cnt = 0; cnt < nALGPort; cnt++)
603 	{
604 		if(proto == pALGPorts[cnt].protocol &&
605 			 port == pALGPorts[cnt].port)
606 		{
607 			return true;
608 		}
609 	}
610 
611 	return false;
612 }
613 
isPwrSaveIf(uint32_t ip_addr)614 bool NatApp::isPwrSaveIf(uint32_t ip_addr)
615 {
616 	int cnt;
617 
618 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
619 	{
620 		if(0 != PwrSaveIfs[cnt] &&
621 			 ip_addr == PwrSaveIfs[cnt])
622 		{
623 			return true;
624 		}
625 	}
626 
627 	return false;
628 }
629 
UpdatePwrSaveIf(uint32_t client_lan_ip)630 int NatApp::UpdatePwrSaveIf(uint32_t client_lan_ip)
631 {
632 	int cnt;
633 	IPACMDBG_H("Received IP address: 0x%x\n", client_lan_ip);
634 
635 	if(client_lan_ip == INVALID_IP_ADDR)
636 	{
637 		IPACMERR("Invalid ip address received\n");
638 		return -1;
639 	}
640 
641 	/* check for duplicate events */
642 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
643 	{
644 		if(PwrSaveIfs[cnt] == client_lan_ip)
645 		{
646 			IPACMDBG("The client 0x%x is already in power save\n", client_lan_ip);
647 			return 0;
648 		}
649 	}
650 
651 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
652 	{
653 		if(PwrSaveIfs[cnt] == 0)
654 		{
655 			PwrSaveIfs[cnt] = client_lan_ip;
656 			break;
657 		}
658 	}
659 
660 	for(cnt = 0; cnt < max_entries; cnt++)
661 	{
662 		if(cache[cnt].private_ip == client_lan_ip &&
663 			 cache[cnt].enabled == true)
664 		{
665 			if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
666 			{
667 				IPACMERR("unable to delete the rule\n");
668 				continue;
669 			}
670 
671 			cache[cnt].enabled = false;
672 			cache[cnt].rule_hdl = 0;
673 		}
674 	}
675 
676 	return 0;
677 }
678 
ResetPwrSaveIf(uint32_t client_lan_ip)679 int NatApp::ResetPwrSaveIf(uint32_t client_lan_ip)
680 {
681 	int cnt;
682 	ipa_nat_ipv4_rule nat_rule;
683 
684 	IPACMDBG_H("Received ip address: 0x%x\n", client_lan_ip);
685 
686 	if(client_lan_ip == INVALID_IP_ADDR)
687 	{
688 		IPACMERR("Invalid ip address received\n");
689 		return -1;
690 	}
691 
692 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
693 	{
694 		if(PwrSaveIfs[cnt] == client_lan_ip)
695 		{
696 			PwrSaveIfs[cnt] = 0;
697 			break;
698 		}
699 	}
700 
701 	for(cnt = 0; cnt < max_entries; cnt++)
702 	{
703 		IPACMDBG("cache (%d): enable %d, ip 0x%x\n", cnt, cache[cnt].enabled, cache[cnt].private_ip);
704 
705 		if(cache[cnt].private_ip == client_lan_ip &&
706 			 cache[cnt].enabled == false)
707 		{
708 			memset(&nat_rule, 0 , sizeof(nat_rule));
709 			nat_rule.private_ip = cache[cnt].private_ip;
710 			nat_rule.target_ip = cache[cnt].target_ip;
711 			nat_rule.target_port = cache[cnt].target_port;
712 			nat_rule.private_port = cache[cnt].private_port;
713 			nat_rule.public_port = cache[cnt].public_port;
714 			nat_rule.protocol = cache[cnt].protocol;
715 
716 			if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0)
717 			{
718 				IPACMERR("unable to add the rule delete from cache\n");
719 				memset(&cache[cnt], 0, sizeof(cache[cnt]));
720 				curCnt--;
721 				continue;
722 			}
723 			cache[cnt].enabled = true;
724 
725 			IPACMDBG("On power reset added below rule successfully\n");
726 			iptodot("Private IP", nat_rule.private_ip);
727 			iptodot("Target IP", nat_rule.target_ip);
728 			IPACMDBG("Private Port:%d \t Target Port: %d\t", nat_rule.private_port, nat_rule.target_port);
729 			IPACMDBG("Public Port:%d\n", nat_rule.public_port);
730 			IPACMDBG("protocol: %d\n", nat_rule.protocol);
731 
732 		}
733 	}
734 
735 	return -1;
736 }
737 
GetTableHdl(uint32_t in_ip_addr)738 uint32_t NatApp::GetTableHdl(uint32_t in_ip_addr)
739 {
740 	if(in_ip_addr == pub_ip_addr)
741 	{
742 		return nat_table_hdl;
743 	}
744 
745 	return -1;
746 }
747 
AddTempEntry(const nat_table_entry * new_entry)748 void NatApp::AddTempEntry(const nat_table_entry *new_entry)
749 {
750 	int cnt;
751 
752 	IPACMDBG("Received below Temp Nat entry\n");
753 	iptodot("Private IP", new_entry->private_ip);
754 	iptodot("Target IP", new_entry->target_ip);
755 	IPACMDBG("Private Port: %d\t Target Port: %d\t", new_entry->private_port, new_entry->target_port);
756 	IPACMDBG("protocolcol: %d\n", new_entry->protocol);
757 
758 	if(isAlgPort(new_entry->protocol, new_entry->private_port) ||
759 		 isAlgPort(new_entry->protocol, new_entry->target_port))
760 	{
761 		IPACMDBG("connection using ALG Port. Dont insert into nat cache\n");
762 		return;
763 	}
764 
765 	if(ChkForDup(new_entry))
766 	{
767 		return;
768 	}
769 
770 	for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
771 	{
772 		if(temp[cnt].private_ip == new_entry->private_ip &&
773 			 temp[cnt].target_ip == new_entry->target_ip &&
774 			 temp[cnt].private_port ==  new_entry->private_port  &&
775 			 temp[cnt].target_port == new_entry->target_port &&
776 			 temp[cnt].protocol == new_entry->protocol)
777 		{
778 			IPACMDBG("Received duplicate Temp entry\n");
779 			return;
780 		}
781 	}
782 
783 	for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
784 	{
785 		if(temp[cnt].private_ip == 0 &&
786 			 temp[cnt].target_ip == 0)
787 		{
788 			memcpy(&temp[cnt], new_entry, sizeof(nat_table_entry));
789 			IPACMDBG("Added Temp Entry\n");
790 			return;
791 		}
792 	}
793 
794 	IPACMDBG("Unable to add temp entry, cache full\n");
795 	return;
796 }
797 
DeleteTempEntry(const nat_table_entry * entry)798 void NatApp::DeleteTempEntry(const nat_table_entry *entry)
799 {
800 	int cnt;
801 
802 	IPACMDBG("Received below nat entry\n");
803 	iptodot("Private IP", entry->private_ip);
804 	iptodot("Target IP", entry->target_ip);
805 	IPACMDBG("Private Port: %d\t Target Port: %d\n", entry->private_port, entry->target_port);
806 	IPACMDBG("protocol: %d\n", entry->protocol);
807 
808 	for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
809 	{
810 		if(temp[cnt].private_ip == entry->private_ip &&
811 			 temp[cnt].target_ip == entry->target_ip &&
812 			 temp[cnt].private_port ==  entry->private_port  &&
813 			 temp[cnt].target_port == entry->target_port &&
814 			 temp[cnt].protocol == entry->protocol)
815 		{
816 			memset(&temp[cnt], 0, sizeof(nat_table_entry));
817 			IPACMDBG("Delete Temp Entry\n");
818 			return;
819 		}
820 	}
821 
822 	IPACMDBG("No Such Temp Entry exists\n");
823 	return;
824 }
825 
FlushTempEntries(uint32_t ip_addr,bool isAdd,bool isDummy)826 void NatApp::FlushTempEntries(uint32_t ip_addr, bool isAdd,
827 		bool isDummy)
828 {
829 	int cnt;
830 	int ret;
831 
832 	IPACMDBG_H("Received below with isAdd:%d ", isAdd);
833 	iptodot("IP Address: ", ip_addr);
834 
835 	for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
836 	{
837 		if(temp[cnt].private_ip == ip_addr ||
838 			 temp[cnt].target_ip == ip_addr)
839 		{
840 			if(isAdd)
841 			{
842 				if(temp[cnt].public_ip == pub_ip_addr)
843 				{
844 					if (isDummy) {
845 						/* To avoild DL expections for non IPA path */
846 						temp[cnt].private_ip = temp[cnt].public_ip;
847 						temp[cnt].private_port = temp[cnt].public_port;
848 						IPACMDBG("Flushing dummy temp rule");
849 						iptodot("Private IP", temp[cnt].private_ip);
850 					}
851 
852 					ret = AddEntry(&temp[cnt]);
853 					if(ret)
854 					{
855 						IPACMERR("unable to add temp entry: %d\n", ret);
856 						continue;
857 					}
858 				}
859 			}
860 			memset(&temp[cnt], 0, sizeof(nat_table_entry));
861 		}
862 	}
863 
864 	return;
865 }
866 
DelEntriesOnClntDiscon(uint32_t ip_addr)867 int NatApp::DelEntriesOnClntDiscon(uint32_t ip_addr)
868 {
869 	int cnt, tmp = 0;
870 	IPACMDBG_H("Received IP address: 0x%x\n", ip_addr);
871 
872 	if(ip_addr == INVALID_IP_ADDR)
873 	{
874 		IPACMERR("Invalid ip address received\n");
875 		return -1;
876 	}
877 
878 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
879 	{
880 		if(PwrSaveIfs[cnt] == ip_addr)
881 		{
882 			PwrSaveIfs[cnt] = 0;
883 			IPACMDBG("Remove %d power save entry\n", cnt);
884 			break;
885 		}
886 	}
887 
888 	for(cnt = 0; cnt < max_entries; cnt++)
889 	{
890 		if(cache[cnt].private_ip == ip_addr)
891 		{
892 			if(cache[cnt].enabled == true)
893 			{
894 				if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
895 				{
896 					IPACMERR("unable to delete the rule\n");
897 					continue;
898 				}
899 				else
900 				{
901 					IPACMDBG("won't delete the rule\n");
902 					cache[cnt].enabled = false;
903 					tmp++;
904 				}
905 			}
906 			IPACMDBG("won't delete the rule for entry %d, enabled %d\n",cnt, cache[cnt].enabled);
907 		}
908 	}
909 
910 	IPACMDBG("Deleted (but cached) %d entries\n", tmp);
911 	return 0;
912 }
913 
DelEntriesOnSTAClntDiscon(uint32_t ip_addr)914 int NatApp::DelEntriesOnSTAClntDiscon(uint32_t ip_addr)
915 {
916 	int cnt, tmp = curCnt;
917 	IPACMDBG_H("Received IP address: 0x%x\n", ip_addr);
918 
919 	if(ip_addr == INVALID_IP_ADDR)
920 	{
921 		IPACMERR("Invalid ip address received\n");
922 		return -1;
923 	}
924 
925 
926 	for(cnt = 0; cnt < max_entries; cnt++)
927 	{
928 		if(cache[cnt].target_ip == ip_addr)
929 		{
930 			if(cache[cnt].enabled == true)
931 			{
932 				if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
933 				{
934 					IPACMERR("unable to delete the rule\n");
935 					continue;
936 				}
937 			}
938 
939 			memset(&cache[cnt], 0, sizeof(cache[cnt]));
940 			curCnt--;
941 		}
942 	}
943 
944 	IPACMDBG("Deleted %d entries\n", (tmp - curCnt));
945 	return 0;
946 }
947 
CacheEntry(const nat_table_entry * rule)948 void NatApp::CacheEntry(const nat_table_entry *rule)
949 {
950 	int cnt;
951 
952 	if(rule->private_ip == 0 ||
953 		 rule->target_ip == 0 ||
954 		 rule->private_port == 0  ||
955 		 rule->target_port == 0 ||
956 		 rule->protocol == 0)
957 	{
958 		IPACMERR("Invalid Connection, ignoring it\n");
959 		return;
960 	}
961 
962 	if(!ChkForDup(rule))
963 	{
964 		for(cnt=0; cnt < max_entries; cnt++)
965 		{
966 			if(cache[cnt].private_ip == 0 &&
967 				 cache[cnt].target_ip == 0 &&
968 				 cache[cnt].private_port == 0  &&
969 				 cache[cnt].target_port == 0 &&
970 				 cache[cnt].protocol == 0)
971 			{
972 				break;
973 			}
974 		}
975 
976 		if(max_entries == cnt)
977 		{
978 			IPACMERR("Error: Unable to add, reached maximum rules\n");
979 			return;
980 		}
981 		else
982 		{
983 			cache[cnt].enabled = false;
984 			cache[cnt].rule_hdl = 0;
985 			cache[cnt].private_ip = rule->private_ip;
986 			cache[cnt].target_ip = rule->target_ip;
987 			cache[cnt].target_port = rule->target_port;
988 			cache[cnt].private_port = rule->private_port;
989 			cache[cnt].protocol = rule->protocol;
990 			cache[cnt].timestamp = 0;
991 			cache[cnt].public_port = rule->public_port;
992 			cache[cnt].public_ip = rule->public_ip;
993 			cache[cnt].dst_nat = rule->dst_nat;
994 			curCnt++;
995 		}
996 
997 	}
998 	else
999 	{
1000 		IPACMERR("Duplicate rule. Ignore it\n");
1001 		return;
1002 	}
1003 
1004 	IPACMDBG("Cached rule(%d) successfully\n", cnt);
1005 	return;
1006 }
1007 
Read_TcpUdp_Timeout(void)1008 void NatApp::Read_TcpUdp_Timeout(void) {
1009 #ifdef FEATURE_IPACM_HAL
1010 	tcp_timeout = 432000;
1011 	udp_timeout = 180;
1012 	IPACMDBG_H("udp timeout value: %d\n", udp_timeout);
1013 	IPACMDBG_H("tcp timeout value: %d\n", tcp_timeout);
1014 #else
1015 	FILE *udp_fd = NULL, *tcp_fd = NULL;
1016 	/* Read UDP timeout value */
1017 	udp_fd = fopen(IPACM_UDP_FULL_FILE_NAME, "r");
1018 	if (udp_fd == NULL) {
1019 		IPACMERR("unable to open %s\n", IPACM_UDP_FULL_FILE_NAME);
1020 		goto fail;
1021 	}
1022 
1023 	if (fscanf(udp_fd, "%d", &udp_timeout) != 1) {
1024 		IPACMERR("Error reading udp timeout\n");
1025 	}
1026 	IPACMDBG_H("udp timeout value: %d\n", udp_timeout);
1027 
1028 
1029 	/* Read TCP timeout value */
1030 	tcp_fd = fopen(IPACM_TCP_FULL_FILE_NAME, "r");
1031 	if (tcp_fd == NULL) {
1032 		IPACMERR("unable to open %s\n", IPACM_TCP_FULL_FILE_NAME);
1033 		goto fail;
1034 	}
1035 
1036 
1037 	if (fscanf(tcp_fd, "%d", &tcp_timeout) != 1) {
1038 		IPACMERR("Error reading tcp timeout\n");
1039 	}
1040 	IPACMDBG_H("tcp timeout value: %d\n", tcp_timeout);
1041 
1042 fail:
1043 	if (udp_fd) {
1044 		fclose(udp_fd);
1045 	}
1046 	if (tcp_fd) {
1047 		fclose(tcp_fd);
1048 	}
1049 #endif
1050 	return;
1051 }
1052