Home | History | Annotate | Download | only in src
      1 /*
      2 Copyright (c) 2013-2016, 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 */
     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 
     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 
     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 
    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 	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 
    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 */
    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 */
    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 */
    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 
    388 void* 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*/
    418 void* 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*/
    514 void* 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 */
    570 ctcatch:
    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*/
    604 void 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 
    651 void 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 
    698 void 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