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