[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/drv/qmss/device/k2h/src/qmss_device.c>
65 #include <ti/drv/cppi/device/k2h/src/cppi_device.c>
66 char* DTS_LOG_FILE_QUEUE_ETHx[] = {
67 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
68 char* DTS_LOG_FILE_FLOW_ETHx[] = {
69 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
70 #elif defined (DEVICE_K2K)
71 #include <ti/drv/qmss/device/k2k/src/qmss_device.c>
72 #include <ti/drv/cppi/device/k2k/src/cppi_device.c>
73 char* DTS_LOG_FILE_QUEUE_ETHx[] = {
74 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
75 char* DTS_LOG_FILE_FLOW_ETHx[] = {
76 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
77 #elif defined (DEVICE_K2L)
78 #include <ti/drv/qmss/device/k2l/src/qmss_device.c>
79 #include <ti/drv/cppi/device/k2l/src/cppi_device.c>
80 char* DTS_LOG_FILE_QUEUE_ETHx[] = {
81 "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/complete-queue"};
82 char* DTS_LOG_FILE_FLOW_ETHx[] = {
83 "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/flow"};
84 #elif defined (DEVICE_K2E)
85 #include <ti/drv/qmss/device/k2e/src/qmss_device.c>
86 #include <ti/drv/cppi/device/k2e/src/cppi_device.c>
87 char* DTS_LOG_FILE_QUEUE_ETHx[] = {
88 "/proc/device-tree/soc/pktdma@24186000/channels/netrx0/complete-queue"};
89 char* DTS_LOG_FILE_FLOW_ETHx[] = {
90 "/proc/device-tree/soc/pktdma@24186000/channels/netrx0/flow"};
92 #else /*Default */
93 #include <ti/runtime/hplib/device/k2h/src/hplib_device.c>
94 #include <ti/runtime/netapi/device/k2h/src/netapi_device.c>
95 #include <ti/drv/qmss/device/k2h/src/qmss_device.c>
96 #include <ti/drv/cppi/device/k2h/src/cppi_device.c>
97 char* DTS_LOG_FILE_QUEUE_ETHx[] = {
98 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
99 char* DTS_LOG_FILE_FLOW_ETHx[] = {
100 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
102 #endif
104 /**********************************************************************
105 ************************** Local Definitions *************************
106 **********************************************************************/
107 #if 0
109 char* DTS_LOG_FILE_QUEUE_ETHx[] = {
110 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
111 char* DTS_LOG_FILE_FLOW_ETHx[] = {
112 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
114 char* DTS_LOG_FILE_QUEUE_ETHx[] = {
115 "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/complete-queue"};
116 char* DTS_LOG_FILE_FLOW_ETHx[] = {
117 "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/flow"};
118 #endif
121 /**********************************************************************
122 ************************** Global Variables **************************
123 **********************************************************************/
125 static ipsecmgr_ipc_daemon_send_if_t *send_iface;
126 NETAPI_T netapi_handle;
128 ipsecMgrMcb_t globalDB;
130 /* Lock file for the daemon */
131 #define LOCK_FILE "/var/lock/ipsecmgr_daemon"
133 /* snoop task */
134 static pthread_t snoop_run_th;
136 static NETAPI_CFG_T our_netapi_default_cfg=
137 {
138 TUNE_NETAPI_PERM_MEM_SZ,
139 128, //start of packet offset for hw to place data on rx for default flow
140 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
141 TUNE_NETAPI_NUM_GLOBAL_DESC, //total we will use
142 TUNE_NETAPI_DEFAULT_NUM_BUFFERS, //#descriptors+buffers in default heap
143 64, //#descriptors w/o buffers in default heap
144 TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128, //size of buffers in default heap
145 128, //tail room
146 256, //extra room
147 0
148 };
152 static int QUIT = 0;
154 /* stub functions */
155 static void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
156 PKTIO_METADATA_T meta[], int n_pkts,
157 uint64_t ts )
158 {
159 return;
160 }
162 /* byte swap routine */
163 static unsigned int swap32 (unsigned int x)
164 {
165 unsigned int y;
167 y = (((x >> 24) & 0xff) << 0) |
168 (((x >> 16) & 0xff) << 8) |
169 (((x >> 8) & 0xff) << 16) |
170 (((x >> 0) & 0xff) << 24) ;
172 return (y);
174 }
176 void cleanup_sa_sp()
177 {
178 int slot, error=0;;
179 /* delete any offloaded rx SA's and policies */
180 /* and delete any offloaded tx SA's */
181 for (slot = 0;slot < 64;slot++)
182 {
183 if(globalDB.rx_sa[slot].in_use)
184 {
185 globalDB.rx_sa[slot].in_use = 0;
186 if(globalDB.rx_sa[slot].spAppId)
187 {
188 netapi_secDelRxPolicy(netapi_handle,
189 (NETCP_CFG_IPSEC_POLICY_T) globalDB.rx_sa[slot].spAppId,
190 &error);
191 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
192 "cleanup_sa_sp: SP deleted: sp_app_id: 0x%x, slot: %d, error: %d\n",
193 globalDB.rx_sa[slot].spAppId, slot, error);
194 }
195 netapi_secDelSA(netapi_handle,
196 NETCP_CFG_NO_INTERFACE,
197 (NETCP_CFG_SA_T) globalDB.rx_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.rx_sa[slot].saAppId, slot, error);
203 }
204 if(globalDB.tx_sa[slot].in_use)
205 {
206 globalDB.tx_sa[slot].in_use = 0;
207 netapi_secDelSA(netapi_handle,
208 NETCP_CFG_NO_INTERFACE,
209 (NETCP_CFG_SA_T) globalDB.tx_sa[slot].saAppId,
210 &error);
211 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
212 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n",
213 globalDB.tx_sa[slot].saAppId, slot, error);
214 }
215 }
216 }
219 static void* snoop_run_thread (void* arg)
220 {
221 cpu_set_t cpu_set;
222 CPU_ZERO( &cpu_set);
223 CPU_SET( 0, &cpu_set);
225 hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
226 ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
227 "snoop_run_thread: daemon entering forever event loop\n");
229 while (1)
230 {
231 /* Poll for message from user application */
232 ipsecmgr_ipc_poll();
234 /* Poll for message from Kernel */
235 ipsecmgr_snoop_run();
236 if (QUIT == 1)
237 break;
238 }
239 ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
240 "snoop_run_thread: calling shutdown\n");
241 ipsecmgr_snoop_shutdown ();
242 cleanup_sa_sp();
243 netapi_shutdown(netapi_handle);
245 return;
246 }
248 /**
249 * @b Description
250 * @n
251 * SIGTERM handler.
252 *
253 * @param[in] signum
254 * signal number to terminate deamon.
255 */
256 static void sig_term_handler(int signum)
257 {
258 QUIT = 1;
259 }
261 /**
262 * @b Description
263 * @n
264 * Function to implement task sleep functionality
265 * for IPSecMgr
266 *
267 * @param[in] time_in_msec
268 * Time in milliseconds to sleep
269 *
270 * @retval
271 * Not Applicable.
272 */
273 static void task_sleep(uint32_t time_in_msec)
274 {
275 pthread_mutex_t fake_mutex = PTHREAD_MUTEX_INITIALIZER;
276 pthread_cond_t fake_cond = PTHREAD_COND_INITIALIZER;
277 struct timespec ts;
278 int rt;
279 unsigned int sec, nsec;
281 sec = time_in_msec/1000;
282 nsec = (time_in_msec - (sec*1000)) * 1000000;
284 /* Use the wall-clock time */
285 clock_gettime(CLOCK_REALTIME, &ts);
287 ts.tv_sec += sec;
288 ts.tv_nsec += nsec;
290 pthread_mutex_lock(&fake_mutex);
291 rt = pthread_cond_timedwait(&fake_cond, &fake_mutex, &ts);
292 pthread_mutex_unlock(&fake_mutex);
293 }
296 /**
297 * @b Description
298 * @n
299 * NETAPI Proxy's IPSecMgr Start Offload Response
300 * message handler.
301 *
302 * This function is called by the IPSecMgr library
303 * when it has a response ready corresponding to an
304 * Start Offload SP request issued by the user application.
305 *
306 * @param[in] rsp
307 * IPSecMgr's Start Offload SP response
308 * @param[in] addr
309 * Destination address (user application) to send
310 * the response to
311 * @param[in] addr_size
312 * Size of destination address passed
313 *
314 * @retval
315 * Success - 0
316 * @retval
317 * ERROR - <0
318 */
319 static int offload_sp_rsp_send
320 (
321 ipsecmgr_snoop_offload_sp_rsp_param_t *rsp,
322 void *addr,
323 uint32_t addr_size
324 )
325 {
326 ipsecmgr_ipc_offload_sp_rsp_param_t offload_sp_rsp;
328 offload_sp_rsp.type = rsp->type;
329 offload_sp_rsp.result = rsp->result;
330 offload_sp_rsp.trans_id = rsp->trans_id;
331 offload_sp_rsp.err_code = rsp->err_code;
332 offload_sp_rsp.sp_handle = rsp->sp_handle;
333 offload_sp_rsp.sa_handle = rsp->sa_handle;
335 if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
336 ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
337 "offload_sp_rsp_send: addr size not correct\n");
338 return -1;
339 }
341 return send_iface->offload_sp_rsp(&offload_sp_rsp,
342 (ipsecmgr_ipc_addr_t *)addr);
343 }
344 static void offload_sp_req_recv
345 (
346 ipsecmgr_ipc_offload_sp_req_param_t *req,
347 ipsecmgr_ipc_addr_t *src_addr
348 )
349 {
350 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"offload_sp_req_recv called for policy id\n",
351 req->policy_id);
352 ipsecmgr_snoop_offload_sp_rsp_param_t rsp;
353 uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
354 ipsecmgr_snoop_offload_sp_req_param_t offload_sp_req;
356 offload_sp_req.trans_id = req->trans_id;
357 offload_sp_req.policy_id = req->policy_id;
358 offload_sp_req.sa_flags = req->sa_flags;
359 offload_sp_req.if_name = req->if_name;
360 offload_sp_req.dscp_cfg = req->dscp_cfg;
361 offload_sp_req.l5_selector = req->l5_selector;
363 memset(&rsp, 0, sizeof(rsp));
364 rsp.trans_id = req->trans_id;
366 if (ipsecmgr_snoop_offload_sp_req(&offload_sp_req, (void*)src_addr,
367 addr_size)) {
368 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
369 "offload_sp_req_recv: snoop_offload_sp_req failed\n");
370 rsp.result = RESULT_FAILURE;
371 rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
372 }
373 else
374 {
375 rsp.result = RESULT_SUCCESS;
376 rsp.type = RSP_TYPE_ACK;
377 }
379 if (offload_sp_rsp_send(&rsp, (void *)src_addr, addr_size))
380 {
381 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
382 "offload_sp_req_recv: failed to send ACK for offload_sp\n");
383 }
384 return;
385 }
388 /**
389 * @b Description
390 * @n
391 * NETAPI Proxy's IPSecMgr Stop Offload response message
392 * handler.
393 *
394 * This function is called by the IPSecMgr library
395 * when it has a response ready corresponding to an
396 * Stop Offload SP request issued by the user application.
397 *
398 * @param[in] rsp
399 * IPSecMgr's Stop Offload SP response
400 * @param[in] addr
401 * Destination address (user application) to send
402 * the response to
403 * @param[in] addr_size
404 * Size of destination address passed
405 *
406 * @retval
407 * Success - 0
408 * @retval
409 * ERROR - <0
410 */
411 static int stop_offload_rsp_send
412 (
413 ipsecmgr_snoop_stop_offload_rsp_param_t *rsp,
414 void *addr,
415 uint32_t addr_size
416 )
417 {
418 ipsecmgr_ipc_stop_offload_rsp_param_t stop_offload_rsp;
420 stop_offload_rsp.type = rsp->type;
421 stop_offload_rsp.result = rsp->result;
422 stop_offload_rsp.trans_id = rsp->trans_id;
424 if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
425 ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
426 "stop_offload_rsp_send: addr size not correct\n");
427 return -1;
428 }
430 return send_iface->stop_offload_rsp(&stop_offload_rsp,
431 (ipsecmgr_ipc_addr_t *)addr);
432 }
434 static void stop_offload_req_recv
435 (
436 ipsecmgr_ipc_stop_offload_req_param_t *req,
437 ipsecmgr_ipc_addr_t *src_addr
438 )
439 {
440 ipsecmgr_snoop_stop_offload_req_param_t stop_offload_req;
441 uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
442 ipsecmgr_snoop_stop_offload_rsp_param_t rsp;
444 stop_offload_req.trans_id = req->trans_id;
445 stop_offload_req.policy_id = req->policy_id;
447 memset(&rsp, 0, sizeof(rsp));
448 rsp.trans_id = req->trans_id;
450 if (ipsecmgr_snoop_stop_offload(&stop_offload_req, (void*)src_addr,
451 addr_size)) {
452 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
453 "stop_offload_req_recv: snoop_stop_offload failed\n");
454 rsp.result = RESULT_FAILURE;
455 rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
456 }
457 else
458 {
459 rsp.result = RESULT_SUCCESS;
460 rsp.type = RSP_TYPE_ACK;
461 }
463 if (stop_offload_rsp_send(&rsp, (void *)src_addr, addr_size))
464 {
465 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
466 "stop_offload_req_recv: failed to send ACK for stop_offload\n");
467 }
468 return;
469 }
471 /**
472 * @b Description
473 * @n
474 * Function to initialize IPSec Manager library.
475 *
476 * @retval
477 * Success - 0
478 * @retval
479 * ERROR - >0
480 */
481 static int32_t init_ipsecmgr (void)
482 {
483 struct ipsecmgr_snoop_fp_cfg_cb fp_cfg_cb;
484 struct ipsecmgr_snoop_mgnt_cb mgnt_cb;
485 struct ipsecmgr_snoop_platform_cb plat_cb;
486 ipsecmgr_ipc_daemon_recv_if_t recv_if;
487 ipsecmgr_ipc_cfg_t ipc_cfg;
488 int32_t status;
489 pthread_attr_t threadAttr;
491 /* Initializations */
492 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
493 "DEBUG: init_ipsecmgr() starting initialization\n");
494 memset(&fp_cfg_cb, 0, sizeof(fp_cfg_cb));
495 memset(&mgnt_cb, 0, sizeof(mgnt_cb));
496 memset(&plat_cb, 0, sizeof(plat_cb));
497 memset(&recv_if, 0, sizeof(recv_if));
498 memset(&ipc_cfg, 0, sizeof(ipc_cfg));
500 /* Initialize IPC library */
501 ipc_cfg.mode = IPC_MODE_SNOOP_DAEMON;
502 if (ipsecmgr_ipc_init(&ipc_cfg)) {
503 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
504 "init_ipsecmgr: ipc_init failed\n");
505 return -1;
506 }
507 else
508 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
509 "init_ipsecmgr: ipc_init sucess\n");
511 if (ipsecmgr_ipc_get_daemon_send_iface(&send_iface)) {
512 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
513 "init_ipsecmgr: ipc_get_daemon_send_iface failed\n");
514 return -1;
515 }
516 recv_if.offload_sp_req = offload_sp_req_recv;
517 recv_if.stop_offload_req = stop_offload_req_recv;
518 /* Register ipsecmgr daemon recieve i/f */
519 if (ipsecmgr_ipc_register_daemon_recv_iface(&recv_if)) {
520 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
521 "snoop_run: ipc_register_daemon_recv_iface failed\n");
522 return -1;
523 }
525 /* Initialize the IPSec Manager Snoop library */
526 fp_cfg_cb.add_sa = netapilib_ifAddSA;
527 fp_cfg_cb.add_sp = netapilib_ifAddSP;
528 fp_cfg_cb.del_sa = netapilib_ifDeleteSA;
529 fp_cfg_cb.del_sp = netapilib_ifDeleteSP;
530 fp_cfg_cb.get_sa_ctx = netapilib_ifGetSACtx;
532 plat_cb.log_msg = (ipsecmgr_snoop_log_msg_t)ipsecmgr_syslog_msg;
533 plat_cb.sleep = task_sleep;
535 mgnt_cb.offload_sp_rsp = offload_sp_rsp_send;
536 mgnt_cb.stop_offload_rsp= stop_offload_rsp_send;
537 mgnt_cb.rekey_event = NULL; // No explicit notifications needed on Rekey completion
539 if ((status = ipsecmgr_snoop_init (&fp_cfg_cb, &mgnt_cb, &plat_cb)))
540 {
541 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
542 "DEBUG: init_ipsecmgr() ipsecmgr_snoop_init failed (%d)\n", status);
543 return -1;
544 }
548 #ifdef GDB_DEBUG
549 snoop_run_thread(NULL);
550 #else
551 /* Create the task context for snoop library */
552 pthread_attr_init(&threadAttr);
553 pthread_attr_setstacksize(&threadAttr, 0x10000);
554 if (pthread_create(&snoop_run_th, (void*) NULL, snoop_run_thread, NULL))
555 {
556 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
557 "ERROR: snoop run thread failed to start, error code\n");
558 return -1;
559 }
561 /* Setup signal handler for SIGTERM */
562 if (signal(SIGTERM, sig_term_handler) == SIG_ERR) {
563 ipsecmgr_syslog_msg(SYSLOG_LEVEL_WARN,
564 "init_ipsecmgr: cannot handle SIGTERM\n");
565 }
566 /* Wait for the NETAPI Proxy task to finish its processing and exit. */
567 pthread_join (snoop_run_th, NULL);
568 #endif
569 return 0;
570 }
572 /**
573 * @b Description
574 * @n
575 * Utility function to daemonize the current
576 * application.
577 *
578 * @param[in] lock_file
579 * Lock file to be used by the daemon
580 */
581 static void daemonize (const char *lock_file)
582 {
583 pid_t pid, sid;
584 int32_t lock_fp = -1;
585 char str[10];
587 /* already a daemon */
588 if (getppid () == 1)
589 return;
591 /* Fork off the parent process */
592 if ((pid = fork ()) < 0)
593 {
594 ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
595 "ERROR: daemonize() unable to fork daemon, code=%d (%s)",
596 errno,
597 strerror(errno));
598 exit (-1);
599 }
601 /* If we got a PID, then exit the parent process. */
602 if (pid > 0)
603 exit (0);
605 /* At this point we are executing as the child process */
607 /* Create a new SID for the child process */
608 if ((sid = setsid ()) < 0)
609 {
610 ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
611 "ERROR: daemonize() unable to create a new session, code %d (%s)",
612 errno,
613 strerror(errno));
614 exit (-1);
615 }
617 /* Change the file mode mask */
618 umask (027);
620 /* Change the current working directory. This prevents the current
621 * directory from being locked; hence not being able to remove it. */
622 if ((chdir("/")) < 0)
623 {
624 ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
625 "ERROR: daemonize() unable to change directory to %s, code %d (%s)",
626 "/",
627 errno,
628 strerror(errno));
629 exit (-1);
630 }
632 /* Create the lock file */
633 if (lock_file)
634 {
635 if ((lock_fp = open(lock_file, O_RDWR|O_CREAT, 0640)) < 0 )
636 {
637 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
638 "ERROR: daemonize() unable to create lock file %s, code=%d (%s)",
639 lock_file,
640 errno,
641 strerror(errno));
642 exit (-1);
643 }
644 }
646 if (lockf (lock_fp, F_TLOCK, 0) < 0)
647 exit(-1); /* can not lock */
649 /* Record pid to lockfile */
650 sprintf (str, "%d\n", getpid());
651 write (lock_fp, str, strlen(str));
653 /* Cancel certain signals */
654 signal (SIGCHLD, SIG_DFL); /* A child process dies */
655 signal (SIGTSTP, SIG_IGN); /* Various TTY signals */
656 signal (SIGTTOU, SIG_IGN);
657 signal (SIGTTIN, SIG_IGN);
658 signal (SIGHUP, SIG_IGN); /* Ignore hangup signal */
659 signal (SIGTERM, sig_term_handler); /* catch SIGTERM */
661 /* Redirect standard files to /dev/null */
662 freopen( "/dev/null", "r", stdin);
663 freopen( "/dev/null", "w", stdout);
664 freopen( "/dev/null", "w", stderr);
666 /* Done setting up the daemon */
667 return;
668 }
670 int get_kernel_config()
671 {
672 uint32_t temp=0;
673 FILE *pDts = NULL;
675 pDts = fopen(DTS_LOG_FILE_QUEUE_ETHx[0], "rb");
677 if(pDts)
678 {
679 fread((void*)&temp, sizeof(uint32_t), 1, pDts);
680 globalDB.qNum = (int)swap32(temp);
681 fclose(pDts);
682 }
683 else
684 {
685 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
686 "main: error opening device tree file: %s\n",DTS_LOG_FILE_QUEUE_ETHx[0]);
687 return -1;
688 }
690 pDts = NULL;
691 pDts = fopen(DTS_LOG_FILE_FLOW_ETHx[0], "rb");
693 if(pDts)
694 {
695 fread((void*)&temp, sizeof(uint32_t), 1, pDts);
696 globalDB.flowId = (int)swap32(temp);
697 fclose(pDts);
698 }
699 else
700 {
701 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
702 "main: error opening device tree file: %s\n",DTS_LOG_FILE_FLOW_ETHx[0]);
703 return -1;
704 }
705 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
706 "get_kernel_config: flow: 0x%x, qNum: 0x%x\n",
707 globalDB.flowId, globalDB.qNum);
708 return 0;
709 }
711 int create_pktio_channel()
712 {
713 static int count = 0;
714 int error = 0;
715 char name[19];
716 PKTIO_HANDLE_T *pktio_channel;
717 PKTIO_CFG_T pktio_cfg;
718 NETCP_CFG_ROUTE_T route;
719 NETCP_CFG_FLOW_T flow;
720 NETCP_CFG_EXCEPTION_PKT_T expPkt_appid = 0;
722 memset(&pktio_cfg,0,sizeof(PKTIO_CFG_T));
723 memset((void *)&route, 0, sizeof (NETCP_CFG_ROUTE_T));
724 memset((void *)&flow, 0, sizeof (NETCP_CFG_FLOW_T));
726 sprintf(&name[0],"%s","offload_0");
727 pktio_cfg.qnum = globalDB.qNum;
728 pktio_cfg.flags1 = PKTIO_RX;
729 pktio_cfg.flags2 = PKTIO_GLOBAL | PKTIO_PKT;
730 pktio_cfg.max_n = 8;
732 globalDB.pktio_channel = netapi_pktioCreate(netapi_handle,
733 &name[0],
734 (PKTIO_CB)recv_cb,
735 &pktio_cfg,
736 &error);
737 if (!globalDB.pktio_channel)
738 {
739 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
740 "create_pktio_channel: failed\n");
741 return -1;
742 }
745 flow.dma_engine= 1;
746 flow.flowid = globalDB.flowId;
747 route.p_dest_q = globalDB.pktio_channel;
748 route.p_flow = &flow;
749 route.valid_params |= NETCP_CFG_VALID_PARAM_ROUTE_TYPE;
750 route.routeType = NWAL_ROUTE_RX_INTF_W_FLOW;
751 /* enable exception packet handling for fragmented packets */
752 expPkt_appid = netapi_netcpCfgExceptions(netapi_handle,
753 7,
754 NETCP_CFG_ACTION_TO_SW,
755 (NETCP_CFG_ROUTE_HANDLE_T) &route);
757 return 0;
758 }
759 /**
760 * @b Description
761 * @n
762 * Entry point for the NETAPI Proxy application.
763 *
764 * @param[in] argc
765 * Number of arguments passed to the application
766 * @param[in] argv
767 * Arguments passed to the application.
768 *
769 * @retval
770 * Success - 0
771 * @retval
772 * ERROR - >0
773 */
774 int32_t main (int argc, char* argv[])
775 {
776 int32_t retVal;
777 int i, iface;
778 char* pTok = NULL;
779 int ip_entry_count = 0;
780 struct ifaddrs *ifaddr, *ifa;
781 int family, s;
782 char host[NI_MAXHOST];
783 struct sockaddr_in6 ipv6_addr;
784 cpu_set_t cpu_set;
785 ipsecmgr_syslog_init();
787 memset(&globalDB, 0, sizeof(globalDB));
789 /* assign main net_test thread to run on core 0 */
790 CPU_ZERO( &cpu_set);
791 CPU_SET( 0, &cpu_set);
792 hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
793 /* create netapi */
794 netapi_handle = netapi_init(NETAPI_SYS_MASTER,
795 &our_netapi_default_cfg);
796 if(netapi_handle == NULL)
797 {
798 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
799 "ERROR: netapi_init failed\n");
800 return -1;
801 }
802 else
803 netapi_netcpCfgExceptions(netapi_handle,
804 NETCP_CFG_ALL_EXCEPTIONS,
805 NETCP_CFG_ACTION_DISCARD,
806 (NETCP_CFG_ROUTE_HANDLE_T) NULL);
808 if (get_kernel_config())
809 {
810 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
811 "ERROR: main: get_kernel_config() failed\n");
812 return -1;
813 }
814 else
815 {
816 /* create pktio channel */
817 if(create_pktio_channel())
818 {
819 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
820 "ERROR: main: pktio channel creation failed\n");
821 return -1;
822 }
823 }
824 /*Create the proxy daemon. */
825 printf("main: calling daemonize\n");
826 daemonize (LOCK_FILE);
828 /* Initialize and start the IPSec Mgr Snoop functionality */
829 if ((retVal = init_ipsecmgr ()) < 0)
830 {
831 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
832 "ERROR: IPSec Mgr init failed, error code %d \n",
833 retVal);
834 return -1;
835 }
836 else
837 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
838 "main: ipsecmgr daemon shutdonw complete\n");
840 }