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 ctcatch:
486 ret = nfct_catch(pClient->tcp_hdl);
487 if((ret == -1) && (errno != ENOMSG))
488 {
489 IPACMERR("(%d)(%d)(%s)\n", ret, errno, strerror(errno));
490 return NULL;
491 }
492 else
493 {
494 IPACMDBG("ctcatch ret:%d, errno:%d\n", ret, errno);
495 goto ctcatch;
496 }
497
498 IPACMDBG("Exit from tcp thread\n");
499
500 /* destroy the filter.. this will not detach the filter */
501 nfct_filter_destroy(pClient->tcp_filter);
502 pClient->tcp_filter = NULL;
503
504 /* de-register the callback */
505 nfct_callback_unregister(pClient->tcp_hdl);
506 /* close the handle */
507 #ifdef FEATURE_IPACM_HAL
508 nfct_close2(pClient->tcp_hdl, true);
509 #else
510 nfct_close(pClient->tcp_hdl);
511 #endif
512 pClient->tcp_hdl = NULL;
513
514 pthread_exit(NULL);
515 return NULL;
516 }
517
518 /* Thread to initialize UDP Conntrack Filters*/
UDPRegisterWithConnTrack(void *)519 void* IPACM_ConntrackClient::UDPRegisterWithConnTrack(void *)
520 {
521 int ret;
522 IPACM_ConntrackClient *pClient = NULL;
523
524 IPACMDBG("\n");
525
526 pClient = IPACM_ConntrackClient::GetInstance();
527 if(pClient == NULL)
528 {
529 IPACMERR("unable to retrieve instance of conntrack client\n");
530 return NULL;
531 }
532
533 #ifdef FEATURE_IPACM_HAL
534 if (pClient->fd_udp < 0) {
535 IPACMERR("unable to get conntrack UDP handle due to fd_udp is invalid \n");
536 return NULL;
537 } else {
538 pClient->udp_hdl = nfct_open2(CONNTRACK,
539 (NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY), pClient->fd_udp);
540 }
541 #else
542 pClient->udp_hdl = nfct_open(CONNTRACK,
543 (NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY));
544 #endif
545 if(pClient->udp_hdl == NULL)
546 {
547 PERROR("nfct_open failed on getting udp_hdl\n");
548 return NULL;
549 }
550
551 /* Initialize Filter */
552 ret = IPA_Conntrack_UDP_Filter_Init();
553 if(-1 == ret)
554 {
555 IPACMDBG("Unable to initalize udp filters\n");
556 return NULL;
557 }
558
559 /* Attach the filter to net filter handler */
560 ret = nfct_filter_attach(nfct_fd(pClient->udp_hdl), pClient->udp_filter);
561 if(ret == -1)
562 {
563 IPACMDBG("unable to attach the filter\n");
564 return NULL;
565 }
566
567 /* Register callback with netfilter handler */
568 IPACMDBG_H("udp handle:%pK, fd:%d\n", pClient->udp_hdl, nfct_fd(pClient->udp_hdl));
569 nfct_callback_register(pClient->udp_hdl,
570 (nf_conntrack_msg_type)(NFCT_T_NEW | NFCT_T_DESTROY),
571 IPAConntrackEventCB,
572 NULL);
573
574 /* Block to catch events from net filter connection track */
575 ctcatch:
576 ret = nfct_catch(pClient->udp_hdl);
577 /* Due to conntrack dump, sequence number might mismatch for initial events. */
578 if((ret == -1) && (errno != ENOMSG) && (errno != EILSEQ))
579 {
580 IPACMDBG("(%d)(%d)(%s)\n", ret, errno, strerror(errno));
581 return NULL;
582 }
583 else
584 {
585 IPACMDBG("ctcatch ret:%d, errno:%d\n", ret, errno);
586 goto ctcatch;
587 }
588
589 IPACMDBG("Exit from udp thread with ret: %d\n", ret);
590
591 /* destroy the filter.. this will not detach the filter */
592 nfct_filter_destroy(pClient->udp_filter);
593 pClient->udp_filter = NULL;
594
595 /* de-register the callback */
596 nfct_callback_unregister(pClient->udp_hdl);
597 /* close the handle */
598 #ifdef FEATURE_IPACM_HAL
599 nfct_close2(pClient->udp_hdl, true);
600 #else
601 nfct_close(pClient->udp_hdl);
602 #endif
603 pClient->udp_hdl = NULL;
604
605 pthread_exit(NULL);
606 return NULL;
607 }
608
609 /* Thread to initialize TCP Conntrack Filters*/
UNRegisterWithConnTrack(void)610 void IPACM_ConntrackClient::UNRegisterWithConnTrack(void)
611 {
612 IPACM_ConntrackClient *pClient = NULL;
613
614 IPACMDBG("\n");
615
616 pClient = IPACM_ConntrackClient::GetInstance();
617 if(pClient == NULL)
618 {
619 IPACMERR("unable to retrieve instance of conntrack client\n");
620 return;
621 }
622
623 /* destroy the TCP filter.. this will not detach the filter */
624 if (pClient->tcp_filter) {
625 nfct_filter_destroy(pClient->tcp_filter);
626 pClient->tcp_filter = NULL;
627 }
628
629 /* de-register the callback */
630 if (pClient->tcp_hdl) {
631 nfct_callback_unregister(pClient->tcp_hdl);
632 /* close the handle */
633 nfct_close(pClient->tcp_hdl);
634 pClient->tcp_hdl = NULL;
635 }
636
637 /* destroy the filter.. this will not detach the filter */
638 if (pClient->udp_filter) {
639 nfct_filter_destroy(pClient->udp_filter);
640 pClient->udp_filter = NULL;
641 }
642
643 /* de-register the callback */
644 if (pClient->udp_hdl) {
645 nfct_callback_unregister(pClient->udp_hdl);
646 /* close the handle */
647 nfct_close(pClient->udp_hdl);
648 pClient->udp_hdl = NULL;
649 }
650
651 pClient->fd_tcp = -1;
652 pClient->fd_udp = -1;
653
654 return;
655 }
656
UpdateUDPFilters(void * param,bool isWan)657 void IPACM_ConntrackClient::UpdateUDPFilters(void *param, bool isWan)
658 {
659 static bool isIgnore = false;
660 int ret = 0;
661 IPACM_ConntrackClient *pClient = NULL;
662
663 pClient = IPACM_ConntrackClient::GetInstance();
664 if(pClient == NULL)
665 {
666 IPACMERR("unable to retrieve conntrack client instance\n");
667 return;
668 }
669
670 if(pClient->udp_filter == NULL)
671 {
672 return;
673 }
674
675 if(!isWan)
676 {
677 IPA_Conntrack_Filters_Ignore_Local_Iface(pClient->udp_filter,
678 (ipacm_event_iface_up *)param);
679
680 if(!isIgnore)
681 {
682 IPA_Conntrack_Filters_Ignore_Bridge_Addrs(pClient->udp_filter);
683 IPA_Conntrack_Filters_Ignore_Local_Addrs(pClient->udp_filter);
684 isIgnore = true;
685 }
686 }
687
688 /* Attach the filter to udp handle */
689 if(pClient->udp_hdl != NULL)
690 {
691 IPACMDBG("attaching the filter to udp handle\n");
692 ret = nfct_filter_attach(nfct_fd(pClient->udp_hdl), pClient->udp_filter);
693 if(ret == -1)
694 {
695 PERROR("unable to attach the filter to udp handle\n");
696 IPACMERR("udp handle:%pK, fd:%d Error: %d\n",pClient->udp_hdl, nfct_fd(pClient->udp_hdl), ret);
697 return;
698 }
699 }
700
701 return;
702 }
703
UpdateTCPFilters(void * param,bool isWan)704 void IPACM_ConntrackClient::UpdateTCPFilters(void *param, bool isWan)
705 {
706 static bool isIgnore = false;
707 int ret = 0;
708 IPACM_ConntrackClient *pClient = NULL;
709
710 pClient = IPACM_ConntrackClient::GetInstance();
711 if(pClient == NULL)
712 {
713 IPACMERR("unable to retrieve conntrack client instance\n");
714 return;
715 }
716
717 if(pClient->tcp_filter == NULL)
718 return;
719
720 if(!isWan)
721 {
722 IPA_Conntrack_Filters_Ignore_Local_Iface(pClient->tcp_filter,
723 (ipacm_event_iface_up *)param);
724
725 if(!isIgnore)
726 {
727 IPA_Conntrack_Filters_Ignore_Bridge_Addrs(pClient->udp_filter);
728 IPA_Conntrack_Filters_Ignore_Local_Addrs(pClient->udp_filter);
729 isIgnore = true;
730 }
731 }
732
733 /* Attach the filter to tcp handle */
734 if(pClient->tcp_hdl != NULL)
735 {
736 IPACMDBG("attaching the filter to tcp handle\n");
737 ret = nfct_filter_attach(nfct_fd(pClient->tcp_hdl), pClient->tcp_filter);
738 if(ret == -1)
739 {
740 PERROR("unable to attach the filter to tcp handle\n");
741 IPACMERR("tcp handle:%pK, fd:%d Error: %d\n",pClient->tcp_hdl, nfct_fd(pClient->tcp_hdl), ret);
742 return;
743 }
744 }
745
746 return;
747 }
748
749