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 
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 
45 extern IPACM_EvtDispatcher cm_dis;
46 extern void ParseCTMessage(struct nf_conntrack *ct);
47 
48 IPACM_ConntrackClient *IPACM_ConntrackClient::pInstance = NULL;
49 IPACM_ConntrackListener *CtList = NULL;
50 
51 /* ================================
52 		 Local Function Definitions
53 		 =================================
54 */
IPACM_ConntrackClient()55 IPACM_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 
GetInstance()69 IPACM_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 
IPAConntrackEventCB(enum nf_conntrack_msg_type type,struct nf_conntrack * ct,void * data)97 int 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 
154 IGNORE:
155 	nfct_destroy(ct);
156 	return NFCT_CB_STOLEN;
157 
158 }
159 
IPA_Conntrack_Filters_Ignore_Bridge_Addrs(struct nfct_filter * filter)160 int 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 	/* retrieve bridge interface ipv4 address */
178 	memset(&ifr, 0, sizeof(struct ifreq));
179 	ifr.ifr_addr.sa_family = AF_INET;
180 
181 	if(strlen(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name) >= sizeof(ifr.ifr_name))
182 	{
183 		IPACMERR("interface name overflows: len %zu\n",
184 			strlen(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name));
185 		close(fd);
186 		return -1;
187 	}
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 
IPA_Conntrack_Filters_Ignore_Local_Iface(struct nfct_filter * filter,ipacm_event_iface_up * param)223 int 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 */
IPA_Conntrack_Filters_Ignore_Local_Addrs(struct nfct_filter * filter)275 int 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 */
IPA_Conntrack_TCP_Filter_Init(void)302 int 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 */
IPA_Conntrack_UDP_Filter_Init(void)365 int 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 
UDPConnTimeoutUpdate(void * ptr)388 void* IPACM_ConntrackClient::UDPConnTimeoutUpdate(void *ptr)
389 {
390 	NatApp *nat_inst = NULL;
391 	ptr = NULL;
392 #ifdef IPACM_DEBUG
393 	IPACMDBG("\n");
394 #endif
395 
396 	nat_inst = NatApp::GetInstance();
397 	if(nat_inst == NULL)
398 	{
399 		IPACMERR("unable to create nat instance\n");
400 		return NULL;
401 	}
402 
403 	while(1)
404 	{
405 		nat_inst->UpdateUDPTimeStamp();
406 		sleep(UDP_TIMEOUT_UPDATE);
407 	} /* end of while(1) loop */
408 
409 #ifdef IPACM_DEBUG
410 	IPACMDBG("Returning from %s() %d\n", __FUNCTION__, __LINE__);
411 #endif
412 
413 	return NULL;
414 }
415 
416 /* Thread to initialize TCP Conntrack Filters*/
TCPRegisterWithConnTrack(void *)417 void* IPACM_ConntrackClient::TCPRegisterWithConnTrack(void *)
418 {
419 	int ret;
420 	IPACM_ConntrackClient *pClient;
421 	unsigned subscrips = 0;
422 
423 	IPACMDBG("\n");
424 
425 	pClient = IPACM_ConntrackClient::GetInstance();
426 	if(pClient == NULL)
427 	{
428 		IPACMERR("unable to get conntrack client instance\n");
429 		return NULL;
430 	}
431 
432 	subscrips = (NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY);
433 #ifdef CT_OPT
434 	subscrips |= NF_NETLINK_CONNTRACK_NEW;
435 #endif
436 
437 #ifdef FEATURE_IPACM_HAL
438 	if (pClient->fd_tcp < 0) {
439 		IPACMERR("unable to get conntrack TCP handle due to fd_tcp is invalid \n");
440 		return NULL;
441 	} else {
442 		pClient->tcp_hdl = nfct_open2(CONNTRACK, subscrips, pClient->fd_tcp);
443 	}
444 #else
445 	pClient->tcp_hdl = nfct_open(CONNTRACK, subscrips);
446 #endif
447 
448 	if(pClient->tcp_hdl == NULL)
449 	{
450 		PERROR("nfct_open failed on getting tcp_hdl\n");
451 		return NULL;
452 	}
453 
454 	/* Initialize the filter */
455 	ret = IPA_Conntrack_TCP_Filter_Init();
456 	if(ret == -1)
457 	{
458 		IPACMERR("Unable to initliaze TCP Filter\n");
459 		return NULL;
460 	}
461 
462 	/* Attach the filter to net filter handler */
463 	ret = nfct_filter_attach(nfct_fd(pClient->tcp_hdl), pClient->tcp_filter);
464 	if(ret == -1)
465 	{
466 		IPACMDBG("unable to attach TCP filter\n");
467 		return NULL;
468 	}
469 
470 	/* Register callback with netfilter handler */
471 	IPACMDBG_H("tcp handle:%pK, fd:%d\n", pClient->tcp_hdl, nfct_fd(pClient->tcp_hdl));
472 #ifndef CT_OPT
473 	nfct_callback_register(pClient->tcp_hdl,
474 			(nf_conntrack_msg_type)	(NFCT_T_UPDATE | NFCT_T_DESTROY | NFCT_T_NEW),
475 						IPAConntrackEventCB, NULL);
476 #else
477 	nfct_callback_register(pClient->tcp_hdl, (nf_conntrack_msg_type) NFCT_T_ALL, IPAConntrackEventCB, NULL);
478 #endif
479 
480 	/* Block to catch events from net filter connection track */
481 	/* nfct_catch() receives conntrack events from kernel-space, by default it
482 			 blocks waiting for events. */
483 	IPACMDBG("Waiting for events\n");
484 
485 	ret = nfct_catch(pClient->tcp_hdl);
486 	if(ret == -1)
487 	{
488 		IPACMERR("(%d)(%s)\n", ret, strerror(errno));
489 		return NULL;
490 	}
491 
492 	IPACMDBG("Exit from tcp thread\n");
493 
494 	/* destroy the filter.. this will not detach the filter */
495 	nfct_filter_destroy(pClient->tcp_filter);
496 	pClient->tcp_filter = NULL;
497 
498 	/* de-register the callback */
499 	nfct_callback_unregister(pClient->tcp_hdl);
500 	/* close the handle */
501 #ifdef FEATURE_IPACM_HAL
502 	nfct_close2(pClient->tcp_hdl, true);
503 #else
504 	nfct_close(pClient->tcp_hdl);
505 #endif
506 	pClient->tcp_hdl = NULL;
507 
508 	pthread_exit(NULL);
509 	return NULL;
510 }
511 
512 /* Thread to initialize UDP Conntrack Filters*/
UDPRegisterWithConnTrack(void *)513 void* IPACM_ConntrackClient::UDPRegisterWithConnTrack(void *)
514 {
515 	int ret;
516 	IPACM_ConntrackClient *pClient = NULL;
517 
518 	IPACMDBG("\n");
519 
520 	pClient = IPACM_ConntrackClient::GetInstance();
521 	if(pClient == NULL)
522 	{
523 		IPACMERR("unable to retrieve instance of conntrack client\n");
524 		return NULL;
525 	}
526 
527 #ifdef FEATURE_IPACM_HAL
528 	if (pClient->fd_udp < 0) {
529 		IPACMERR("unable to get conntrack UDP handle due to fd_udp is invalid \n");
530 		return NULL;
531 	} else {
532 		pClient->udp_hdl = nfct_open2(CONNTRACK,
533 					(NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY), pClient->fd_udp);
534 	}
535 #else
536 	pClient->udp_hdl = nfct_open(CONNTRACK,
537 					(NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY));
538 #endif
539 	if(pClient->udp_hdl == NULL)
540 	{
541 		PERROR("nfct_open failed on getting udp_hdl\n");
542 		return NULL;
543 	}
544 
545 	/* Initialize Filter */
546 	ret = IPA_Conntrack_UDP_Filter_Init();
547 	if(-1 == ret)
548 	{
549 		IPACMDBG("Unable to initalize udp filters\n");
550 		return NULL;
551 	}
552 
553 	/* Attach the filter to net filter handler */
554 	ret = nfct_filter_attach(nfct_fd(pClient->udp_hdl), pClient->udp_filter);
555 	if(ret == -1)
556 	{
557 		IPACMDBG("unable to attach the filter\n");
558 		return NULL;
559 	}
560 
561 	/* Register callback with netfilter handler */
562 	IPACMDBG_H("udp handle:%pK, fd:%d\n", pClient->udp_hdl, nfct_fd(pClient->udp_hdl));
563 	nfct_callback_register(pClient->udp_hdl,
564 			(nf_conntrack_msg_type)(NFCT_T_NEW | NFCT_T_DESTROY),
565 			IPAConntrackEventCB,
566 			NULL);
567 
568 	/* Block to catch events from net filter connection track */
569 ctcatch:
570 	ret = nfct_catch(pClient->udp_hdl);
571 	if(ret == -1)
572 	{
573 		IPACMDBG("(%d)(%s)\n", ret, strerror(errno));
574 		return NULL;
575 	}
576 	else
577 	{
578 		IPACMDBG("ctcatch ret:%d\n", ret);
579 		goto ctcatch;
580 	}
581 
582 	IPACMDBG("Exit from udp thread with ret: %d\n", ret);
583 
584 	/* destroy the filter.. this will not detach the filter */
585 	nfct_filter_destroy(pClient->udp_filter);
586 	pClient->udp_filter = NULL;
587 
588 	/* de-register the callback */
589 	nfct_callback_unregister(pClient->udp_hdl);
590 	/* close the handle */
591 #ifdef FEATURE_IPACM_HAL
592 	nfct_close2(pClient->udp_hdl, true);
593 #else
594 	nfct_close(pClient->udp_hdl);
595 #endif
596 	pClient->udp_hdl = NULL;
597 
598 	pthread_exit(NULL);
599 	return NULL;
600 }
601 
602 /* Thread to initialize TCP Conntrack Filters*/
UNRegisterWithConnTrack(void)603 void IPACM_ConntrackClient::UNRegisterWithConnTrack(void)
604 {
605 	IPACM_ConntrackClient *pClient = NULL;
606 
607 	IPACMDBG("\n");
608 
609 	pClient = IPACM_ConntrackClient::GetInstance();
610 	if(pClient == NULL)
611 	{
612 		IPACMERR("unable to retrieve instance of conntrack client\n");
613 		return;
614 	}
615 
616 	/* destroy the TCP filter.. this will not detach the filter */
617 	if (pClient->tcp_filter) {
618 		nfct_filter_destroy(pClient->tcp_filter);
619 		pClient->tcp_filter = NULL;
620 	}
621 
622 	/* de-register the callback */
623 	if (pClient->tcp_hdl) {
624 		nfct_callback_unregister(pClient->tcp_hdl);
625 		/* close the handle */
626 		nfct_close(pClient->tcp_hdl);
627 		pClient->tcp_hdl = NULL;
628 	}
629 
630 	/* destroy the filter.. this will not detach the filter */
631 	if (pClient->udp_filter) {
632 		nfct_filter_destroy(pClient->udp_filter);
633 		pClient->udp_filter = NULL;
634 	}
635 
636 	/* de-register the callback */
637 	if (pClient->udp_hdl) {
638 		nfct_callback_unregister(pClient->udp_hdl);
639 		/* close the handle */
640 		nfct_close(pClient->udp_hdl);
641 		pClient->udp_hdl = NULL;
642 	}
643 
644 	pClient->fd_tcp = -1;
645 	pClient->fd_udp = -1;
646 
647 	return;
648 }
649 
UpdateUDPFilters(void * param,bool isWan)650 void IPACM_ConntrackClient::UpdateUDPFilters(void *param, bool isWan)
651 {
652 	static bool isIgnore = false;
653 	int ret = 0;
654 	IPACM_ConntrackClient *pClient = NULL;
655 
656 	pClient = IPACM_ConntrackClient::GetInstance();
657 	if(pClient == NULL)
658 	{
659 		IPACMERR("unable to retrieve conntrack client instance\n");
660 		return;
661 	}
662 
663 	if(pClient->udp_filter == NULL)
664 	{
665 		 return;
666 	}
667 
668 	if(!isWan)
669 	{
670 		IPA_Conntrack_Filters_Ignore_Local_Iface(pClient->udp_filter,
671 																		 (ipacm_event_iface_up *)param);
672 
673 		if(!isIgnore)
674 		{
675 			IPA_Conntrack_Filters_Ignore_Bridge_Addrs(pClient->udp_filter);
676 			IPA_Conntrack_Filters_Ignore_Local_Addrs(pClient->udp_filter);
677 			isIgnore = true;
678 		}
679 	}
680 
681 	/* Attach the filter to udp handle */
682 	if(pClient->udp_hdl != NULL)
683 	{
684 		IPACMDBG("attaching the filter to udp handle\n");
685 		ret = nfct_filter_attach(nfct_fd(pClient->udp_hdl), pClient->udp_filter);
686 		if(ret == -1)
687 		{
688 			PERROR("unable to attach the filter to udp handle\n");
689 			IPACMERR("udp handle:%pK, fd:%d Error: %d\n",pClient->udp_hdl, nfct_fd(pClient->udp_hdl), ret);
690 			return;
691 		}
692 	}
693 
694 	return;
695 }
696 
UpdateTCPFilters(void * param,bool isWan)697 void IPACM_ConntrackClient::UpdateTCPFilters(void *param, bool isWan)
698 {
699 	static bool isIgnore = false;
700 	int ret = 0;
701 	IPACM_ConntrackClient *pClient = NULL;
702 
703 	pClient = IPACM_ConntrackClient::GetInstance();
704 	if(pClient == NULL)
705 	{
706 		IPACMERR("unable to retrieve conntrack client instance\n");
707 		return;
708 	}
709 
710 	if(pClient->tcp_filter == NULL)
711 		return;
712 
713 	if(!isWan)
714 	{
715 		IPA_Conntrack_Filters_Ignore_Local_Iface(pClient->tcp_filter,
716 																	(ipacm_event_iface_up *)param);
717 
718 		if(!isIgnore)
719 		{
720 			IPA_Conntrack_Filters_Ignore_Bridge_Addrs(pClient->udp_filter);
721 			IPA_Conntrack_Filters_Ignore_Local_Addrs(pClient->udp_filter);
722 			isIgnore = true;
723 		}
724 	}
725 
726 	/* Attach the filter to tcp handle */
727 	if(pClient->tcp_hdl != NULL)
728 	{
729 		IPACMDBG("attaching the filter to tcp handle\n");
730 		ret = nfct_filter_attach(nfct_fd(pClient->tcp_hdl), pClient->tcp_filter);
731 		if(ret == -1)
732 		{
733 			PERROR("unable to attach the filter to tcp handle\n");
734 			IPACMERR("tcp handle:%pK, fd:%d Error: %d\n",pClient->tcp_hdl, nfct_fd(pClient->tcp_hdl), ret);
735 			return;
736 		}
737 	}
738 
739   return;
740 }
741 
742