1/*
2Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are
6met:
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
17THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <errno.h>
34#include <arpa/inet.h>
35#include <netinet/in.h>
36#include <sys/ioctl.h>
37#include <net/if.h>
38#include "IPACM_Iface.h"
39#include "IPACM_ConntrackListener.h"
40#include "IPACM_ConntrackClient.h"
41#include "IPACM_Log.h"
42
43#define LO_NAME "lo"
44
45extern IPACM_EvtDispatcher cm_dis;
46extern void ParseCTMessage(struct nf_conntrack *ct);
47
48IPACM_ConntrackClient *IPACM_ConntrackClient::pInstance = NULL;
49IPACM_ConntrackListener *CtList = NULL;
50
51/* ================================
52		 Local Function Definitions
53		 =================================
54*/
55IPACM_ConntrackClient::IPACM_ConntrackClient()
56{
57	IPACMDBG("\n");
58
59	tcp_hdl = NULL;
60	udp_hdl = NULL;
61	tcp_filter = NULL;
62	udp_filter = NULL;
63	fd_tcp = -1;
64	fd_udp = -1;
65	subscrips_tcp = NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY;
66	subscrips_udp = NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY;
67}
68
69IPACM_ConntrackClient* IPACM_ConntrackClient::GetInstance()
70{
71	if(pInstance == NULL)
72	{
73		pInstance = new IPACM_ConntrackClient();
74
75		pInstance->udp_filter = nfct_filter_create();
76		if(pInstance->udp_filter == NULL)
77		{
78			IPACMERR("unable to create UDP filter\n");
79			delete pInstance;
80			return NULL;
81		}
82		IPACMDBG("Created UDP filter\n");
83
84		pInstance->tcp_filter = nfct_filter_create();
85		if(pInstance->tcp_filter == NULL)
86		{
87			IPACMERR("unable to create TCP filter\n");
88			delete pInstance;
89			return NULL;
90		}
91		IPACMDBG("Created TCP filter\n");
92	}
93
94	return pInstance;
95}
96
97int IPACM_ConntrackClient::IPAConntrackEventCB
98(
99	 enum nf_conntrack_msg_type type,
100	 struct nf_conntrack *ct,
101	 void *data
102	 )
103{
104	ipacm_cmd_q_data evt_data;
105	ipacm_ct_evt_data *ct_data;
106	uint8_t ip_type = 0;
107	data = NULL;
108
109	IPACMDBG("Event callback called with msgtype: %d\n",type);
110
111	/* Retrieve ip type */
112	ip_type = nfct_get_attr_u8(ct, ATTR_REPL_L3PROTO);
113
114#ifndef CT_OPT
115	if(AF_INET6 == ip_type)
116	{
117		IPACMDBG("Ignoring ipv6(%d) connections\n", ip_type);
118		goto IGNORE;
119	}
120
121#endif
122
123	ct_data = (ipacm_ct_evt_data *)malloc(sizeof(ipacm_ct_evt_data));
124	if(ct_data == NULL)
125	{
126		IPACMERR("unable to allocate memory \n");
127		goto IGNORE;
128	}
129
130	ct_data->ct = ct;
131	ct_data->type = type;
132
133	evt_data.event = IPA_PROCESS_CT_MESSAGE;
134	evt_data.evt_data = (void *)ct_data;
135
136#ifdef CT_OPT
137	if(AF_INET6 == ip_type)
138	{
139		evt_data.event = IPA_PROCESS_CT_MESSAGE_V6;
140	}
141#endif
142
143	if(0 != IPACM_EvtDispatcher::PostEvt(&evt_data))
144	{
145		IPACMERR("Error sending Conntrack message to processing thread!\n");
146		free(ct_data);
147		goto IGNORE;
148	}
149
150/* NFCT_CB_STOLEN means that the conntrack object is not released after the
151	 callback That must be manually done later when the object is no longer needed. */
152	return NFCT_CB_STOLEN;
153
154IGNORE:
155	nfct_destroy(ct);
156	return NFCT_CB_STOLEN;
157
158}
159
160int IPACM_ConntrackClient::IPA_Conntrack_Filters_Ignore_Bridge_Addrs
161(
162	 struct nfct_filter *filter
163)
164{
165	int fd;
166	fd = socket(AF_INET, SOCK_DGRAM, 0);
167	if(fd < 0)
168	{
169		PERROR("unable to open socket");
170		return -1;
171	}
172
173	int ret;
174	uint32_t ipv4_addr;
175	struct ifreq ifr;
176
177	if(strlen(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name) >= sizeof(ifr.ifr_name))
178	{
179		IPACMERR("interface name overflows: len %zu\n",
180			strlen(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name));
181		close(fd);
182		return -1;
183	}
184
185	/* retrieve bridge interface ipv4 address */
186	memset(&ifr, 0, sizeof(struct ifreq));
187	ifr.ifr_addr.sa_family = AF_INET;
188	(void)strlcpy(ifr.ifr_name, IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, sizeof(ifr.ifr_name));
189	IPACMDBG("bridge interface name (%s)\n", ifr.ifr_name);
190
191	ret = ioctl(fd, SIOCGIFADDR, &ifr);
192	if (ret < 0)
193	{
194		IPACMERR("unable to retrieve (%s) interface address\n",ifr.ifr_name);
195		close(fd);
196		return -1;
197	}
198	IPACMDBG("Interface (%s) address %s\n", ifr.ifr_name, inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
199	ipv4_addr = ntohl(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr);
200	close(fd);
201
202	/* ignore whatever is destined to or originates from broadcast ip address */
203	struct nfct_filter_ipv4 filter_ipv4;
204
205	filter_ipv4.addr = ipv4_addr;
206	filter_ipv4.mask = 0xffffffff;
207
208	nfct_filter_set_logic(filter,
209												NFCT_FILTER_DST_IPV4,
210												NFCT_FILTER_LOGIC_NEGATIVE);
211
212	nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
213
214	nfct_filter_set_logic(filter,
215												NFCT_FILTER_SRC_IPV4,
216												NFCT_FILTER_LOGIC_NEGATIVE);
217
218	nfct_filter_add_attr(filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4);
219
220  return 0;
221}
222
223int IPACM_ConntrackClient::IPA_Conntrack_Filters_Ignore_Local_Iface
224(
225	 struct nfct_filter *filter,
226	 ipacm_event_iface_up *param
227)
228{
229	struct nfct_filter_ipv4 filter_ipv4;
230
231	filter_ipv4.addr = param->ipv4_addr;
232	filter_ipv4.mask = 0xffffffff;
233
234	/* ignore whatever is destined to local interfaces */
235	IPACMDBG("Ignore connections destinated to interface %s", param->ifname);
236	iptodot("with ipv4 address", param->ipv4_addr);
237	nfct_filter_set_logic(filter,
238												NFCT_FILTER_DST_IPV4,
239												NFCT_FILTER_LOGIC_NEGATIVE);
240
241	nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
242
243	IPACMDBG("Ignore connections orignated from interface %s", param->ifname);
244	iptodot("with ipv4 address", filter_ipv4.addr);
245	nfct_filter_set_logic(filter,
246												NFCT_FILTER_SRC_IPV4,
247												NFCT_FILTER_LOGIC_NEGATIVE);
248
249	nfct_filter_add_attr(filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4);
250
251	/* Retrieve broadcast address */
252	/* Intialize with 255.255.255.255 */
253	uint32_t bc_ip_addr = 0xFFFFFFFF;
254
255	/* calculate broadcast address from addr and addr_mask */
256	bc_ip_addr = (bc_ip_addr & (~param->addr_mask));
257	bc_ip_addr = (bc_ip_addr | (param->ipv4_addr & param->addr_mask));
258
259	/* netfitler expecting in host-byte order */
260	filter_ipv4.addr = bc_ip_addr;
261	filter_ipv4.mask = 0xffffffff;
262
263	iptodot("with broadcast address", filter_ipv4.addr);
264	nfct_filter_set_logic(filter,
265												NFCT_FILTER_DST_IPV4,
266												NFCT_FILTER_LOGIC_NEGATIVE);
267
268	nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
269
270	return 0;
271}
272
273/* Function which sets up filters to ignore
274		 connections to and from local interfaces */
275int IPACM_ConntrackClient::IPA_Conntrack_Filters_Ignore_Local_Addrs
276(
277	 struct nfct_filter *filter
278)
279{
280	struct nfct_filter_ipv4 filter_ipv4;
281
282	/* ignore whatever is destined to or originates from broadcast ip address */
283	filter_ipv4.addr = 0xffffffff;
284	filter_ipv4.mask = 0xffffffff;
285
286	nfct_filter_set_logic(filter,
287												NFCT_FILTER_DST_IPV4,
288												NFCT_FILTER_LOGIC_NEGATIVE);
289
290	nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
291
292	nfct_filter_set_logic(filter,
293												NFCT_FILTER_SRC_IPV4,
294												NFCT_FILTER_LOGIC_NEGATIVE);
295
296	nfct_filter_add_attr(filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4);
297
298	return 0;
299} /* IPA_Conntrack_Filters_Ignore_Local_Addrs() */
300
301/* Initialize TCP Filter */
302int IPACM_ConntrackClient::IPA_Conntrack_TCP_Filter_Init(void)
303{
304	int ret = 0;
305	IPACM_ConntrackClient *pClient;
306
307	IPACMDBG("\n");
308
309	pClient = IPACM_ConntrackClient::GetInstance();
310	if(pClient == NULL)
311	{
312		IPACMERR("unable to get conntrack client instance\n");
313		return -1;
314	}
315
316	ret = nfct_filter_set_logic(pClient->tcp_filter,
317															NFCT_FILTER_L4PROTO,
318															NFCT_FILTER_LOGIC_POSITIVE);
319	if(ret == -1)
320	{
321		IPACMERR("Unable to set filter logic\n");
322		return -1;
323	}
324
325	/* set protocol filters as tcp and udp */
326	nfct_filter_add_attr_u32(pClient->tcp_filter, NFCT_FILTER_L4PROTO, IPPROTO_TCP);
327
328
329	struct nfct_filter_proto tcp_proto_state;
330	tcp_proto_state.proto = IPPROTO_TCP;
331	tcp_proto_state.state = TCP_CONNTRACK_ESTABLISHED;
332
333	ret = nfct_filter_set_logic(pClient->tcp_filter,
334															NFCT_FILTER_L4PROTO_STATE,
335															NFCT_FILTER_LOGIC_POSITIVE);
336	if(ret == -1)
337	{
338		IPACMERR("unable to set filter logic\n");
339		return -1;
340	}
341	nfct_filter_add_attr(pClient->tcp_filter,
342											 NFCT_FILTER_L4PROTO_STATE,
343											 &tcp_proto_state);
344
345
346	tcp_proto_state.proto = IPPROTO_TCP;
347	tcp_proto_state.state = TCP_CONNTRACK_FIN_WAIT;
348	ret = nfct_filter_set_logic(pClient->tcp_filter,
349															NFCT_FILTER_L4PROTO_STATE,
350															NFCT_FILTER_LOGIC_POSITIVE);
351	if(ret == -1)
352	{
353		IPACMERR("unable to set filter logic\n");
354		return -1;
355	}
356
357	nfct_filter_add_attr(pClient->tcp_filter,
358											 NFCT_FILTER_L4PROTO_STATE,
359											 &tcp_proto_state);
360	return 0;
361}
362
363
364/* Initialize UDP Filter */
365int IPACM_ConntrackClient::IPA_Conntrack_UDP_Filter_Init(void)
366{
367	int ret = 0;
368	IPACM_ConntrackClient *pClient = IPACM_ConntrackClient::GetInstance();
369	if(pClient == NULL)
370	{
371		IPACMERR("unable to get conntrack client instance\n");
372		return -1;
373	}
374
375	ret = nfct_filter_set_logic(pClient->udp_filter,
376															NFCT_FILTER_L4PROTO,
377															NFCT_FILTER_LOGIC_POSITIVE);
378	if(ret == -1)
379	{
380		IPACMERR("unable to set filter logic\n");
381	}
382	/* set protocol filters as tcp and udp */
383	nfct_filter_add_attr_u32(pClient->udp_filter, NFCT_FILTER_L4PROTO, IPPROTO_UDP);
384
385	return 0;
386}
387
388void* IPACM_ConntrackClient::UDPConnTimeoutUpdate(void *ptr)
389{
390
391	NatApp *nat_inst = NULL;
392	ptr = NULL;
393#ifdef IPACM_DEBUG
394	IPACMDBG("\n");
395#endif
396
397	nat_inst = NatApp::GetInstance();
398	if(nat_inst == NULL)
399	{
400		IPACMERR("unable to create nat instance\n");
401		return NULL;
402	}
403
404	while(1)
405	{
406		nat_inst->UpdateUDPTimeStamp();
407		sleep(UDP_TIMEOUT_UPDATE);
408	} /* end of while(1) loop */
409
410#ifdef IPACM_DEBUG
411	IPACMDBG("Returning from %s() %d\n", __FUNCTION__, __LINE__);
412#endif
413
414	return NULL;
415}
416
417/* Thread to initialize TCP Conntrack Filters*/
418void* IPACM_ConntrackClient::TCPRegisterWithConnTrack(void *)
419{
420	int ret;
421	IPACM_ConntrackClient *pClient;
422	unsigned subscrips = 0;
423
424	IPACMDBG("\n");
425
426	pClient = IPACM_ConntrackClient::GetInstance();
427	if(pClient == NULL)
428	{
429		IPACMERR("unable to get conntrack client instance\n");
430		return NULL;
431	}
432
433	subscrips = (NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY);
434#ifdef CT_OPT
435	subscrips |= NF_NETLINK_CONNTRACK_NEW;
436#endif
437
438#ifdef FEATURE_IPACM_HAL
439	if (pClient->fd_tcp < 0) {
440		IPACMERR("unable to get conntrack TCP handle due to fd_tcp is invalid \n");
441		return NULL;
442	} else {
443		pClient->tcp_hdl = nfct_open2(CONNTRACK, subscrips, pClient->fd_tcp);
444	}
445#else
446	pClient->tcp_hdl = nfct_open(CONNTRACK, subscrips);
447#endif
448
449	if(pClient->tcp_hdl == NULL)
450	{
451		PERROR("nfct_open failed on getting tcp_hdl\n");
452		return NULL;
453	}
454
455	/* Initialize the filter */
456	ret = IPA_Conntrack_TCP_Filter_Init();
457	if(ret == -1)
458	{
459		IPACMERR("Unable to initliaze TCP Filter\n");
460		return NULL;
461	}
462
463	/* Attach the filter to net filter handler */
464	ret = nfct_filter_attach(nfct_fd(pClient->tcp_hdl), pClient->tcp_filter);
465	if(ret == -1)
466	{
467		IPACMDBG("unable to attach TCP filter\n");
468		return NULL;
469	}
470
471	/* Register callback with netfilter handler */
472	IPACMDBG_H("tcp handle:%p, fd:%d\n", pClient->tcp_hdl, nfct_fd(pClient->tcp_hdl));
473#ifndef CT_OPT
474	nfct_callback_register(pClient->tcp_hdl,
475			(nf_conntrack_msg_type)	(NFCT_T_UPDATE | NFCT_T_DESTROY | NFCT_T_NEW),
476						IPAConntrackEventCB, NULL);
477#else
478	nfct_callback_register(pClient->tcp_hdl, (nf_conntrack_msg_type) NFCT_T_ALL, IPAConntrackEventCB, NULL);
479#endif
480
481	/* Block to catch events from net filter connection track */
482	/* nfct_catch() receives conntrack events from kernel-space, by default it
483			 blocks waiting for events. */
484	IPACMDBG("Waiting for events\n");
485
486	ret = nfct_catch(pClient->tcp_hdl);
487	if(ret == -1)
488	{
489		IPACMERR("(%d)(%s)\n", ret, strerror(errno));
490		return NULL;
491	}
492
493	IPACMDBG("Exit from tcp thread\n");
494
495	/* destroy the filter.. this will not detach the filter */
496	nfct_filter_destroy(pClient->tcp_filter);
497	pClient->tcp_filter = NULL;
498
499	/* de-register the callback */
500	nfct_callback_unregister(pClient->tcp_hdl);
501	/* close the handle */
502#ifdef FEATURE_IPACM_HAL
503	nfct_close2(pClient->tcp_hdl, true);
504#else
505	nfct_close(pClient->tcp_hdl);
506#endif
507	pClient->tcp_hdl = NULL;
508
509	pthread_exit(NULL);
510	return NULL;
511}
512
513/* Thread to initialize UDP Conntrack Filters*/
514void* IPACM_ConntrackClient::UDPRegisterWithConnTrack(void *)
515{
516	int ret;
517	IPACM_ConntrackClient *pClient = NULL;
518
519	IPACMDBG("\n");
520
521	pClient = IPACM_ConntrackClient::GetInstance();
522	if(pClient == NULL)
523	{
524		IPACMERR("unable to retrieve instance of conntrack client\n");
525		return NULL;
526	}
527
528#ifdef FEATURE_IPACM_HAL
529	if (pClient->fd_udp < 0) {
530		IPACMERR("unable to get conntrack UDP handle due to fd_udp is invalid \n");
531		return NULL;
532	} else {
533		pClient->udp_hdl = nfct_open2(CONNTRACK,
534					(NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY), pClient->fd_udp);
535	}
536#else
537	pClient->udp_hdl = nfct_open(CONNTRACK,
538					(NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY));
539#endif
540	if(pClient->udp_hdl == NULL)
541	{
542		PERROR("nfct_open failed on getting udp_hdl\n");
543		return NULL;
544	}
545
546	/* Initialize Filter */
547	ret = IPA_Conntrack_UDP_Filter_Init();
548	if(-1 == ret)
549	{
550		IPACMDBG("Unable to initalize udp filters\n");
551		return NULL;
552	}
553
554	/* Attach the filter to net filter handler */
555	ret = nfct_filter_attach(nfct_fd(pClient->udp_hdl), pClient->udp_filter);
556	if(ret == -1)
557	{
558		IPACMDBG("unable to attach the filter\n");
559		return NULL;
560	}
561
562	/* Register callback with netfilter handler */
563	IPACMDBG_H("udp handle:%p, fd:%d\n", pClient->udp_hdl, nfct_fd(pClient->udp_hdl));
564	nfct_callback_register(pClient->udp_hdl,
565			(nf_conntrack_msg_type)(NFCT_T_NEW | NFCT_T_DESTROY),
566			IPAConntrackEventCB,
567			NULL);
568
569	/* Block to catch events from net filter connection track */
570ctcatch:
571	ret = nfct_catch(pClient->udp_hdl);
572	if(ret == -1)
573	{
574		IPACMDBG("(%d)(%s)\n", ret, strerror(errno));
575		return NULL;
576	}
577	else
578	{
579		IPACMDBG("ctcatch ret:%d\n", ret);
580		goto ctcatch;
581	}
582
583	IPACMDBG("Exit from udp thread with ret: %d\n", ret);
584
585	/* destroy the filter.. this will not detach the filter */
586	nfct_filter_destroy(pClient->udp_filter);
587	pClient->udp_filter = NULL;
588
589	/* de-register the callback */
590	nfct_callback_unregister(pClient->udp_hdl);
591	/* close the handle */
592#ifdef FEATURE_IPACM_HAL
593	nfct_close2(pClient->udp_hdl, true);
594#else
595	nfct_close(pClient->udp_hdl);
596#endif
597	pClient->udp_hdl = NULL;
598
599	pthread_exit(NULL);
600	return NULL;
601}
602
603/* Thread to initialize TCP Conntrack Filters*/
604void IPACM_ConntrackClient::UNRegisterWithConnTrack(void)
605{
606	IPACM_ConntrackClient *pClient = NULL;
607
608	IPACMDBG("\n");
609
610	pClient = IPACM_ConntrackClient::GetInstance();
611	if(pClient == NULL)
612	{
613		IPACMERR("unable to retrieve instance of conntrack client\n");
614		return;
615	}
616
617	/* destroy the TCP filter.. this will not detach the filter */
618	if (pClient->tcp_filter) {
619		nfct_filter_destroy(pClient->tcp_filter);
620		pClient->tcp_filter = NULL;
621	}
622
623	/* de-register the callback */
624	if (pClient->tcp_hdl) {
625		nfct_callback_unregister(pClient->tcp_hdl);
626		/* close the handle */
627		nfct_close(pClient->tcp_hdl);
628		pClient->tcp_hdl = NULL;
629	}
630
631	/* destroy the filter.. this will not detach the filter */
632	if (pClient->udp_filter) {
633		nfct_filter_destroy(pClient->udp_filter);
634		pClient->udp_filter = NULL;
635	}
636
637	/* de-register the callback */
638	if (pClient->udp_hdl) {
639		nfct_callback_unregister(pClient->udp_hdl);
640		/* close the handle */
641		nfct_close(pClient->udp_hdl);
642		pClient->udp_hdl = NULL;
643	}
644
645	pClient->fd_tcp = -1;
646	pClient->fd_udp = -1;
647
648	return;
649}
650
651void IPACM_ConntrackClient::UpdateUDPFilters(void *param, bool isWan)
652{
653	static bool isIgnore = false;
654	int ret = 0;
655	IPACM_ConntrackClient *pClient = NULL;
656
657	pClient = IPACM_ConntrackClient::GetInstance();
658	if(pClient == NULL)
659	{
660		IPACMERR("unable to retrieve conntrack client instance\n");
661		return;
662	}
663
664	if(pClient->udp_filter == NULL)
665	{
666		 return;
667	}
668
669	if(!isWan)
670	{
671		IPA_Conntrack_Filters_Ignore_Local_Iface(pClient->udp_filter,
672																		 (ipacm_event_iface_up *)param);
673
674		if(!isIgnore)
675		{
676			IPA_Conntrack_Filters_Ignore_Bridge_Addrs(pClient->udp_filter);
677			IPA_Conntrack_Filters_Ignore_Local_Addrs(pClient->udp_filter);
678			isIgnore = true;
679		}
680	}
681
682	/* Attach the filter to udp handle */
683	if(pClient->udp_hdl != NULL)
684	{
685		IPACMDBG("attaching the filter to udp handle\n");
686		ret = nfct_filter_attach(nfct_fd(pClient->udp_hdl), pClient->udp_filter);
687		if(ret == -1)
688		{
689			PERROR("unable to attach the filter to udp handle\n");
690			IPACMERR("udp handle:%p, fd:%d Error: %d\n",pClient->udp_hdl, nfct_fd(pClient->udp_hdl), ret);
691			return;
692		}
693	}
694
695	return;
696}
697
698void IPACM_ConntrackClient::UpdateTCPFilters(void *param, bool isWan)
699{
700	static bool isIgnore = false;
701	int ret = 0;
702	IPACM_ConntrackClient *pClient = NULL;
703
704	pClient = IPACM_ConntrackClient::GetInstance();
705	if(pClient == NULL)
706	{
707		IPACMERR("unable to retrieve conntrack client instance\n");
708		return;
709	}
710
711	if(pClient->tcp_filter == NULL)
712		return;
713
714	if(!isWan)
715	{
716		IPA_Conntrack_Filters_Ignore_Local_Iface(pClient->tcp_filter,
717																	(ipacm_event_iface_up *)param);
718
719		if(!isIgnore)
720		{
721			IPA_Conntrack_Filters_Ignore_Bridge_Addrs(pClient->udp_filter);
722			IPA_Conntrack_Filters_Ignore_Local_Addrs(pClient->udp_filter);
723			isIgnore = true;
724		}
725	}
726
727	/* Attach the filter to tcp handle */
728	if(pClient->tcp_hdl != NULL)
729	{
730		IPACMDBG("attaching the filter to tcp handle\n");
731		ret = nfct_filter_attach(nfct_fd(pClient->tcp_hdl), pClient->tcp_filter);
732		if(ret == -1)
733		{
734			PERROR("unable to attach the filter to tcp handle\n");
735			IPACMERR("tcp handle:%p, fd:%d Error: %d\n",pClient->tcp_hdl, nfct_fd(pClient->tcp_hdl), ret);
736			return;
737		}
738	}
739
740  return;
741}
742
743