1 /*
2 Copyright (c) 2013-2019, 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 #include "IPACM_ConntrackListener.h"
32 #ifdef FEATURE_IPACM_HAL
33 #include "IPACM_OffloadManager.h"
34 #endif
35 #include "IPACM_Iface.h"
36 
37 #define INVALID_IP_ADDR 0x0
38 
39 #define HDR_METADATA_MUX_ID_BMASK 0x00FF0000
40 #define HDR_METADATA_MUX_ID_SHFT 0x10
41 
42 /* NatApp class Implementation */
43 NatApp *NatApp::pInstance = NULL;
NatApp()44 NatApp::NatApp()
45 {
46 	max_entries = 0;
47 	cache = NULL;
48 
49 	nat_table_hdl = 0;
50 	pub_ip_addr = 0;
51 	pub_mux_id = 0;
52 
53 	curCnt = 0;
54 
55 	pALGPorts = NULL;
56 	nALGPort = 0;
57 
58 	ct = NULL;
59 	ct_hdl = NULL;
60 
61 	memset(temp, 0, sizeof(temp));
62 	m_fd_ipa = open(IPA_DEVICE_NAME, O_RDWR);
63 	if(m_fd_ipa < 0)
64 	{
65 		IPACMERR("Failed to open %s\n",IPA_DEVICE_NAME);
66 	}
67 }
68 
~NatApp()69 NatApp::~NatApp()
70 {
71 	if (m_fd_ipa) {
72 		close(m_fd_ipa);
73 	}
74 }
75 
Init(void)76 int NatApp::Init(void)
77 {
78 	IPACM_Config *pConfig;
79 	int size = 0;
80 
81 	pConfig = IPACM_Config::GetInstance();
82 	if(pConfig == NULL)
83 	{
84 		IPACMERR("Unable to get Config instance\n");
85 		return -1;
86 	}
87 
88 	max_entries = pConfig->GetNatMaxEntries();
89 
90 	size = (sizeof(nat_table_entry) * max_entries);
91 	cache = (nat_table_entry *)malloc(size);
92 	if(cache == NULL)
93 	{
94 		IPACMERR("Unable to allocate memory for cache\n");
95 		goto fail;
96 	}
97 	IPACMDBG("Allocated %d bytes for config manager nat cache\n", size);
98 	memset(cache, 0, size);
99 
100 	nALGPort = pConfig->GetAlgPortCnt();
101 	if(nALGPort > 0)
102 	{
103 		pALGPorts = (ipacm_alg *)malloc(sizeof(ipacm_alg) * nALGPort);
104 		if(pALGPorts == NULL)
105 		{
106 			IPACMERR("Unable to allocate memory for alg prots\n");
107 			goto fail;
108 		}
109 		memset(pALGPorts, 0, sizeof(ipacm_alg) * nALGPort);
110 
111 		pConfig->GetAlgPorts(nALGPort, pALGPorts);
112 
113 		IPACMDBG("Printing %d alg ports information\n", nALGPort);
114 		for(int cnt=0; cnt<nALGPort; cnt++)
115 		{
116 			IPACMDBG("%d: Proto[%d], port[%d]\n", cnt, pALGPorts[cnt].protocol, pALGPorts[cnt].port);
117 		}
118 	}
119 	else
120 	{
121 		IPACMERR("Unable to retrieve ALG prot count\n");
122 		goto fail;
123 	}
124 
125 	return 0;
126 
127 fail:
128 	if(cache != NULL)
129 	{
130 		free(cache);
131 	}
132 	if(pALGPorts != NULL)
133 	{
134 		free(pALGPorts);
135 	}
136 	return -1;
137 }
138 
GetInstance()139 NatApp* NatApp::GetInstance()
140 {
141 	if(pInstance == NULL)
142 	{
143 		pInstance = new NatApp();
144 
145 		if(pInstance->Init())
146 		{
147 			delete pInstance;
148 			return NULL;
149 		}
150 	}
151 
152 	return pInstance;
153 }
154 
GenerateMetdata(uint8_t mux_id)155 uint32_t NatApp::GenerateMetdata(uint8_t mux_id)
156 {
157 	return (mux_id << HDR_METADATA_MUX_ID_SHFT) & HDR_METADATA_MUX_ID_BMASK;
158 }
159 
160 /* NAT APP related object function definitions */
161 
AddTable(uint32_t pub_ip,uint8_t mux_id)162 int NatApp::AddTable(uint32_t pub_ip, uint8_t mux_id)
163 {
164 	int ret;
165 	int cnt = 0;
166 	ipa_nat_ipv4_rule nat_rule;
167 	IPACMDBG_H("%s() %d\n", __FUNCTION__, __LINE__);
168 
169 	/* Not reset the cache wait it timeout by destroy event */
170 #if 0
171 	if (pub_ip != pub_ip_addr_pre)
172 	{
173 		IPACMDBG("Reset the cache because NAT-ipv4 different\n");
174 		memset(cache, 0, sizeof(nat_table_entry) * max_entries);
175 		curCnt = 0;
176 	}
177 #endif
178 	ret = ipa_nat_add_ipv4_tbl(pub_ip, max_entries, &nat_table_hdl);
179 	if(ret)
180 	{
181 		IPACMERR("unable to create nat table Error:%d\n", ret);
182 		return ret;
183 	}
184 	if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_v4_0) {
185 		/* modify PDN 0 so it will hold the mux ID in the src metadata field */
186 		ipa_nat_pdn_entry entry;
187 
188 		entry.dst_metadata = 0;
189 		entry.src_metadata = GenerateMetdata(mux_id);
190 		entry.public_ip = pub_ip;
191 		ret = ipa_nat_modify_pdn(nat_table_hdl, 0, &entry);
192 		if(ret)
193 		{
194 			IPACMERR("unable to modify PDN 0 entry Error:%d INIT_HDR_METADATA register values will be used!\n", ret);
195 		}
196 	}
197 
198 	/* Add back the cached NAT-entry */
199 	if (pub_ip == pub_ip_addr_pre)
200 	{
201 		IPACMDBG("Restore the cache to ipa NAT-table\n");
202 		for(cnt = 0; cnt < max_entries; cnt++)
203 		{
204 			if(cache[cnt].private_ip !=0)
205 			{
206 				memset(&nat_rule, 0 , sizeof(nat_rule));
207 				nat_rule.private_ip = cache[cnt].private_ip;
208 				nat_rule.target_ip = cache[cnt].target_ip;
209 				nat_rule.target_port = cache[cnt].target_port;
210 				nat_rule.private_port = cache[cnt].private_port;
211 				nat_rule.public_port = cache[cnt].public_port;
212 				nat_rule.protocol = cache[cnt].protocol;
213 
214 				if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0)
215 				{
216 					IPACMERR("unable to add the rule delete from cache\n");
217 					memset(&cache[cnt], 0, sizeof(cache[cnt]));
218 					curCnt--;
219 					continue;
220 				}
221 				cache[cnt].enabled = true;
222 				/* send connections info to pcie modem only with DL direction */
223 				if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP))
224 				{
225 					ret = AddConnection(&cache[cnt]);
226 					if(ret > 0)
227 					{
228 						/* save the rule id for deletion */
229 						cache[cnt].rule_id = ret;
230 						IPACMDBG_H("rule-id(%d)\n", cache[cnt].rule_id);
231 					}
232 					else
233 					{
234 						IPACMERR("unable to add Connection to pcie modem: error:%d\n", ret);
235 						cache[cnt].rule_id = 0;
236 					}
237 				}
238 
239 				IPACMDBG("On wan-iface reset added below rule successfully\n");
240 				iptodot("Private IP", nat_rule.private_ip);
241 				iptodot("Target IP", nat_rule.target_ip);
242 				IPACMDBG("Private Port:%d \t Target Port: %d\t", nat_rule.private_port, nat_rule.target_port);
243 				IPACMDBG("Public Port:%d\n", nat_rule.public_port);
244 				IPACMDBG("protocol: %d\n", nat_rule.protocol);
245 			}
246 		}
247 	}
248 
249 	pub_ip_addr = pub_ip;
250 	pub_mux_id = mux_id;
251 	IPACMDBG(" Set pub_mux_id: %d\t", pub_mux_id);
252 	return 0;
253 }
254 
Reset()255 void NatApp::Reset()
256 {
257 	nat_table_hdl = 0;
258 	pub_ip_addr = 0;
259 	pub_mux_id = 0;
260 }
261 
DeleteTable(uint32_t pub_ip)262 int NatApp::DeleteTable(uint32_t pub_ip)
263 {
264 	int cnt = 0;
265 	int ret;
266 	IPACMDBG_H("%s() %d\n", __FUNCTION__, __LINE__);
267 
268 	CHK_TBL_HDL();
269 
270 	if(pub_ip_addr != pub_ip)
271 	{
272 		IPACMDBG("Public ip address is not matching\n");
273 		IPACMERR("unable to delete the nat table\n");
274 		return -1;
275 	}
276 
277 	/* NAT tbl deleted, reset enabled bit */
278 	for(cnt = 0; cnt < max_entries; cnt++)
279 	{
280 		cache[cnt].enabled = false;
281 		/* send connections del info to pcie modem first */
282 		if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP) && (cache[cnt].rule_id > 0))
283 
284 		{
285 			ret = DelConnection(cache[cnt].rule_id);
286 			if(ret)
287 			{
288 				IPACMERR("unable to del Connection to pcie modem: %d\n", ret);
289 			}
290 			else
291 			{
292 				/* save the rule id for deletion */
293 				cache[cnt].rule_id = 0;
294 			}
295 		}
296 	}
297 
298 	ret = ipa_nat_del_ipv4_tbl(nat_table_hdl);
299 	if(ret)
300 	{
301 		IPACMERR("unable to delete nat table Error: %d\n", ret);;
302 		return ret;
303 	}
304 
305 	pub_ip_addr_pre = pub_ip_addr;
306 	Reset();
307 	return 0;
308 }
309 
310 /* Check for duplicate entries */
ChkForDup(const nat_table_entry * rule)311 bool NatApp::ChkForDup(const nat_table_entry *rule)
312 {
313 	int cnt = 0;
314 	IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
315 
316 	for(; cnt < max_entries; cnt++)
317 	{
318 		if(cache[cnt].private_ip == rule->private_ip &&
319 			 cache[cnt].target_ip == rule->target_ip &&
320 			 cache[cnt].private_port ==  rule->private_port  &&
321 			 cache[cnt].target_port == rule->target_port &&
322 			 cache[cnt].protocol == rule->protocol)
323 		{
324 			log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
325 			rule->target_port,"Duplicate Rule\n");
326 			return true;
327 		}
328 	}
329 
330 	return false;
331 }
332 
333 /* Delete the entry from Nat table on connection close */
DeleteEntry(const nat_table_entry * rule)334 int NatApp::DeleteEntry(const nat_table_entry *rule)
335 {
336 	int cnt = 0;
337 	int ret = 0;
338 	IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
339 
340 	log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
341 	rule->target_port,"for deletion\n");
342 
343 
344 	for(; cnt < max_entries; cnt++)
345 	{
346 		if(cache[cnt].private_ip == rule->private_ip &&
347 			 cache[cnt].target_ip == rule->target_ip &&
348 			 cache[cnt].private_port ==  rule->private_port  &&
349 			 cache[cnt].target_port == rule->target_port &&
350 			 cache[cnt].protocol == rule->protocol)
351 		{
352 
353 			if(cache[cnt].enabled == true)
354 			{
355 				/* send connections del info to pcie modem first */
356 				if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP) && (cache[cnt].rule_id > 0))
357 				{
358 					ret = DelConnection(cache[cnt].rule_id);
359 					if(ret)
360 					{
361 						IPACMERR("unable to del Connection to pcie modem: %d\n", ret);
362 					}
363 					else
364 					{
365 						/* save the rule id for deletion */
366 						cache[cnt].rule_id = 0;
367 					}
368 				}
369 
370 				if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
371 				{
372 					IPACMERR("%s() %d deletion failed\n", __FUNCTION__, __LINE__);
373 				}
374 
375 				IPACMDBG_H("Deleted Nat entry(%d) Successfully\n", cnt);
376 			}
377 			else
378 			{
379 				IPACMDBG_H("Deleted Nat entry(%d) only from cache\n", cnt);
380 			}
381 
382 			memset(&cache[cnt], 0, sizeof(cache[cnt]));
383 			curCnt--;
384 			break;
385 		}
386 	}
387 
388 	return 0;
389 }
390 
391 /* Add new entry to the nat table on new connection */
AddEntry(const nat_table_entry * rule)392 int NatApp::AddEntry(const nat_table_entry *rule)
393 {
394 	int cnt = 0;
395 	ipa_nat_ipv4_rule nat_rule;
396 	int ret = 0;
397 
398 	IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
399 
400 	CHK_TBL_HDL();
401 	log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
402 	rule->target_port,"for addition\n");
403 	if(isAlgPort(rule->protocol, rule->private_port) ||
404 		 isAlgPort(rule->protocol, rule->target_port))
405 	{
406 		IPACMERR("connection using ALG Port, ignore\n");
407 		return -1;
408 	}
409 
410 	if(rule->private_ip == 0 ||
411 		 rule->target_ip == 0 ||
412 		 rule->private_port == 0  ||
413 		 rule->target_port == 0 ||
414 		 rule->protocol == 0)
415 	{
416 		IPACMERR("Invalid Connection, ignoring it\n");
417 		return 0;
418 	}
419 
420 	if(!ChkForDup(rule))
421 	{
422 		for(; cnt < max_entries; cnt++)
423 		{
424 			if(cache[cnt].private_ip == 0 &&
425 				 cache[cnt].target_ip == 0 &&
426 				 cache[cnt].private_port == 0  &&
427 				 cache[cnt].target_port == 0 &&
428 				 cache[cnt].protocol == 0)
429 			{
430 				break;
431 			}
432 		}
433 
434 		if(max_entries == cnt)
435 		{
436 			IPACMERR("Error: Unable to add, reached maximum rules\n");
437 			return -1;
438 		}
439 		else
440 		{
441 			memset(&nat_rule, 0, sizeof(nat_rule));
442 			nat_rule.private_ip = rule->private_ip;
443 			nat_rule.target_ip = rule->target_ip;
444 			nat_rule.target_port = rule->target_port;
445 			nat_rule.private_port = rule->private_port;
446 			nat_rule.public_port = rule->public_port;
447 			nat_rule.protocol = rule->protocol;
448 
449 			if(isPwrSaveIf(rule->private_ip) ||
450 				 isPwrSaveIf(rule->target_ip))
451 			{
452 				IPACMDBG("Device is Power Save mode: Dont insert into nat table but cache\n");
453 				cache[cnt].enabled = false;
454 				cache[cnt].rule_hdl = 0;
455 			}
456 			else
457 			{
458 
459 				if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0)
460 				{
461 					IPACMERR("unable to add the rule\n");
462 					return -1;
463 				}
464 
465 				cache[cnt].enabled = true;
466 				/* send connections info to pcie modem only with DL direction */
467 				if ((CtList->backhaul_mode == Q6_MHI_WAN) && (rule->dst_nat == true || rule->protocol == IPPROTO_TCP))
468 				{
469 					ret = AddConnection(rule);
470 					if(ret > 0)
471 					{
472 						/* save the rule id for deletion */
473 						cache[cnt].rule_id = ret;
474 						IPACMDBG_H("rule-id(%d)\n", cache[cnt].rule_id);
475 					}
476 					else
477 					{
478 						IPACMERR("unable to add Connection to pcie modem: error:%d\n", ret);
479 						cache[cnt].rule_id = 0;
480 					}
481 				}
482 			}
483 			cache[cnt].private_ip = rule->private_ip;
484 			cache[cnt].target_ip = rule->target_ip;
485 			cache[cnt].target_port = rule->target_port;
486 			cache[cnt].private_port = rule->private_port;
487 			cache[cnt].protocol = rule->protocol;
488 			cache[cnt].timestamp = 0;
489 			cache[cnt].public_port = rule->public_port;
490 			cache[cnt].dst_nat = rule->dst_nat;
491 			curCnt++;
492 		}
493 
494 	}
495 	else
496 	{
497 		IPACMERR("Duplicate rule. Ignore it\n");
498 		return -1;
499 	}
500 
501 	if(cache[cnt].enabled == true)
502 	{
503 		IPACMDBG_H("Added rule(%d) successfully\n", cnt);
504 	}
505   else
506   {
507     IPACMDBG_H("Cached rule(%d) successfully\n", cnt);
508   }
509 
510 	return 0;
511 }
512 
513 /* Add new entry to the nat table on new connection, return rule-id */
AddConnection(const nat_table_entry * rule)514 int NatApp::AddConnection(const nat_table_entry *rule)
515 {
516 	int len, res = IPACM_SUCCESS;
517 	ipa_ioc_add_flt_rule *pFilteringTable = NULL;
518 
519 	/* contruct filter rules to pcie modem */
520 	struct ipa_flt_rule_add flt_rule_entry;
521 	ipa_ioc_generate_flt_eq flt_eq;
522 
523 	IPACMDBG("\n");
524 	len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
525 	pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
526 	if (pFilteringTable == NULL)
527 	{
528 		IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
529 		return IPACM_FAILURE;
530 	}
531 	memset(pFilteringTable, 0, len);
532 
533 
534 	pFilteringTable->commit = 1;
535 	pFilteringTable->global = false;
536 	pFilteringTable->ip = IPA_IP_v4;
537 	pFilteringTable->num_rules = (uint8_t)1;
538 
539 	/* Configuring Software-Routing Filtering Rule */
540 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
541 	flt_rule_entry.at_rear = true;
542 	flt_rule_entry.flt_rule_hdl = -1;
543 	flt_rule_entry.status = -1;
544 
545 	flt_rule_entry.rule.retain_hdr = 1;
546 	flt_rule_entry.rule.to_uc = 0;
547 	flt_rule_entry.rule.eq_attrib_type = 1;
548 	flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
549 	if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
550 		flt_rule_entry.rule.hashable = true;
551 	flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_PORT;
552 	flt_rule_entry.rule.attrib.src_port = rule->target_port;
553 	flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_PORT;
554 	flt_rule_entry.rule.attrib.dst_port = rule->public_port;
555 	flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
556 	flt_rule_entry.rule.attrib.u.v4.protocol = rule->protocol;
557 	flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
558 	flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
559 	flt_rule_entry.rule.attrib.u.v4.dst_addr = rule->public_ip;
560 	flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR;
561 	flt_rule_entry.rule.attrib.u.v4.src_addr_mask = 0xFFFFFFFF;
562 	flt_rule_entry.rule.attrib.u.v4.src_addr = rule->target_ip;
563 	IPACMDBG_H("src(0x%x) port(%d)->dst(0x%x) port(%d), protocol(%d) pub_mux_id (%d)\n",
564 				rule->target_ip, rule->target_port, rule->public_ip, rule->public_port,
565 				rule->protocol, pub_mux_id);
566 
567 	memset(&flt_eq, 0, sizeof(flt_eq));
568 	memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
569 	flt_eq.ip = IPA_IP_v4;
570 	if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
571 	{
572 		IPACMERR("Failed to get eq_attrib\n");
573 		res = IPACM_FAILURE;
574 		goto fail;
575 	}
576 	memcpy(&flt_rule_entry.rule.eq_attrib,
577 		&flt_eq.eq_attrib,
578 		sizeof(flt_rule_entry.rule.eq_attrib));
579 	memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
580 
581 	if(false == IPACM_Iface::m_filtering.AddOffloadFilteringRule(pFilteringTable, pub_mux_id, 0))
582 	{
583 		IPACMERR("Failed to install WAN DL filtering table.\n");
584 		res = IPACM_FAILURE;
585 		goto fail;
586 	}
587 
588 	/* get rule-id */
589 	res = pFilteringTable->rules[0].flt_rule_hdl;
590 
591 fail:
592 	if(pFilteringTable != NULL)
593 	{
594 		free(pFilteringTable);
595 	}
596 	return res;
597 }
598 
DelConnection(const uint32_t rule_id)599 int NatApp::DelConnection(const uint32_t rule_id)
600 {
601 	int len, res = IPACM_SUCCESS;
602 	ipa_ioc_del_flt_rule *pFilteringTable = NULL;
603 
604 
605 	struct ipa_flt_rule_del flt_rule_entry;
606 
607 	IPACMDBG("\n");
608 	len = sizeof(struct ipa_ioc_del_flt_rule) + sizeof(struct ipa_flt_rule_del);
609 	pFilteringTable = (struct ipa_ioc_del_flt_rule*)malloc(len);
610 	if (pFilteringTable == NULL)
611 	{
612 		IPACMERR("Error Locate ipa_ioc_del_flt_rule memory...\n");
613 		return IPACM_FAILURE;
614 	}
615 	memset(pFilteringTable, 0, len);
616 
617 
618 	pFilteringTable->commit = 1;
619 	pFilteringTable->ip = IPA_IP_v4;
620 	pFilteringTable->num_hdls = (uint8_t)1;
621 
622 	/* Configuring Software-Routing Filtering Rule */
623 	memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
624 	flt_rule_entry.hdl = rule_id;
625 
626 	memcpy(&(pFilteringTable->hdl[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
627 
628 	if(false == IPACM_Iface::m_filtering.DelOffloadFilteringRule(pFilteringTable))
629 	{
630 		IPACMERR("Failed to install WAN DL filtering table.\n");
631 		res = IPACM_FAILURE;
632 		goto fail;
633 	}
634 
635 fail:
636 	if(pFilteringTable != NULL)
637 	{
638 		free(pFilteringTable);
639 	}
640 	return res;
641 }
642 
UpdateCTUdpTs(nat_table_entry * rule,uint32_t new_ts)643 void NatApp::UpdateCTUdpTs(nat_table_entry *rule, uint32_t new_ts)
644 {
645 #ifdef FEATURE_IPACM_HAL
646 	IOffloadManager::ConntrackTimeoutUpdater::natTimeoutUpdate_t entry;
647 	IPACM_OffloadManager* OffloadMng;
648 #endif
649 	iptodot("Private IP:", rule->private_ip);
650 	iptodot("Target IP:",  rule->target_ip);
651 	IPACMDBG("Private Port: %d, Target Port: %d\n", rule->private_port, rule->target_port);
652 
653 #ifndef FEATURE_IPACM_HAL
654 	int ret;
655 	if(!ct_hdl)
656 	{
657 		ct_hdl = nfct_open(CONNTRACK, 0);
658 		if(!ct_hdl)
659 		{
660 			PERROR("nfct_open");
661 			return;
662 		}
663 	}
664 
665 	if(!ct)
666 	{
667 		ct = nfct_new();
668 		if(!ct)
669 		{
670 			PERROR("nfct_new");
671 			return;
672 		}
673 	}
674 
675 	nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET);
676 	if(rule->protocol == IPPROTO_UDP)
677 	{
678 		nfct_set_attr_u8(ct, ATTR_L4PROTO, rule->protocol);
679 		nfct_set_attr_u32(ct, ATTR_TIMEOUT, udp_timeout);
680 	}
681 	else
682 	{
683 		nfct_set_attr_u8(ct, ATTR_L4PROTO, rule->protocol);
684 		nfct_set_attr_u32(ct, ATTR_TIMEOUT, tcp_timeout);
685 	}
686 
687 	if(rule->dst_nat == false)
688 	{
689 		nfct_set_attr_u32(ct, ATTR_IPV4_SRC, htonl(rule->private_ip));
690 		nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(rule->private_port));
691 
692 		nfct_set_attr_u32(ct, ATTR_IPV4_DST, htonl(rule->target_ip));
693 		nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(rule->target_port));
694 
695 		IPACMDBG("dst nat is not set\n");
696 	}
697 	else
698 	{
699 		nfct_set_attr_u32(ct, ATTR_IPV4_SRC, htonl(rule->target_ip));
700 		nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(rule->target_port));
701 
702 		nfct_set_attr_u32(ct, ATTR_IPV4_DST, htonl(pub_ip_addr));
703 		nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(rule->public_port));
704 
705 		IPACMDBG("dst nat is set\n");
706 	}
707 
708 	iptodot("Source IP:", nfct_get_attr_u32(ct, ATTR_IPV4_SRC));
709 	iptodot("Destination IP:",  nfct_get_attr_u32(ct, ATTR_IPV4_DST));
710 	IPACMDBG("Source Port: %d, Destination Port: %d\n",
711 					 nfct_get_attr_u16(ct, ATTR_PORT_SRC), nfct_get_attr_u16(ct, ATTR_PORT_DST));
712 
713 	IPACMDBG("updating %d connection with time: %d\n",
714 					 rule->protocol, nfct_get_attr_u32(ct, ATTR_TIMEOUT));
715 
716 	ret = nfct_query(ct_hdl, NFCT_Q_UPDATE, ct);
717 	if(ret == -1)
718 	{
719 		IPACMERR("unable to update time stamp");
720 		DeleteEntry(rule);
721 	}
722 	else
723 	{
724 		rule->timestamp = new_ts;
725 		IPACMDBG("Updated time stamp successfully\n");
726 	}
727 #else
728 	if(rule->protocol == IPPROTO_UDP)
729 	{
730 		entry.proto = IOffloadManager::ConntrackTimeoutUpdater::UDP;;
731 	}
732 	else
733 	{
734 		entry.proto = IOffloadManager::ConntrackTimeoutUpdater::TCP;
735 	}
736 
737 	if(rule->dst_nat == false)
738 	{
739 		entry.src.ipAddr = htonl(rule->private_ip);
740 		entry.src.port = rule->private_port;
741 		entry.dst.ipAddr = htonl(rule->target_ip);
742 		entry.dst.port = rule->target_port;
743 		IPACMDBG("dst nat is not set\n");
744 	}
745 	else
746 	{
747 		entry.src.ipAddr = htonl(rule->target_ip);
748 		entry.src.port = rule->target_port;
749 		entry.dst.ipAddr = htonl(pub_ip_addr);
750 		entry.dst.port = rule->public_port;
751 		IPACMDBG("dst nat is set\n");
752 	}
753 
754 	iptodot("Source IP:", entry.src.ipAddr);
755 	iptodot("Destination IP:",  entry.dst.ipAddr);
756 	IPACMDBG("Source Port: %d, Destination Port: %d\n",
757 					entry.src.port, entry.dst.port);
758 
759 	OffloadMng = IPACM_OffloadManager::GetInstance();
760 	if (OffloadMng->touInstance == NULL) {
761 		IPACMERR("OffloadMng->touInstance is NULL, can't forward to framework!\n");
762 	} else {
763 		OffloadMng->touInstance->updateTimeout(entry);
764 		IPACMDBG("Updated time stamp successfully\n");
765 		rule->timestamp = new_ts;
766 	}
767 #endif
768 	return;
769 }
770 
UpdateUDPTimeStamp()771 void NatApp::UpdateUDPTimeStamp()
772 {
773 	int cnt;
774 	uint32_t ts;
775 	bool read_to = false;
776 
777 	for(cnt = 0; cnt < max_entries; cnt++)
778 	{
779 		ts = 0;
780 		if(cache[cnt].enabled == true &&
781 		   (cache[cnt].private_ip != cache[cnt].public_ip))
782 		{
783 			IPACMDBG("\n");
784 			if(ipa_nat_query_timestamp(nat_table_hdl, cache[cnt].rule_hdl, &ts) < 0)
785 			{
786 				IPACMERR("unable to retrieve timeout for rule hanle: %d\n", cache[cnt].rule_hdl);
787 				continue;
788 			}
789 
790 			if(cache[cnt].timestamp == ts)
791 			{
792 				IPACMDBG("No Change in Time Stamp: cahce:%d, ipahw:%d\n",
793 								                  cache[cnt].timestamp, ts);
794 				continue;
795 			}
796 
797 			if (read_to == false) {
798 				read_to = true;
799 				Read_TcpUdp_Timeout();
800 			}
801 
802 			UpdateCTUdpTs(&cache[cnt], ts);
803 		} /* end of outer if */
804 
805 	} /* end of for loop */
806 
807 }
808 
isAlgPort(uint8_t proto,uint16_t port)809 bool NatApp::isAlgPort(uint8_t proto, uint16_t port)
810 {
811 	int cnt;
812 	for(cnt = 0; cnt < nALGPort; cnt++)
813 	{
814 		if(proto == pALGPorts[cnt].protocol &&
815 			 port == pALGPorts[cnt].port)
816 		{
817 			return true;
818 		}
819 	}
820 
821 	return false;
822 }
823 
isPwrSaveIf(uint32_t ip_addr)824 bool NatApp::isPwrSaveIf(uint32_t ip_addr)
825 {
826 	int cnt;
827 
828 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
829 	{
830 		if(0 != PwrSaveIfs[cnt] &&
831 			 ip_addr == PwrSaveIfs[cnt])
832 		{
833 			return true;
834 		}
835 	}
836 
837 	return false;
838 }
839 
UpdatePwrSaveIf(uint32_t client_lan_ip)840 int NatApp::UpdatePwrSaveIf(uint32_t client_lan_ip)
841 {
842 	int cnt, ret;
843 	IPACMDBG_H("Received IP address: 0x%x\n", client_lan_ip);
844 
845 	if(client_lan_ip == INVALID_IP_ADDR)
846 	{
847 		IPACMERR("Invalid ip address received\n");
848 		return -1;
849 	}
850 
851 	/* check for duplicate events */
852 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
853 	{
854 		if(PwrSaveIfs[cnt] == client_lan_ip)
855 		{
856 			IPACMDBG("The client 0x%x is already in power save\n", client_lan_ip);
857 			return 0;
858 		}
859 	}
860 
861 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
862 	{
863 		if(PwrSaveIfs[cnt] == 0)
864 		{
865 			PwrSaveIfs[cnt] = client_lan_ip;
866 			break;
867 		}
868 	}
869 
870 	for(cnt = 0; cnt < max_entries; cnt++)
871 	{
872 		if(cache[cnt].private_ip == client_lan_ip &&
873 			 cache[cnt].enabled == true)
874 		{
875 			/* send connections del info to pcie modem first */
876 			if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP) && (cache[cnt].rule_id > 0))
877 			{
878 				ret = DelConnection(cache[cnt].rule_id);
879 				if(ret)
880 				{
881 					IPACMERR("unable to del Connection to pcie modem: %d\n", ret);
882 				}
883 				else
884 				{
885 					/* save the rule id for deletion */
886 					cache[cnt].rule_id = 0;
887 				}
888 			}
889 
890 			if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
891 			{
892 				IPACMERR("unable to delete the rule\n");
893 				continue;
894 			}
895 
896 			cache[cnt].enabled = false;
897 			cache[cnt].rule_hdl = 0;
898 		}
899 	}
900 
901 	return 0;
902 }
903 
ResetPwrSaveIf(uint32_t client_lan_ip)904 int NatApp::ResetPwrSaveIf(uint32_t client_lan_ip)
905 {
906 	int cnt, ret;
907 	ipa_nat_ipv4_rule nat_rule;
908 
909 	IPACMDBG_H("Received ip address: 0x%x\n", client_lan_ip);
910 
911 	if(client_lan_ip == INVALID_IP_ADDR)
912 	{
913 		IPACMERR("Invalid ip address received\n");
914 		return -1;
915 	}
916 
917 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
918 	{
919 		if(PwrSaveIfs[cnt] == client_lan_ip)
920 		{
921 			PwrSaveIfs[cnt] = 0;
922 			break;
923 		}
924 	}
925 
926 	for(cnt = 0; cnt < max_entries; cnt++)
927 	{
928 		IPACMDBG("cache (%d): enable %d, ip 0x%x\n", cnt, cache[cnt].enabled, cache[cnt].private_ip);
929 
930 		if(cache[cnt].private_ip == client_lan_ip &&
931 			 cache[cnt].enabled == false)
932 		{
933 			memset(&nat_rule, 0 , sizeof(nat_rule));
934 			nat_rule.private_ip = cache[cnt].private_ip;
935 			nat_rule.target_ip = cache[cnt].target_ip;
936 			nat_rule.target_port = cache[cnt].target_port;
937 			nat_rule.private_port = cache[cnt].private_port;
938 			nat_rule.public_port = cache[cnt].public_port;
939 			nat_rule.protocol = cache[cnt].protocol;
940 
941 			if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0)
942 			{
943 				IPACMERR("unable to add the rule delete from cache\n");
944 				memset(&cache[cnt], 0, sizeof(cache[cnt]));
945 				curCnt--;
946 				continue;
947 			}
948 			cache[cnt].enabled = true;
949 			/* send connections info to pcie modem only with DL direction */
950 			if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP))
951 			{
952 				ret = AddConnection(&cache[cnt]);
953 				if(ret > 0)
954 				{
955 					/* save the rule id for deletion */
956 					cache[cnt].rule_id = ret;
957 					IPACMDBG_H("rule-id(%d)\n", cache[cnt].rule_id);
958 				}
959 				else
960 				{
961 					IPACMERR("unable to add Connection to pcie modem: error:%d\n", ret);
962 					cache[cnt].rule_id = 0;
963 				}
964 			}
965 
966 			IPACMDBG("On power reset added below rule successfully\n");
967 			iptodot("Private IP", nat_rule.private_ip);
968 			iptodot("Target IP", nat_rule.target_ip);
969 			IPACMDBG("Private Port:%d \t Target Port: %d\t", nat_rule.private_port, nat_rule.target_port);
970 			IPACMDBG("Public Port:%d\n", nat_rule.public_port);
971 			IPACMDBG("protocol: %d\n", nat_rule.protocol);
972 
973 		}
974 	}
975 
976 	return -1;
977 }
978 
GetTableHdl(uint32_t in_ip_addr)979 uint32_t NatApp::GetTableHdl(uint32_t in_ip_addr)
980 {
981 	if(in_ip_addr == pub_ip_addr)
982 	{
983 		return nat_table_hdl;
984 	}
985 
986 	return -1;
987 }
988 
AddTempEntry(const nat_table_entry * new_entry)989 void NatApp::AddTempEntry(const nat_table_entry *new_entry)
990 {
991 	int cnt;
992 
993 	IPACMDBG("Received below Temp Nat entry\n");
994 	iptodot("Private IP", new_entry->private_ip);
995 	iptodot("Target IP", new_entry->target_ip);
996 	IPACMDBG("Private Port: %d\t Target Port: %d\t", new_entry->private_port, new_entry->target_port);
997 	IPACMDBG("protocolcol: %d\n", new_entry->protocol);
998 
999 	if(isAlgPort(new_entry->protocol, new_entry->private_port) ||
1000 		 isAlgPort(new_entry->protocol, new_entry->target_port))
1001 	{
1002 		IPACMDBG("connection using ALG Port. Dont insert into nat cache\n");
1003 		return;
1004 	}
1005 
1006 	if(ChkForDup(new_entry))
1007 	{
1008 		return;
1009 	}
1010 
1011 	for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
1012 	{
1013 		if(temp[cnt].private_ip == new_entry->private_ip &&
1014 			 temp[cnt].target_ip == new_entry->target_ip &&
1015 			 temp[cnt].private_port ==  new_entry->private_port  &&
1016 			 temp[cnt].target_port == new_entry->target_port &&
1017 			 temp[cnt].protocol == new_entry->protocol)
1018 		{
1019 			IPACMDBG("Received duplicate Temp entry\n");
1020 			return;
1021 		}
1022 	}
1023 
1024 	for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
1025 	{
1026 		if(temp[cnt].private_ip == 0 &&
1027 			 temp[cnt].target_ip == 0)
1028 		{
1029 			memcpy(&temp[cnt], new_entry, sizeof(nat_table_entry));
1030 			IPACMDBG("Added Temp Entry\n");
1031 			return;
1032 		}
1033 	}
1034 
1035 	IPACMDBG("Unable to add temp entry, cache full\n");
1036 	return;
1037 }
1038 
DeleteTempEntry(const nat_table_entry * entry)1039 void NatApp::DeleteTempEntry(const nat_table_entry *entry)
1040 {
1041 	int cnt;
1042 
1043 	IPACMDBG("Received below nat entry\n");
1044 	iptodot("Private IP", entry->private_ip);
1045 	iptodot("Target IP", entry->target_ip);
1046 	IPACMDBG("Private Port: %d\t Target Port: %d\n", entry->private_port, entry->target_port);
1047 	IPACMDBG("protocol: %d\n", entry->protocol);
1048 
1049 	for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
1050 	{
1051 		if(temp[cnt].private_ip == entry->private_ip &&
1052 			 temp[cnt].target_ip == entry->target_ip &&
1053 			 temp[cnt].private_port ==  entry->private_port  &&
1054 			 temp[cnt].target_port == entry->target_port &&
1055 			 temp[cnt].protocol == entry->protocol)
1056 		{
1057 			memset(&temp[cnt], 0, sizeof(nat_table_entry));
1058 			IPACMDBG("Delete Temp Entry\n");
1059 			return;
1060 		}
1061 	}
1062 
1063 	IPACMDBG("No Such Temp Entry exists\n");
1064 	return;
1065 }
1066 
FlushTempEntries(uint32_t ip_addr,bool isAdd,bool isDummy)1067 void NatApp::FlushTempEntries(uint32_t ip_addr, bool isAdd,
1068 		bool isDummy)
1069 {
1070 	int cnt;
1071 	int ret;
1072 
1073 	IPACMDBG_H("Received below with isAdd:%d ", isAdd);
1074 	iptodot("IP Address: ", ip_addr);
1075 
1076 	for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
1077 	{
1078 		if(temp[cnt].private_ip == ip_addr ||
1079 			 temp[cnt].target_ip == ip_addr)
1080 		{
1081 			if(isAdd)
1082 			{
1083 				if(temp[cnt].public_ip == pub_ip_addr)
1084 				{
1085 					if (isDummy) {
1086 						/* To avoild DL expections for non IPA path */
1087 						temp[cnt].private_ip = temp[cnt].public_ip;
1088 						temp[cnt].private_port = temp[cnt].public_port;
1089 						IPACMDBG("Flushing dummy temp rule");
1090 						iptodot("Private IP", temp[cnt].private_ip);
1091 					}
1092 
1093 					ret = AddEntry(&temp[cnt]);
1094 					if(ret)
1095 					{
1096 						IPACMERR("unable to add temp entry: %d\n", ret);
1097 						continue;
1098 					}
1099 				}
1100 			}
1101 			memset(&temp[cnt], 0, sizeof(nat_table_entry));
1102 		}
1103 	}
1104 
1105 	return;
1106 }
1107 
DelEntriesOnClntDiscon(uint32_t ip_addr)1108 int NatApp::DelEntriesOnClntDiscon(uint32_t ip_addr)
1109 {
1110 	int cnt, tmp = 0, ret;
1111 	IPACMDBG_H("Received IP address: 0x%x\n", ip_addr);
1112 
1113 	if(ip_addr == INVALID_IP_ADDR)
1114 	{
1115 		IPACMERR("Invalid ip address received\n");
1116 		return -1;
1117 	}
1118 
1119 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
1120 	{
1121 		if(PwrSaveIfs[cnt] == ip_addr)
1122 		{
1123 			PwrSaveIfs[cnt] = 0;
1124 			IPACMDBG("Remove %d power save entry\n", cnt);
1125 			break;
1126 		}
1127 	}
1128 
1129 	for(cnt = 0; cnt < max_entries; cnt++)
1130 	{
1131 		if(cache[cnt].private_ip == ip_addr)
1132 		{
1133 			if(cache[cnt].enabled == true)
1134 			{
1135 				/* send connections del info to pcie modem first */
1136 				if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP) && (cache[cnt].rule_id > 0))
1137 				{
1138 					ret = DelConnection(cache[cnt].rule_id);
1139 					if(ret)
1140 					{
1141 						IPACMERR("unable to del Connection to pcie modem: %d\n", ret);
1142 					}
1143 					else
1144 					{
1145 						/* save the rule id for deletion */
1146 						cache[cnt].rule_id = 0;
1147 					}
1148 				}
1149 
1150 				if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
1151 				{
1152 					IPACMERR("unable to delete the rule\n");
1153 					continue;
1154 				}
1155 				else
1156 				{
1157 					IPACMDBG("won't delete the rule\n");
1158 					cache[cnt].enabled = false;
1159 					tmp++;
1160 				}
1161 			}
1162 			IPACMDBG("won't delete the rule for entry %d, enabled %d\n",cnt, cache[cnt].enabled);
1163 		}
1164 	}
1165 
1166 	IPACMDBG("Deleted (but cached) %d entries\n", tmp);
1167 	return 0;
1168 }
1169 
DelEntriesOnSTAClntDiscon(uint32_t ip_addr)1170 int NatApp::DelEntriesOnSTAClntDiscon(uint32_t ip_addr)
1171 {
1172 	int cnt, tmp = curCnt, ret;
1173 	IPACMDBG_H("Received IP address: 0x%x\n", ip_addr);
1174 
1175 	if(ip_addr == INVALID_IP_ADDR)
1176 	{
1177 		IPACMERR("Invalid ip address received\n");
1178 		return -1;
1179 	}
1180 
1181 
1182 	for(cnt = 0; cnt < max_entries; cnt++)
1183 	{
1184 		if(cache[cnt].target_ip == ip_addr)
1185 		{
1186 			if(cache[cnt].enabled == true)
1187 			{
1188 				/* send connections del info to pcie modem first */
1189 				if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP) && (cache[cnt].rule_id > 0))
1190 				{
1191 					ret = DelConnection(cache[cnt].rule_id);
1192 					if(ret)
1193 					{
1194 						IPACMERR("unable to del Connection to pcie modem: %d\n", ret);
1195 					}
1196 					else
1197 					{
1198 						/* save the rule id for deletion */
1199 						cache[cnt].rule_id = 0;
1200 					}
1201 				}
1202 
1203 				if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
1204 				{
1205 					IPACMERR("unable to delete the rule\n");
1206 					continue;
1207 				}
1208 			}
1209 
1210 			memset(&cache[cnt], 0, sizeof(cache[cnt]));
1211 			curCnt--;
1212 		}
1213 	}
1214 
1215 	IPACMDBG("Deleted %d entries\n", (tmp - curCnt));
1216 	return 0;
1217 }
1218 
CacheEntry(const nat_table_entry * rule)1219 void NatApp::CacheEntry(const nat_table_entry *rule)
1220 {
1221 	int cnt;
1222 
1223 	if(rule->private_ip == 0 ||
1224 		 rule->target_ip == 0 ||
1225 		 rule->private_port == 0  ||
1226 		 rule->target_port == 0 ||
1227 		 rule->protocol == 0)
1228 	{
1229 		IPACMERR("Invalid Connection, ignoring it\n");
1230 		return;
1231 	}
1232 
1233 	if(!ChkForDup(rule))
1234 	{
1235 		for(cnt=0; cnt < max_entries; cnt++)
1236 		{
1237 			if(cache[cnt].private_ip == 0 &&
1238 				 cache[cnt].target_ip == 0 &&
1239 				 cache[cnt].private_port == 0  &&
1240 				 cache[cnt].target_port == 0 &&
1241 				 cache[cnt].protocol == 0)
1242 			{
1243 				break;
1244 			}
1245 		}
1246 
1247 		if(max_entries == cnt)
1248 		{
1249 			IPACMERR("Error: Unable to add, reached maximum rules\n");
1250 			return;
1251 		}
1252 		else
1253 		{
1254 			cache[cnt].enabled = false;
1255 			cache[cnt].rule_hdl = 0;
1256 			cache[cnt].private_ip = rule->private_ip;
1257 			cache[cnt].target_ip = rule->target_ip;
1258 			cache[cnt].target_port = rule->target_port;
1259 			cache[cnt].private_port = rule->private_port;
1260 			cache[cnt].protocol = rule->protocol;
1261 			cache[cnt].timestamp = 0;
1262 			cache[cnt].public_port = rule->public_port;
1263 			cache[cnt].public_ip = rule->public_ip;
1264 			cache[cnt].dst_nat = rule->dst_nat;
1265 			curCnt++;
1266 		}
1267 
1268 	}
1269 	else
1270 	{
1271 		IPACMERR("Duplicate rule. Ignore it\n");
1272 		return;
1273 	}
1274 
1275 	IPACMDBG("Cached rule(%d) successfully\n", cnt);
1276 	return;
1277 }
1278 
Read_TcpUdp_Timeout(void)1279 void NatApp::Read_TcpUdp_Timeout(void) {
1280 #ifdef FEATURE_IPACM_HAL
1281 	tcp_timeout = 432000;
1282 	udp_timeout = 180;
1283 	IPACMDBG_H("udp timeout value: %d\n", udp_timeout);
1284 	IPACMDBG_H("tcp timeout value: %d\n", tcp_timeout);
1285 #else
1286 	FILE *udp_fd = NULL, *tcp_fd = NULL;
1287 	/* Read UDP timeout value */
1288 	udp_fd = fopen(IPACM_UDP_FULL_FILE_NAME, "r");
1289 	if (udp_fd == NULL) {
1290 		IPACMERR("unable to open %s\n", IPACM_UDP_FULL_FILE_NAME);
1291 		goto fail;
1292 	}
1293 
1294 	if (fscanf(udp_fd, "%d", &udp_timeout) != 1) {
1295 		IPACMERR("Error reading udp timeout\n");
1296 	}
1297 	IPACMDBG_H("udp timeout value: %d\n", udp_timeout);
1298 
1299 
1300 	/* Read TCP timeout value */
1301 	tcp_fd = fopen(IPACM_TCP_FULL_FILE_NAME, "r");
1302 	if (tcp_fd == NULL) {
1303 		IPACMERR("unable to open %s\n", IPACM_TCP_FULL_FILE_NAME);
1304 		goto fail;
1305 	}
1306 
1307 
1308 	if (fscanf(tcp_fd, "%d", &tcp_timeout) != 1) {
1309 		IPACMERR("Error reading tcp timeout\n");
1310 	}
1311 	IPACMDBG_H("tcp timeout value: %d\n", tcp_timeout);
1312 
1313 fail:
1314 	if (udp_fd) {
1315 		fclose(udp_fd);
1316 	}
1317 	if (tcp_fd) {
1318 		fclose(tcp_fd);
1319 	}
1320 #endif
1321 	return;
1322 }
1323