NETAPI updates to support enhanced route types.
[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 /**********************************************************************
64  ************************** Local Definitions *************************
65  **********************************************************************/
66 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
67  "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
69 #if 0
70  "/proc/device-tree/soc/pktdma@2004000/channels/netrx1/complete-queue",
71  "/proc/device-tree/soc/pktdma@2004000/channels/netrx2/complete-queue",
72  "/proc/device-tree/soc/pktdma@2004000/channels/netrx3/complete-queue",
73  "/proc/device-tree/soc/pktdma@2004000/channels/netrx4/complete-queue",
74  "/proc/device-tree/soc/pktdma@2004000/channels/netrx5/complete-queue",
75  "/proc/device-tree/soc/pktdma@2004000/channels/netrx6/complete-queue",
76  "/proc/device-tree/soc/pktdma@2004000/channels/netrx7/complete-queue",
77  "/proc/device-tree/soc/pktdma@2004000/channels/netrx8/complete-queue",
78  "/proc/device-tree/soc/pktdma@2004000/channels/netrx9/complete-queue",
79  "/proc/device-tree/soc/pktdma@2004000/channels/netrx10/complete-queue",
80  "/proc/device-tree/soc/pktdma@2004000/channels/netrx11/complete-queue",
81  "/proc/device-tree/soc/pktdma@2004000/channels/netrx12/complete-queue",
82  "/proc/device-tree/soc/pktdma@2004000/channels/netrx13/complete-queue",
83  "/proc/device-tree/soc/pktdma@2004000/channels/netrx14/complete-queue",
84  "/proc/device-tree/soc/pktdma@2004000/channels/netrx15/complete-queue"
85 };
86 #endif
87 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
88 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
89 #if 0
90 "/proc/device-tree/soc/pktdma@2004000/channels/netrx1/flow",
91 "/proc/device-tree/soc/pktdma@2004000/channels/netrx2/flow",
92 "/proc/device-tree/soc/pktdma@2004000/channels/netrx3/flow",
93 "/proc/device-tree/soc/pktdma@2004000/channels/netrx4/flow",
94 "/proc/device-tree/soc/pktdma@2004000/channels/netrx5/flow",
95 "/proc/device-tree/soc/pktdma@2004000/channels/netrx6/flow",
96 "/proc/device-tree/soc/pktdma@2004000/channels/netrx7/flow",
97 "/proc/device-tree/soc/pktdma@2004000/channels/netrx8/flow",
98 "/proc/device-tree/soc/pktdma@2004000/channels/netrx9/flow",
99 "/proc/device-tree/soc/pktdma@2004000/channels/netrx10/flow",
100 "/proc/device-tree/soc/pktdma@2004000/channels/netrx11/flow",
101 "/proc/device-tree/soc/pktdma@2004000/channels/netrx12/flow",
102 "/proc/device-tree/soc/pktdma@2004000/channels/netrx13/flow",
103 "/proc/device-tree/soc/pktdma@2004000/channels/netrx14/flow",
104 "/proc/device-tree/soc/pktdma@2004000/channels/netrx15/flow",
105 };
106 #endif
107 /**********************************************************************
108  ************************** Global Variables **************************
109  **********************************************************************/
111 static ipsecmgr_ipc_daemon_send_if_t *send_iface;
112 NETAPI_T netapi_handle;
114 //paSysStats_t netcp_stats;
115 ipsecMgrMcb_t globalDB;
116 ipsecMgrIfConfigEntry_T ipConfigList[16];
118 /* Lock file for the daemon */
119 #define LOCK_FILE   "/var/lock/ipsecmgr_daemon"
121 /* snoop task */
122 static pthread_t    snoop_run_th;
124 static NETAPI_CFG_T our_netapi_default_cfg=
126     TUNE_NETAPI_PERM_MEM_SZ,
127     128,  //start of packet offset for hw to place data on rx for default flow
128     TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
129     TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
130     TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
131     64, //#descriptors w/o buffers in default heap
132     TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
133     128,    //tail room
134     256,    //extra room,
135     0
136 };
140 static int QUIT = 0;
142 /* stub functions */
143 static void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
144                          PKTIO_METADATA_T meta[], int n_pkts,
145                          uint64_t ts )
147     return;
150 /* byte swap routine */
151 static unsigned int swap32 (unsigned int x)
153     unsigned int y;
155     y = (((x >> 24) & 0xff) <<  0) |
156         (((x >> 16) & 0xff) <<  8) |
157         (((x >>  8) & 0xff) << 16) |
158         (((x >>  0) & 0xff) << 24) ;
160     return (y);
164 void cleanup_sa_sp()
166     int slot, error=0;;
167     /* delete any offloaded rx SA's and policies */
168     /* and delete any offloaded tx SA's */
169     for (slot = 0;slot < 64;slot++)
170     {
171         if(globalDB.rx_sa[slot].in_use)
172         {
173             globalDB.rx_sa[slot].in_use = 0;
174             if(globalDB.rx_sa[slot].spAppId)
175             {
176                 netapi_secDelRxPolicy(netapi_handle,
177                               (NETCP_CFG_IPSEC_POLICY_T) globalDB.rx_sa[slot].spAppId,
178                               &error);
179                 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
180                 "cleanup_sa_sp: SP deleted: sp_app_id: 0x%x, slot: %d, error: %d\n", 
181                 globalDB.rx_sa[slot].spAppId, slot, error);
182             }
183             netapi_secDelSA(netapi_handle,
184                         NETCP_CFG_NO_INTERFACE,
185                         (NETCP_CFG_SA_T) globalDB.rx_sa[slot].saAppId,
186                         &error);
187             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
188                 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
189                 globalDB.rx_sa[slot].saAppId, slot, error);
190             
191         }
192         if(globalDB.tx_sa[slot].in_use)
193         {
194             globalDB.tx_sa[slot].in_use = 0;
195             netapi_secDelSA(netapi_handle,
196                             NETCP_CFG_NO_INTERFACE,
197                            (NETCP_CFG_SA_T) globalDB.tx_sa[slot].saAppId,
198                             &error);
199             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
200                 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
201                 globalDB.tx_sa[slot].saAppId, slot, error);
202         }
203     }
206 //void netTest_utilsStatsCb(NETAPI_T h, paSysStats_t* pPaStats)
207 NETAPI_SA_STATS_T netapi_sa_statsrx;
208 NETAPI_SA_STATS_T netapi_sa_statstx;
211 void printIPSecStats(Sa_IpsecStats_t* p_saIpsecStats,
212                      nwal_saAALG auth,
213                      nwal_saEALG cipher,
214                      uint32_t    saAppId)
217     printf("\n appId: 0x%x: Autentication mode: %d, Encryption Mode: %d\n",
218                 saAppId,
219                 auth,
220                 cipher);
221                 
222     printf("IPSec replayOld:0x%x,replayDup:0x%x,authFail:0x%x \n",
223                    p_saIpsecStats->replayOld,p_saIpsecStats->replayDup,p_saIpsecStats->authFail);
224     printf("IPSec txESN:0x%x,rxESN:0x%x,pktEncHi:0x%x,pktEncLo:0x%x,pktDecHi:0x%x,pktDecLo:0x%x \n",
225                    p_saIpsecStats->txESN,p_saIpsecStats->rxESN,p_saIpsecStats->pktEncHi,
226                    p_saIpsecStats->pktEncLo,p_saIpsecStats->pktDecHi,p_saIpsecStats->pktDecLo);
233 void utilsStatsCb(NETAPI_T h)
235     uint32_t numFreeDataPackets;
236     uint32_t            numZeroBufferPackets;
237     uint32_t            numPacketsinGarbage;
238     Pktlib_HeapStats    pktLibHeapStats;
239     int i,j;
244         if(globalDB.rx_sa[0].saAppId)
245         {
246             /* Statistics for RX Tunnel */
247             memset(&netapi_sa_statsrx, 0, sizeof(netapi_sa_statsrx));
248             netapi_getSaStats(netapi_handle,
249                               globalDB.rx_sa[0].saAppId,
250                               &netapi_sa_statsrx);
251             if (netapi_sa_statsrx.validParams & NETAPI_IPSEC_STAT_VALID)
252             {
253                 printIPSecStats(&netapi_sa_statsrx.saIpsecStats,
254                                  NWAL_SA_AALG_HMAC_SHA1,
255                                  NWAL_SA_EALG_AES_CBC,
256                                  globalDB.rx_sa[0].saAppId);
257             }
258         }
259 #if 1
260         if (globalDB.tx_sa[0].saAppId)
261         {
262             memset(&netapi_sa_statstx, 0, sizeof(netapi_sa_statstx));
263             netapi_getSaStats(netapi_handle,
264                               globalDB.tx_sa[0].saAppId,
265                               &netapi_sa_statstx);
266             if (netapi_sa_statstx.validParams & NETAPI_IPSEC_STAT_VALID)
267             {
268                  printIPSecStats(&netapi_sa_statstx.saIpsecStats,
269                                    NWAL_SA_AALG_HMAC_SHA1,
270                                    NWAL_SA_EALG_AES_CBC,
271                                    globalDB.tx_sa[0].saAppId);
272             }
273         }
274 #endif
276 static void* snoop_run_thread (void* arg)
278     printf(        "snoop_run_thread: daemon entering forever event loop\n");
279     int count=0;
280     int sat=500000;
281     while (1)
282     {
283         /* Poll for message from user application */
284         ipsecmgr_ipc_poll();
286         /* Poll for message from Kernel */
287         ipsecmgr_snoop_run();
288 #if 1
289         if((count % 50000) == 0)
290             utilsStatsCb(netapi_handle);
291         
292 #endif
293         count++;
294         if (QUIT == 1)
295             break;
296     }
297     ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
298         "snoop_run_thread: calling shutdown\n");
299     utilsStatsCb(netapi_handle);
300     ipsecmgr_snoop_shutdown ();
301     cleanup_sa_sp();
302     netapi_shutdown(netapi_handle);
304     return;
307 /**
308  *  @b Description
309  *  @n  
310  *      SIGTERM handler.
311  *
312  *  @param[in]  signum
313  *      signal number to terminate deamon.
314  */
315 static void sig_term_handler(int signum)
317     QUIT = 1;
320 /**
321  *  @b Description
322  *  @n  
323  *      Function to implement task sleep functionality 
324  *      for IPSecMgr
325  *
326  *  @param[in]  time_in_msec
327  *      Time in milliseconds to sleep
328  *
329  *  @retval
330  *      Not Applicable.
331  */
332 static void task_sleep(uint32_t time_in_msec)
334     pthread_mutex_t fake_mutex = PTHREAD_MUTEX_INITIALIZER;
335     pthread_cond_t fake_cond = PTHREAD_COND_INITIALIZER;
336     struct timespec ts;
337     int rt;
338     unsigned int sec, nsec;
340     sec = time_in_msec/1000;
341     nsec = (time_in_msec - (sec*1000)) * 1000000;
343     /* Use the wall-clock time */
344     clock_gettime(CLOCK_REALTIME, &ts);
346     ts.tv_sec += sec;
347     ts.tv_nsec += nsec;
349     pthread_mutex_lock(&fake_mutex);
350     rt = pthread_cond_timedwait(&fake_cond, &fake_mutex, &ts);
351     pthread_mutex_unlock(&fake_mutex);
355 /**
356  *  @b Description
357  *  @n  
358  *      NETAPI Proxy's IPSecMgr Start Offload Response 
359  *      message handler.
360  *
361  *      This function is called by the IPSecMgr library
362  *      when it has a response ready corresponding to an
363  *      Start Offload SP request issued by the user application.
364  *
365  *  @param[in]  rsp
366  *      IPSecMgr's Start Offload SP response
367  *  @param[in]  addr
368  *      Destination address (user application) to send 
369  *      the response to
370  *  @param[in]  addr_size
371  *      Size of destination address passed
372  *
373  *  @retval
374  *      Success -   0
375  *  @retval
376  *      ERROR   -   <0
377  */
378 static int offload_sp_rsp_send
380     ipsecmgr_snoop_offload_sp_rsp_param_t *rsp,
381     void                                  *addr,
382     uint32_t                              addr_size
385     ipsecmgr_ipc_offload_sp_rsp_param_t offload_sp_rsp;
387     offload_sp_rsp.type = rsp->type;
388     offload_sp_rsp.result = rsp->result;
389     offload_sp_rsp.trans_id = rsp->trans_id;
390     offload_sp_rsp.err_code = rsp->err_code;
391     offload_sp_rsp.sp_handle = rsp->sp_handle;
392     offload_sp_rsp.sa_handle = rsp->sa_handle;
394     if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
395         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
396             "offload_sp_rsp_send: addr size not correct\n");
397         return -1;
398     }
400     return send_iface->offload_sp_rsp(&offload_sp_rsp,
401                                       (ipsecmgr_ipc_addr_t *)addr);
403 static void offload_sp_req_recv
405     ipsecmgr_ipc_offload_sp_req_param_t *req,
406     ipsecmgr_ipc_addr_t                 *src_addr
409     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"offload_sp_req_recv called for policy id\n",
410     req->policy_id);
411     ipsecmgr_snoop_offload_sp_rsp_param_t rsp;
412     uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
413     ipsecmgr_snoop_offload_sp_req_param_t offload_sp_req;
415     offload_sp_req.trans_id = req->trans_id;
416     offload_sp_req.policy_id = req->policy_id;
417     offload_sp_req.sa_flags = req->sa_flags;
418     offload_sp_req.if_name = req->if_name;
419     offload_sp_req.dscp_cfg = req->dscp_cfg;
420     offload_sp_req.l5_selector = req->l5_selector;
422     memset(&rsp, 0, sizeof(rsp));
423     rsp.trans_id = req->trans_id;
425     if (ipsecmgr_snoop_offload_sp_req(&offload_sp_req, (void*)src_addr,
426                                       addr_size)) {
427         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
428             "offload_sp_req_recv: snoop_offload_sp_req failed\n");
429         rsp.result = RESULT_FAILURE;
430         rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
431     }
432     else
433     {
434         rsp.result = RESULT_SUCCESS;
435         rsp.type = RSP_TYPE_ACK;
436     }
437     
438     if (offload_sp_rsp_send(&rsp, (void *)src_addr, addr_size))
439     {
440         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
441             "offload_sp_req_recv: failed to send ACK for offload_sp\n");
442     }
443     return;
447 /**
448  *  @b Description
449  *  @n  
450  *      NETAPI Proxy's IPSecMgr Stop Offload response message 
451  *      handler.
452  *
453  *      This function is called by the IPSecMgr library
454  *      when it has a response ready corresponding to an
455  *      Stop Offload SP request issued by the user application.
456  *
457  *  @param[in]  rsp
458  *      IPSecMgr's Stop Offload SP response
459  *  @param[in]  addr
460  *      Destination address (user application) to send 
461  *      the response to
462  *  @param[in]  addr_size
463  *      Size of destination address passed
464  *
465  *  @retval
466  *      Success -   0
467  *  @retval
468  *      ERROR   -   <0
469  */
470 static int stop_offload_rsp_send
472     ipsecmgr_snoop_stop_offload_rsp_param_t *rsp,
473     void                                    *addr,
474     uint32_t                                addr_size
477     ipsecmgr_ipc_stop_offload_rsp_param_t stop_offload_rsp;
479     stop_offload_rsp.type = rsp->type;
480     stop_offload_rsp.result = rsp->result;
481     stop_offload_rsp.trans_id = rsp->trans_id;
483     if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
484         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
485             "stop_offload_rsp_send: addr size not correct\n");
486         return -1;
487     }
489     return send_iface->stop_offload_rsp(&stop_offload_rsp,
490                                       (ipsecmgr_ipc_addr_t *)addr);
493 static void stop_offload_req_recv
495     ipsecmgr_ipc_stop_offload_req_param_t   *req,
496     ipsecmgr_ipc_addr_t                     *src_addr
499     ipsecmgr_snoop_stop_offload_req_param_t stop_offload_req;
500     uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
501     ipsecmgr_snoop_stop_offload_rsp_param_t rsp;
503     stop_offload_req.trans_id = req->trans_id;
504     stop_offload_req.policy_id = req->policy_id;
506     memset(&rsp, 0, sizeof(rsp));
507     rsp.trans_id = req->trans_id;
509     if (ipsecmgr_snoop_stop_offload(&stop_offload_req, (void*)src_addr,
510                                       addr_size)) {
511         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
512             "stop_offload_req_recv: snoop_stop_offload failed\n");
513         rsp.result = RESULT_FAILURE;
514         rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
515     }
516     else
517     {
518         rsp.result = RESULT_SUCCESS;
519         rsp.type = RSP_TYPE_ACK;
520     }
522     if (stop_offload_rsp_send(&rsp, (void *)src_addr, addr_size))
523     {
524         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
525             "stop_offload_req_recv: failed to send ACK for stop_offload\n");
526     }
527     return;
530 /**
531  *  @b Description
532  *  @n  
533  *      Function to initialize IPSec Manager library.
534  *
535  *  @retval
536  *      Success -   0
537  *  @retval
538  *      ERROR   -   >0
539  */
540 static int32_t init_ipsecmgr (void)
542     struct ipsecmgr_snoop_fp_cfg_cb     fp_cfg_cb;
543     struct ipsecmgr_snoop_mgnt_cb       mgnt_cb;
544     struct ipsecmgr_snoop_platform_cb   plat_cb;
545     ipsecmgr_ipc_daemon_recv_if_t       recv_if;
546     ipsecmgr_ipc_cfg_t                  ipc_cfg;
547     int32_t                             status;
548     pthread_attr_t threadAttr;
550     /* Initializations */
551     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO, 
552                         "DEBUG: init_ipsecmgr() starting initialization\n");
553     memset(&fp_cfg_cb, 0, sizeof(fp_cfg_cb));
554     memset(&mgnt_cb, 0, sizeof(mgnt_cb));
555     memset(&plat_cb, 0, sizeof(plat_cb));
556     memset(&recv_if, 0, sizeof(recv_if));
557     memset(&ipc_cfg, 0, sizeof(ipc_cfg));
559     /* Initialize IPC library */
560     ipc_cfg.mode = IPC_MODE_SNOOP_DAEMON;
561     if (ipsecmgr_ipc_init(&ipc_cfg)) {
562         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
563             "init_ipsecmgr: ipc_init failed\n");
564         return -1;
565     }
566     else
567         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
568             "init_ipsecmgr: ipc_init sucess\n");
570     if (ipsecmgr_ipc_get_daemon_send_iface(&send_iface)) {
571         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
572             "init_ipsecmgr: ipc_get_daemon_send_iface failed\n");
573         return -1;
574     }
575     recv_if.offload_sp_req = offload_sp_req_recv;
576     recv_if.stop_offload_req = stop_offload_req_recv;
577     /* Register ipsecmgr daemon recieve i/f */
578     if (ipsecmgr_ipc_register_daemon_recv_iface(&recv_if)) {
579         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
580             "snoop_run: ipc_register_daemon_recv_iface failed\n");
581         return -1;
582     }
584     /* Initialize the IPSec Manager Snoop library */
585     fp_cfg_cb.add_sa        =   netapilib_ifAddSA;
586     fp_cfg_cb.add_sp        =   netapilib_ifAddSP;
587     fp_cfg_cb.del_sa        =   netapilib_ifDeleteSA;
588     fp_cfg_cb.del_sp        =   netapilib_ifDeleteSP;
589     fp_cfg_cb.get_sa_ctx    =   netapilib_ifGetSACtx;
591     plat_cb.log_msg  = (ipsecmgr_snoop_log_msg_t)ipsecmgr_syslog_msg;
592     plat_cb.sleep           =   task_sleep;
594     mgnt_cb.offload_sp_rsp  =   offload_sp_rsp_send;
595     mgnt_cb.stop_offload_rsp=   stop_offload_rsp_send;
596     mgnt_cb.rekey_event     =   NULL; // No explicit notifications needed on Rekey completion
598     if ((status = ipsecmgr_snoop_init (&fp_cfg_cb, &mgnt_cb, &plat_cb))) 
599     {
600         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
601                             "DEBUG: init_ipsecmgr() ipsecmgr_snoop_init failed (%d)\n", status);
602         return -1;
603     }
605     /* Create the task context for snoop library */
606     pthread_attr_init(&threadAttr);
607     pthread_attr_setstacksize(&threadAttr, 0x10000);
608     if (pthread_create(&snoop_run_th, (void*) NULL, snoop_run_thread, NULL))
609     {
610         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
611             "ERROR: snoop run thread failed to start, error code\n"); 
612         return -1;
613     }
615     /* Setup signal handler for SIGTERM */
616     if (signal(SIGTERM, sig_term_handler) == SIG_ERR) {
617         ipsecmgr_syslog_msg(SYSLOG_LEVEL_WARN,
618             "init_ipsecmgr: cannot handle SIGTERM\n");
619     }
620     /* Wait for the NETAPI Proxy task to finish its processing and exit. */
621     pthread_join (snoop_run_th, NULL);
623     return 0;
626 /**
627  *  @b Description
628  *  @n  
629  *      Utility function to daemonize the current
630  *      application.
631  *
632  *  @param[in]  lock_file
633  *      Lock file to be used by the daemon
634  */
635 static void daemonize (const char *lock_file)
637     pid_t       pid, sid;
638     int32_t     lock_fp = -1;
639     char        str[10];
641     /* already a daemon */
642     if (getppid () == 1)
643         return;
645     /* Fork off the parent process */
646     if ((pid = fork ()) < 0) 
647     {
648         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
649                             "ERROR: daemonize() unable to fork daemon, code=%d (%s)",
650                             errno, 
651                             strerror(errno));
652         exit (-1);
653     }
655     /* If we got a PID, then exit the parent process. */
656     if (pid > 0)
657         exit (0);
659     /* At this point we are executing as the child process */
661     /* Create a new SID for the child process */
662     if ((sid = setsid ()) < 0) 
663     {
664         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
665                             "ERROR: daemonize() unable to create a new session, code %d (%s)",
666                             errno, 
667                             strerror(errno));
668         exit (-1);
669     }
671     /* Change the file mode mask */
672     umask (027);
674     /* Change the current working directory.  This prevents the current
675      * directory from being locked; hence not being able to remove it. */
676     if ((chdir("/")) < 0) 
677     {
678         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
679                             "ERROR: daemonize() unable to change directory to %s, code %d (%s)",
680                             "/", 
681                             errno, 
682                             strerror(errno));
683         exit (-1);
684     }
686     /* Create the lock file */
687     if (lock_file) 
688     {
689         if ((lock_fp = open(lock_file, O_RDWR|O_CREAT, 0640)) < 0 ) 
690         {
691             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR, 
692                                 "ERROR: daemonize() unable to create lock file %s, code=%d (%s)",
693                                 lock_file, 
694                                 errno, 
695                                 strerror(errno));
696             exit (-1);
697         }
698     }
700     if (lockf (lock_fp, F_TLOCK, 0) < 0) 
701         exit(-1); /* can not lock */
703     /* Record pid to lockfile */
704     sprintf (str, "%d\n", getpid());
705     write (lock_fp, str, strlen(str)); 
707     /* Cancel certain signals */
708     signal (SIGCHLD, SIG_DFL); /* A child process dies */
709     signal (SIGTSTP, SIG_IGN); /* Various TTY signals */
710     signal (SIGTTOU, SIG_IGN);
711     signal (SIGTTIN, SIG_IGN);
712     signal (SIGHUP, SIG_IGN); /* Ignore hangup signal */
713     signal (SIGTERM, sig_term_handler); /* catch SIGTERM */
715     /* Redirect standard files to /dev/null */
716     freopen( "/dev/null", "r", stdin);
717     freopen( "/dev/null", "w", stdout);
718     freopen( "/dev/null", "w", stderr);
720     /* Done setting up the daemon */
721     return;
724 /* FUNCTION PURPOSE:validate and process inputs to the application */
725 int32_t parse_cmd_line_args(int argc, char** argv)
727     int32_t             i;
729     /* Valid command line options */
730     if (argc == 1)
731     {
732         printf("netapi_proxyParseCommandLineArgs, argc =1\n");
733         return 0;
734     }
735     else
736     {
737            printf("netapi_proxyParseCommandLineArgs, argc=%d\n", argc);
738     }
740     /* Scan and parse the command line options */
741     for (i = 1; i < argc; i ++)
742     {
743         if (argv[i][0] == '-' && argv[i][1] == 'f')
744         {
745             /* Log file name */                
746             if (i+1 >= argc || argv[i+1] == NULL)
747                 return -1;
748             i++;
749         }
750         else
751         {
752             /* Invalid options */
753             return -1;
754         }
755     }
756     /* Success */
757     return 0;
760 int get_kernel_config(int index)
762     uint32_t temp=0;
763     FILE *pDts = NULL;
765     pDts = fopen(DTS_LOG_FILE_QUEUE_ETHx[index], "rb");
767     if(pDts)
768     {
769         fread((void*)&temp, sizeof(uint32_t), 1, pDts);
770         globalDB.qNum[index]= (int)swap32(temp);
771         fclose(pDts);
772     }
773     else
774     {
775         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
776             "main: error opening device tree file: %s\n",DTS_LOG_FILE_QUEUE_ETHx[index]);
777         return -1;
778     }
780     pDts = NULL;
781     pDts = fopen(DTS_LOG_FILE_FLOW_ETHx[index], "rb");
783     if(pDts)
784     {
785         fread((void*)&temp, sizeof(uint32_t), 1, pDts);
786         globalDB.flowId[index] = (int)swap32(temp);
787         fclose(pDts);
788     }
789     else
790     {
791         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
792             "main: error opening device tree file: %s\n",DTS_LOG_FILE_FLOW_ETHx[index]);
793         return -1;
794     }
795     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
796             "get_kernel_config(%d): flow: 0x%x, qNum: 0x%x\n", 
797                     index, globalDB.flowId[index], globalDB.qNum[index]);
798     return 0;
801 int create_pktio_channel(int index)
803     static int count = 0;
804     int error = 0;
805     char name[19];
806     PKTIO_HANDLE_T *pktio_channel;
807     PKTIO_CFG_T pktio_cfg;
808     NETCP_CFG_ROUTE_T route;
809     NETCP_CFG_FLOW_T flow;
810     NETCP_CFG_EXCEPTION_PKT_T expPkt_appid = 0;
812     memset(&pktio_cfg,0,sizeof(PKTIO_CFG_T));
813     memset((void *)&route, 0, sizeof (NETCP_CFG_ROUTE_T));
814     memset((void *)&flow, 0, sizeof (NETCP_CFG_FLOW_T));
816     sprintf(&name[0],"%s%d","offload_", index);
817     pktio_cfg.qnum = globalDB.qNum[index];
818     pktio_cfg.flags1 = PKTIO_RX;
819     pktio_cfg.flags2 = PKTIO_GLOBAL | PKTIO_PKT;
820     pktio_cfg.max_n = 8;
822     globalDB.pktio_channel[index] = netapi_pktioCreate(netapi_handle,
823                                                &name[0],
824                                                (PKTIO_CB)recv_cb,
825                                                &pktio_cfg,
826                                                &error);
827     if (!globalDB.pktio_channel[index])
828     {
829         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
830             "create_pktio_channel: failed\n");
831         return -1;
832     }
834     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
835             "create_pktio_channel: index: %d, qnum: %d, pktio_handle: 0x%x\n",
836             index, 
837             pktio_cfg.qnum,
838             globalDB.pktio_channel[index]);
840     /* Only want to create exception route for 1st interface */
841     if (index != 0)
842         return 0;
843     flow.dma_engine= 1;
844     flow.flowid = globalDB.flowId[index];
845     route.p_dest_q = globalDB.pktio_channel[index];
846     route.p_flow = &flow;
848     /* enable exception packet handling for fragmented packets */
849     expPkt_appid = netapi_netcpCfgExceptions(netapi_handle,
850                                              7,
851                                              NETCP_CFG_ACTION_TO_SW,
852                                              (NETCP_CFG_ROUTE_HANDLE_T) &route);
853     printf("create_pktio_channel: expPkt appid: 0x%x\n", expPkt_appid);
855     return 0;
857 /**
858  *  @b Description
859  *  @n  
860  *      Entry point for the NETAPI Proxy application.
861  *
862  *  @param[in]  argc
863  *      Number of arguments passed to the application
864  *  @param[in]  argv
865  *      Arguments passed to the application.
866  *
867  *  @retval
868  *      Success -   0
869  *  @retval
870  *      ERROR   -   >0
871  */
872 int32_t main (int argc, char* argv[])
874     int32_t             retVal;
875     int i, iface;
876     char* pTok = NULL;
877     int ip_entry_count = 0;
878     struct ifaddrs *ifaddr, *ifa;
879     int family, s;
880     char host[NI_MAXHOST];
881     struct sockaddr_in6 ipv6_addr;
882     cpu_set_t cpu_set;
883     ipsecmgr_syslog_init();
885     memset(&globalDB, 0, sizeof(globalDB));
886     memset(&ipConfigList, 0, sizeof(ipConfigList));
888         /* assign main net_test thread to run on core 0 */
889     CPU_ZERO( &cpu_set);
890     CPU_SET( 0, &cpu_set);
891     hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
892     /* create netapi */
893     netapi_handle = netapi_init(NETAPI_SYS_MASTER, &our_netapi_default_cfg);
895     if(netapi_handle == NULL)
896     {
897         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR, "ERROR: netapi_init failed\n");
898         return -1;
899     }
900     else
901         netapi_netcpCfgExceptions(netapi_handle, NETCP_CFG_ALL_EXCEPTIONS, NETCP_CFG_ACTION_DISCARD, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
903     for (i = 0; i < 1; i++)
904     {
905         if (get_kernel_config(i))
906         {
907             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
908                                 "ERROR: main: get_kernel_config() failed\n");
909             continue;
910         }
911         else
912         {
913             /* create pktio channel */
914             if(create_pktio_channel(i))
915             {
916                 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
917                                 "ERROR: main: pktio channel creation failed\n");
918             }
919         }
920     }
921     /* Read and parse command line options */
922     if (parse_cmd_line_args (argc, argv) < 0)
923     {
924         printf ("Usage format: netfpproxy.out [-f <log_file>]\n");
925         return -1;
926     }
927     
929     /* Create the proxy daemon. */
930     /*printf("main: calling daemonize\n");
931     daemonize (LOCK_FILE); */
934 #if to_delete
935     if (getifaddrs(&ifaddr) == -1)
936     {
937         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
938                                 "main: getifaddrs failure\n");
939         return -1;
940     }
942     for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
943     {
944         if (ifa->ifa_addr == NULL)
945             continue;
947         family = ifa->ifa_addr->sa_family;
949         ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
950                         "%s  address family: %d%s\n",
951                         ifa->ifa_name, family,
952                         (family == AF_PACKET) ? " (AF_PACKET)" :
953                         (family == AF_INET) ?   " (AF_INET)" :
954                         (family == AF_INET6) ?  " (AF_INET6)" : "");
955         if ((family == AF_INET) ||(family == AF_INET6))
956         {
957             s = getnameinfo(ifa->ifa_addr,
958                 (family == AF_INET) ? sizeof(struct sockaddr_in):
959                                       sizeof(struct sockaddr_in6),
960                 host,
961                 NI_MAXHOST,
962                 NULL,
963                 0,
964                 NI_NUMERICHOST);
966             if (s != 0)
967             {
968                 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
969                     "getnameinfo() failed: %s\n", gai_strerror(s));
970                     continue;
971             }
972             if (family == AF_INET)
973             {
974                 ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
975                                     "ipv4 string %s\n", host);
976                 for (i=0;i<NWAL_IPV4_ADDR_SIZE;i++)
977                 {
978                     ipConfigList[ip_entry_count].ip[i] =
979                                     ifa->ifa_addr->sa_data[i+2];
980                 }
981             }
982             else
983             {
984                 pTok = strtok(host,"%");
985                 for (i=0;i<NWAL_IPV6_ADDR_SIZE;i++)
986                 {
987                     inet_pton(AF_INET6, pTok, &(ipv6_addr.sin6_addr));
989                     ipConfigList[ip_entry_count].ip[i] =
990                         ipv6_addr.sin6_addr.s6_addr[i];
991                     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
992                         "ipv6[%d]: 0x%x\n",
993                         i,
994                         ipConfigList[ip_entry_count].ip[i]);
995                 }
996             }
997             memcpy(&ipConfigList[ip_entry_count].name[0],
998                     ifa->ifa_name,
999                     strlen(ifa->ifa_name));
1000             pTok = strtok(ifa->ifa_name, ":.");
1001             /* now we have the interface name, is this eth0, eth1 or bridge i/f */
1002             if (pTok)
1003             {
1004                 if(strstr(pTok,"eth"))
1005                 {
1006                     sscanf(pTok,"eth%d", &iface);
1007                     ipConfigList[ip_entry_count].iface = iface;
1008                     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
1009                         "eth i/f found with iface %d\n", iface);
1010                 }
1011                 else if(strstr(pTok,"br"))
1012                 {
1013                     sscanf(pTok,"br%d", &iface);
1014                     ipConfigList[ip_entry_count].iface = iface;
1015                     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
1016                         "bridge i/f found with iface %d\n", iface);
1017                 }
1018                 else
1019                 {
1020                     ipConfigList[ip_entry_count].iface = -1;
1021                 }
1022                 ip_entry_count++;
1023             }
1024         }
1025     }
1027     if (ifaddr)
1028         freeifaddrs(ifaddr);
1029 #endif
1030     /* Initialize and start the IPSec Mgr Snoop functionality */
1031     if ((retVal = init_ipsecmgr ()) < 0)
1032     {
1033         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
1034                             "ERROR: IPSec Mgr init failed, error code %d \n",
1035                             retVal);
1036         return -1;
1037     }
1038     else
1039         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
1040                              "main: ipsecmgr daemon shutdonw complete\n");