Integration changes with latest NWAL
[keystone-rtos/netapi.git] / ti / runtime / netapi / applications / ipsec_offload / ipsecmgr / src / netapi_ipsecmgr.c
1 /*
2  * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
3  *
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions
7  *  are met:
8  *
9  *    Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  *    Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the
15  *    distribution.
16  *
17  *    Neither the name of Texas Instruments Incorporated nor the names of
18  *    its contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33 */
36 /* IPSec Manager Include Files */
37 #include "ipsecmgr_snoop.h"
38 #include "ipsecmgr_ipc.h"
39 #include "ipsecmgr_syslog.h"
41 /* Local include */
42 #include "netapilib_interface.h"
44 /* Standard includes */
45 #include <dlfcn.h>
46 #include <stdlib.h>
47 #include <signal.h>
48 #include <stdarg.h>
52 #include <arpa/inet.h>
53 #include <sys/socket.h>
54 #include <ifaddrs.h>
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <unistd.h>
59 #include <sys/types.h>
60 #include <netinet/in.h> 
61 #include <string.h> 
63 #if defined(DEVICE_K2H)
64 #include <ti/runtime/hplib/device/k2h/src/hplib_device.c>
65 #include <ti/runtime/netapi/device/k2h/src/netapi_device.c>
66 #include <ti/drv/qmss/device/k2h/src/qmss_device.c>
67 #include <ti/drv/cppi/device/k2h/src/cppi_device.c>
68 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
69  "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
70 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
71 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
72 #elif defined (DEVICE_K2K)
73 #include <ti/runtime/hplib/device/k2k/src/hplib_device.c>
74 #include <ti/runtime/netapi/device/k2k/src/netapi_device.c>
75 #include <ti/drv/qmss/device/k2k/src/qmss_device.c>
76 #include <ti/drv/cppi/device/k2k/src/cppi_device.c>
77 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
78  "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
79 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
80 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
81 #elif defined (DEVICE_K2L)
82 #include <ti/runtime/hplib/device/k2l/src/hplib_device.c>
83 #include <ti/runtime/netapi/device/k2l/src/netapi_device.c>
84 #include <ti/drv/qmss/device/k2l/src/qmss_device.c>
85 #include <ti/drv/cppi/device/k2l/src/cppi_device.c>
86 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
87  "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/complete-queue"};
88 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
89 "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/flow"};
90 #elif defined (DEVICE_K2E)
91 #include <ti/runtime/hplib/device/k2e/src/hplib_device.c>
92 #include <ti/runtime/netapi/device/k2e/src/netapi_device.c>
93 #include <ti/drv/qmss/device/k2e/src/qmss_device.c>
94 #include <ti/drv/cppi/device/k2e/src/cppi_device.c>
95 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
96  "/proc/device-tree/soc/pktdma@24186000/channels/netrx0/complete-queue"};
97 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
98 "/proc/device-tree/soc/pktdma@24186000/channels/netrx0/flow"};
100 #else /*Default */
101 #include <ti/runtime/hplib/device/k2h/src/hplib_device.c>
102 #include <ti/runtime/netapi/device/k2h/src/netapi_device.c>
103 #include <ti/drv/qmss/device/k2h/src/qmss_device.c>
104 #include <ti/drv/cppi/device/k2h/src/cppi_device.c>
105 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
106  "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
107 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
108 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
110 #endif
112 /**********************************************************************
113  ************************** Local Definitions *************************
114  **********************************************************************/
115 #if 0
117 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
118  "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
119 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
120 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
122 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
123  "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/complete-queue"};
124 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
125 "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/flow"};
126 #endif
129 /**********************************************************************
130  ************************** Global Variables **************************
131  **********************************************************************/
133 static ipsecmgr_ipc_daemon_send_if_t *send_iface;
134 NETAPI_T netapi_handle;
136 ipsecMgrMcb_t globalDB;
138 /* Lock file for the daemon */
139 #define LOCK_FILE   "/var/lock/ipsecmgr_daemon"
141 /* snoop task */
142 static pthread_t    snoop_run_th;
144 static NETAPI_CFG_T our_netapi_default_cfg=
146     TUNE_NETAPI_PERM_MEM_SZ,
147     128,  //start of packet offset for hw to place data on rx for default flow
148     TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
149     TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
150     TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
151     64, //#descriptors w/o buffers in default heap
152     TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
153     128,    //tail room
154     256,    //extra room
155     0
156 };
160 static int QUIT = 0;
162 /* stub functions */
163 static void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
164                          PKTIO_METADATA_T meta[], int n_pkts,
165                          uint64_t ts )
167     return;
170 /* byte swap routine */
171 static unsigned int swap32 (unsigned int x)
173     unsigned int y;
175     y = (((x >> 24) & 0xff) <<  0) |
176         (((x >> 16) & 0xff) <<  8) |
177         (((x >>  8) & 0xff) << 16) |
178         (((x >>  0) & 0xff) << 24) ;
180     return (y);
184 void cleanup_sa_sp()
186     int slot, error=0;;
187     /* delete any offloaded rx SA's and policies */
188     /* and delete any offloaded tx SA's */
189     for (slot = 0;slot < 64;slot++)
190     {
191         if(globalDB.rx_sa[slot].in_use)
192         {
193             globalDB.rx_sa[slot].in_use = 0;
194             if(globalDB.rx_sa[slot].spAppId)
195             {
196                 netapi_secDelRxPolicy(netapi_handle,
197                               (NETCP_CFG_IPSEC_POLICY_T) globalDB.rx_sa[slot].spAppId,
198                               &error);
199                 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
200                 "cleanup_sa_sp: SP deleted: sp_app_id: 0x%x, slot: %d, error: %d\n", 
201                 globalDB.rx_sa[slot].spAppId, slot, error);
202             }
203             netapi_secDelSA(netapi_handle,
204                         NETCP_CFG_NO_INTERFACE,
205                         (NETCP_CFG_SA_T) globalDB.rx_sa[slot].saAppId,
206                         &error);
207             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
208                 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
209                 globalDB.rx_sa[slot].saAppId, slot, error);
210             
211         }
212         if(globalDB.tx_sa[slot].in_use)
213         {
214             globalDB.tx_sa[slot].in_use = 0;
215             netapi_secDelSA(netapi_handle,
216                             NETCP_CFG_NO_INTERFACE,
217                            (NETCP_CFG_SA_T) globalDB.tx_sa[slot].saAppId,
218                             &error);
219             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
220                 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
221                 globalDB.tx_sa[slot].saAppId, slot, error);
222         }
223     }
227 static void* snoop_run_thread (void* arg)
229     cpu_set_t cpu_set;
230     CPU_ZERO( &cpu_set);
231     CPU_SET( 0, &cpu_set);
233     hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
234     ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
235         "snoop_run_thread: daemon entering forever event loop\n");
237     while (1)
238     {
239         /* Poll for message from user application */
240         ipsecmgr_ipc_poll();
242         /* Poll for message from Kernel */
243         ipsecmgr_snoop_run();
244         if (QUIT == 1)
245             break;
246     }
247     ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
248         "snoop_run_thread: calling shutdown\n");
249     ipsecmgr_snoop_shutdown ();
250     cleanup_sa_sp();
251     netapi_shutdown(netapi_handle);
253     return;
256 /**
257  *  @b Description
258  *  @n  
259  *      SIGTERM handler.
260  *
261  *  @param[in]  signum
262  *      signal number to terminate deamon.
263  */
264 static void sig_term_handler(int signum)
266     QUIT = 1;
269 /**
270  *  @b Description
271  *  @n  
272  *      Function to implement task sleep functionality 
273  *      for IPSecMgr
274  *
275  *  @param[in]  time_in_msec
276  *      Time in milliseconds to sleep
277  *
278  *  @retval
279  *      Not Applicable.
280  */
281 static void task_sleep(uint32_t time_in_msec)
283     pthread_mutex_t fake_mutex = PTHREAD_MUTEX_INITIALIZER;
284     pthread_cond_t fake_cond = PTHREAD_COND_INITIALIZER;
285     struct timespec ts;
286     int rt;
287     unsigned int sec, nsec;
289     sec = time_in_msec/1000;
290     nsec = (time_in_msec - (sec*1000)) * 1000000;
292     /* Use the wall-clock time */
293     clock_gettime(CLOCK_REALTIME, &ts);
295     ts.tv_sec += sec;
296     ts.tv_nsec += nsec;
298     pthread_mutex_lock(&fake_mutex);
299     rt = pthread_cond_timedwait(&fake_cond, &fake_mutex, &ts);
300     pthread_mutex_unlock(&fake_mutex);
304 /**
305  *  @b Description
306  *  @n  
307  *      NETAPI Proxy's IPSecMgr Start Offload Response 
308  *      message handler.
309  *
310  *      This function is called by the IPSecMgr library
311  *      when it has a response ready corresponding to an
312  *      Start Offload SP request issued by the user application.
313  *
314  *  @param[in]  rsp
315  *      IPSecMgr's Start Offload SP response
316  *  @param[in]  addr
317  *      Destination address (user application) to send 
318  *      the response to
319  *  @param[in]  addr_size
320  *      Size of destination address passed
321  *
322  *  @retval
323  *      Success -   0
324  *  @retval
325  *      ERROR   -   <0
326  */
327 static int offload_sp_rsp_send
329     ipsecmgr_snoop_offload_sp_rsp_param_t *rsp,
330     void                                  *addr,
331     uint32_t                              addr_size
334     ipsecmgr_ipc_offload_sp_rsp_param_t offload_sp_rsp;
336     offload_sp_rsp.type = rsp->type;
337     offload_sp_rsp.result = rsp->result;
338     offload_sp_rsp.trans_id = rsp->trans_id;
339     offload_sp_rsp.err_code = rsp->err_code;
340     offload_sp_rsp.sp_handle = rsp->sp_handle;
341     offload_sp_rsp.sa_handle = rsp->sa_handle;
343     if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
344         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
345             "offload_sp_rsp_send: addr size not correct\n");
346         return -1;
347     }
349     return send_iface->offload_sp_rsp(&offload_sp_rsp,
350                                       (ipsecmgr_ipc_addr_t *)addr);
352 static void offload_sp_req_recv
354     ipsecmgr_ipc_offload_sp_req_param_t *req,
355     ipsecmgr_ipc_addr_t                 *src_addr
358     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"offload_sp_req_recv called for policy id\n",
359     req->policy_id);
360     ipsecmgr_snoop_offload_sp_rsp_param_t rsp;
361     uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
362     ipsecmgr_snoop_offload_sp_req_param_t offload_sp_req;
364     offload_sp_req.trans_id = req->trans_id;
365     offload_sp_req.policy_id = req->policy_id;
366     offload_sp_req.sa_flags = req->sa_flags;
367     offload_sp_req.if_name = req->if_name;
368     offload_sp_req.dscp_cfg = req->dscp_cfg;
369     offload_sp_req.l5_selector = req->l5_selector;
371     memset(&rsp, 0, sizeof(rsp));
372     rsp.trans_id = req->trans_id;
374     if (ipsecmgr_snoop_offload_sp_req(&offload_sp_req, (void*)src_addr,
375                                       addr_size)) {
376         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
377             "offload_sp_req_recv: snoop_offload_sp_req failed\n");
378         rsp.result = RESULT_FAILURE;
379         rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
380     }
381     else
382     {
383         rsp.result = RESULT_SUCCESS;
384         rsp.type = RSP_TYPE_ACK;
385     }
386     
387     if (offload_sp_rsp_send(&rsp, (void *)src_addr, addr_size))
388     {
389         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
390             "offload_sp_req_recv: failed to send ACK for offload_sp\n");
391     }
392     return;
396 /**
397  *  @b Description
398  *  @n  
399  *      NETAPI Proxy's IPSecMgr Stop Offload response message 
400  *      handler.
401  *
402  *      This function is called by the IPSecMgr library
403  *      when it has a response ready corresponding to an
404  *      Stop Offload SP request issued by the user application.
405  *
406  *  @param[in]  rsp
407  *      IPSecMgr's Stop Offload SP response
408  *  @param[in]  addr
409  *      Destination address (user application) to send 
410  *      the response to
411  *  @param[in]  addr_size
412  *      Size of destination address passed
413  *
414  *  @retval
415  *      Success -   0
416  *  @retval
417  *      ERROR   -   <0
418  */
419 static int stop_offload_rsp_send
421     ipsecmgr_snoop_stop_offload_rsp_param_t *rsp,
422     void                                    *addr,
423     uint32_t                                addr_size
426     ipsecmgr_ipc_stop_offload_rsp_param_t stop_offload_rsp;
428     stop_offload_rsp.type = rsp->type;
429     stop_offload_rsp.result = rsp->result;
430     stop_offload_rsp.trans_id = rsp->trans_id;
432     if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
433         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
434             "stop_offload_rsp_send: addr size not correct\n");
435         return -1;
436     }
438     return send_iface->stop_offload_rsp(&stop_offload_rsp,
439                                       (ipsecmgr_ipc_addr_t *)addr);
442 static void stop_offload_req_recv
444     ipsecmgr_ipc_stop_offload_req_param_t   *req,
445     ipsecmgr_ipc_addr_t                     *src_addr
448     ipsecmgr_snoop_stop_offload_req_param_t stop_offload_req;
449     uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
450     ipsecmgr_snoop_stop_offload_rsp_param_t rsp;
452     stop_offload_req.trans_id = req->trans_id;
453     stop_offload_req.policy_id = req->policy_id;
455     memset(&rsp, 0, sizeof(rsp));
456     rsp.trans_id = req->trans_id;
458     if (ipsecmgr_snoop_stop_offload(&stop_offload_req, (void*)src_addr,
459                                       addr_size)) {
460         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
461             "stop_offload_req_recv: snoop_stop_offload failed\n");
462         rsp.result = RESULT_FAILURE;
463         rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
464     }
465     else
466     {
467         rsp.result = RESULT_SUCCESS;
468         rsp.type = RSP_TYPE_ACK;
469     }
471     if (stop_offload_rsp_send(&rsp, (void *)src_addr, addr_size))
472     {
473         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
474             "stop_offload_req_recv: failed to send ACK for stop_offload\n");
475     }
476     return;
479 /**
480  *  @b Description
481  *  @n  
482  *      Function to initialize IPSec Manager library.
483  *
484  *  @retval
485  *      Success -   0
486  *  @retval
487  *      ERROR   -   >0
488  */
489 static int32_t init_ipsecmgr (void)
491     struct ipsecmgr_snoop_fp_cfg_cb     fp_cfg_cb;
492     struct ipsecmgr_snoop_mgnt_cb       mgnt_cb;
493     struct ipsecmgr_snoop_platform_cb   plat_cb;
494     ipsecmgr_ipc_daemon_recv_if_t       recv_if;
495     ipsecmgr_ipc_cfg_t                  ipc_cfg;
496     int32_t                             status;
497     pthread_attr_t threadAttr;
499     /* Initializations */
500     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO, 
501                         "DEBUG: init_ipsecmgr() starting initialization\n");
502     memset(&fp_cfg_cb, 0, sizeof(fp_cfg_cb));
503     memset(&mgnt_cb, 0, sizeof(mgnt_cb));
504     memset(&plat_cb, 0, sizeof(plat_cb));
505     memset(&recv_if, 0, sizeof(recv_if));
506     memset(&ipc_cfg, 0, sizeof(ipc_cfg));
508     /* Initialize IPC library */
509     ipc_cfg.mode = IPC_MODE_SNOOP_DAEMON;
510     if (ipsecmgr_ipc_init(&ipc_cfg)) {
511         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
512             "init_ipsecmgr: ipc_init failed\n");
513         return -1;
514     }
515     else
516         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
517             "init_ipsecmgr: ipc_init sucess\n");
519     if (ipsecmgr_ipc_get_daemon_send_iface(&send_iface)) {
520         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
521             "init_ipsecmgr: ipc_get_daemon_send_iface failed\n");
522         return -1;
523     }
524     recv_if.offload_sp_req = offload_sp_req_recv;
525     recv_if.stop_offload_req = stop_offload_req_recv;
526     /* Register ipsecmgr daemon recieve i/f */
527     if (ipsecmgr_ipc_register_daemon_recv_iface(&recv_if)) {
528         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
529             "snoop_run: ipc_register_daemon_recv_iface failed\n");
530         return -1;
531     }
533     /* Initialize the IPSec Manager Snoop library */
534     fp_cfg_cb.add_sa        =   netapilib_ifAddSA;
535     fp_cfg_cb.add_sp        =   netapilib_ifAddSP;
536     fp_cfg_cb.del_sa        =   netapilib_ifDeleteSA;
537     fp_cfg_cb.del_sp        =   netapilib_ifDeleteSP;
538     fp_cfg_cb.get_sa_ctx    =   netapilib_ifGetSACtx;
540     plat_cb.log_msg  = (ipsecmgr_snoop_log_msg_t)ipsecmgr_syslog_msg;
541     plat_cb.sleep           =   task_sleep;
543     mgnt_cb.offload_sp_rsp  =   offload_sp_rsp_send;
544     mgnt_cb.stop_offload_rsp=   stop_offload_rsp_send;
545     mgnt_cb.rekey_event     =   NULL; // No explicit notifications needed on Rekey completion
547     if ((status = ipsecmgr_snoop_init (&fp_cfg_cb, &mgnt_cb, &plat_cb))) 
548     {
549         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
550                             "DEBUG: init_ipsecmgr() ipsecmgr_snoop_init failed (%d)\n", status);
551         return -1;
552     }
556 #ifdef GDB_DEBUG
557     snoop_run_thread(NULL);
558 #else
559     /* Create the task context for snoop library */
560     pthread_attr_init(&threadAttr);
561     pthread_attr_setstacksize(&threadAttr, 0x10000);
562     if (pthread_create(&snoop_run_th, (void*) NULL, snoop_run_thread, NULL))
563     {
564         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
565             "ERROR: snoop run thread failed to start, error code\n"); 
566         return -1;
567     }
569     /* Setup signal handler for SIGTERM */
570     if (signal(SIGTERM, sig_term_handler) == SIG_ERR) {
571         ipsecmgr_syslog_msg(SYSLOG_LEVEL_WARN,
572             "init_ipsecmgr: cannot handle SIGTERM\n");
573     }
574     /* Wait for the NETAPI Proxy task to finish its processing and exit. */
575     pthread_join (snoop_run_th, NULL);
576 #endif
577     return 0;
580 /**
581  *  @b Description
582  *  @n  
583  *      Utility function to daemonize the current
584  *      application.
585  *
586  *  @param[in]  lock_file
587  *      Lock file to be used by the daemon
588  */
589 static void daemonize (const char *lock_file)
591     pid_t       pid, sid;
592     int32_t     lock_fp = -1;
593     char        str[10];
595     /* already a daemon */
596     if (getppid () == 1)
597         return;
599     /* Fork off the parent process */
600     if ((pid = fork ()) < 0) 
601     {
602         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
603                             "ERROR: daemonize() unable to fork daemon, code=%d (%s)",
604                             errno, 
605                             strerror(errno));
606         exit (-1);
607     }
609     /* If we got a PID, then exit the parent process. */
610     if (pid > 0)
611         exit (0);
613     /* At this point we are executing as the child process */
615     /* Create a new SID for the child process */
616     if ((sid = setsid ()) < 0) 
617     {
618         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
619                             "ERROR: daemonize() unable to create a new session, code %d (%s)",
620                             errno, 
621                             strerror(errno));
622         exit (-1);
623     }
625     /* Change the file mode mask */
626     umask (027);
628     /* Change the current working directory.  This prevents the current
629      * directory from being locked; hence not being able to remove it. */
630     if ((chdir("/")) < 0) 
631     {
632         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
633                             "ERROR: daemonize() unable to change directory to %s, code %d (%s)",
634                             "/", 
635                             errno, 
636                             strerror(errno));
637         exit (-1);
638     }
640     /* Create the lock file */
641     if (lock_file) 
642     {
643         if ((lock_fp = open(lock_file, O_RDWR|O_CREAT, 0640)) < 0 ) 
644         {
645             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR, 
646                                 "ERROR: daemonize() unable to create lock file %s, code=%d (%s)",
647                                 lock_file, 
648                                 errno, 
649                                 strerror(errno));
650             exit (-1);
651         }
652     }
654     if (lockf (lock_fp, F_TLOCK, 0) < 0) 
655         exit(-1); /* can not lock */
657     /* Record pid to lockfile */
658     sprintf (str, "%d\n", getpid());
659     write (lock_fp, str, strlen(str)); 
661     /* Cancel certain signals */
662     signal (SIGCHLD, SIG_DFL); /* A child process dies */
663     signal (SIGTSTP, SIG_IGN); /* Various TTY signals */
664     signal (SIGTTOU, SIG_IGN);
665     signal (SIGTTIN, SIG_IGN);
666     signal (SIGHUP, SIG_IGN); /* Ignore hangup signal */
667     signal (SIGTERM, sig_term_handler); /* catch SIGTERM */
669     /* Redirect standard files to /dev/null */
670     freopen( "/dev/null", "r", stdin);
671     freopen( "/dev/null", "w", stdout);
672     freopen( "/dev/null", "w", stderr);
674     /* Done setting up the daemon */
675     return;
678 int get_kernel_config()
680     uint32_t temp=0;
681     FILE *pDts = NULL;
683     pDts = fopen(DTS_LOG_FILE_QUEUE_ETHx[0], "rb");
685     if(pDts)
686     {
687         fread((void*)&temp, sizeof(uint32_t), 1, pDts);
688         globalDB.qNum = (int)swap32(temp);
689         fclose(pDts);
690     }
691     else
692     {
693         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
694             "main: error opening device tree file: %s\n",DTS_LOG_FILE_QUEUE_ETHx[0]);
695         return -1;
696     }
698     pDts = NULL;
699     pDts = fopen(DTS_LOG_FILE_FLOW_ETHx[0], "rb");
701     if(pDts)
702     {
703         fread((void*)&temp, sizeof(uint32_t), 1, pDts);
704         globalDB.flowId = (int)swap32(temp);
705         fclose(pDts);
706     }
707     else
708     {
709         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
710             "main: error opening device tree file: %s\n",DTS_LOG_FILE_FLOW_ETHx[0]);
711         return -1;
712     }
713     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
714             "get_kernel_config: flow: 0x%x, qNum: 0x%x\n", 
715              globalDB.flowId, globalDB.qNum);
716     return 0;
719 int create_pktio_channel()
721     static int count = 0;
722     int error = 0;
723     char name[19];
724     PKTIO_HANDLE_T *pktio_channel;
725     PKTIO_CFG_T pktio_cfg;
726     NETCP_CFG_ROUTE_T route;
727     NETCP_CFG_FLOW_T flow;
728     NETCP_CFG_EXCEPTION_PKT_T expPkt_appid = 0;
730     memset(&pktio_cfg,0,sizeof(PKTIO_CFG_T));
731     memset((void *)&route, 0, sizeof (NETCP_CFG_ROUTE_T));
732     memset((void *)&flow, 0, sizeof (NETCP_CFG_FLOW_T));
734     sprintf(&name[0],"%s","offload_0");
735     pktio_cfg.qnum = globalDB.qNum;
736     pktio_cfg.flags1 = PKTIO_RX;
737     pktio_cfg.flags2 = PKTIO_GLOBAL | PKTIO_PKT;
738     pktio_cfg.max_n = 8;
740     globalDB.pktio_channel = netapi_pktioCreate(netapi_handle,
741                                                &name[0],
742                                                (PKTIO_CB)recv_cb,
743                                                &pktio_cfg,
744                                                &error);
745     if (!globalDB.pktio_channel)
746     {
747         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
748             "create_pktio_channel: failed\n");
749         return -1;
750     }
753     flow.dma_engine= 1;
754     flow.flowid = globalDB.flowId;
755     route.p_dest_q = globalDB.pktio_channel;
756     route.p_flow = &flow;
757     route.valid_params |= NETCP_CFG_VALID_PARAM_ROUTE_TYPE;
758     route.routeType = NWAL_ROUTE_RX_INTF_W_FLOW;
759     /* enable exception packet handling for fragmented packets */
760     expPkt_appid = netapi_netcpCfgExceptions(netapi_handle,
761                                              7,
762                                              NETCP_CFG_ACTION_TO_SW,
763                                              (NETCP_CFG_ROUTE_HANDLE_T) &route);
765     return 0;
767 /**
768  *  @b Description
769  *  @n  
770  *      Entry point for the NETAPI Proxy application.
771  *
772  *  @param[in]  argc
773  *      Number of arguments passed to the application
774  *  @param[in]  argv
775  *      Arguments passed to the application.
776  *
777  *  @retval
778  *      Success -   0
779  *  @retval
780  *      ERROR   -   >0
781  */
782 int32_t main (int argc, char* argv[])
784     int32_t             retVal;
785     int i, iface;
786     char* pTok = NULL;
787     int ip_entry_count = 0;
788     struct ifaddrs *ifaddr, *ifa;
789     int family, s;
790     char host[NI_MAXHOST];
791     struct sockaddr_in6 ipv6_addr;
792     cpu_set_t cpu_set;
793     ipsecmgr_syslog_init();
795     memset(&globalDB, 0, sizeof(globalDB));
797     /* assign main net_test thread to run on core 0 */
798     CPU_ZERO( &cpu_set);
799     CPU_SET( 0, &cpu_set);
800     hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
801     /* create netapi */
802     netapi_handle = netapi_init(NETAPI_SYS_MASTER,
803                                 &our_netapi_default_cfg,
804                                 &hplibDeviceGblCfgParam,
805                                 &netapiDeviceGblCfgParam);
806     if(netapi_handle == NULL)
807     {
808         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
809                              "ERROR: netapi_init failed\n");
810         return -1;
811     }
812     else
813         netapi_netcpCfgExceptions(netapi_handle,
814                                   NETCP_CFG_ALL_EXCEPTIONS,
815                                   NETCP_CFG_ACTION_DISCARD,
816                                   (NETCP_CFG_ROUTE_HANDLE_T) NULL);
818     if (get_kernel_config())
819     {
820         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
821                             "ERROR: main: get_kernel_config() failed\n");
822         return -1;
823     }
824     else
825     {
826         /* create pktio channel */
827         if(create_pktio_channel())
828         {
829             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
830                             "ERROR: main: pktio channel creation failed\n");
831             return -1;
832         }
833     }
834      /*Create the proxy daemon. */
835     printf("main: calling daemonize\n");
836     daemonize (LOCK_FILE); 
838     /* Initialize and start the IPSec Mgr Snoop functionality */
839     if ((retVal = init_ipsecmgr ()) < 0)
840     {
841         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
842                             "ERROR: IPSec Mgr init failed, error code %d \n",
843                             retVal);
844         return -1;
845     }
846     else
847         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
848                              "main: ipsecmgr daemon shutdonw complete\n");