[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 **********************************************************************/
124 extern Rm_ServiceHandle *rmClientServiceHandle;
126 static ipsecmgr_ipc_daemon_send_if_t *send_iface;
127 NETAPI_T netapi_handle;
129 ipsecMgrMcb_t globalDB;
131 static int use_rm =0;
133 /* Lock file for the daemon */
134 #define LOCK_FILE "/var/lock/ipsecmgr_daemon"
136 /* snoop task */
137 static pthread_t snoop_run_th;
139 static NETAPI_CFG_T our_netapi_default_cfg=
140 {
141 TUNE_NETAPI_PERM_MEM_SZ,
142 128, //start of packet offset for hw to place data on rx for default flow
143 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
144 TUNE_NETAPI_NUM_GLOBAL_DESC, //total we will use
145 TUNE_NETAPI_DEFAULT_NUM_BUFFERS, //#descriptors+buffers in default heap
146 64, //#descriptors w/o buffers in default heap
147 TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128, //size of buffers in default heap
148 128, //tail room
149 256, //extra room
150 0,
151 NULL
152 };
156 static int QUIT = 0;
158 /* stub functions */
159 static void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
160 PKTIO_METADATA_T meta[], int n_pkts,
161 uint64_t ts )
162 {
163 return;
164 }
166 /* byte swap routine */
167 static unsigned int swap32 (unsigned int x)
168 {
169 unsigned int y;
171 y = (((x >> 24) & 0xff) << 0) |
172 (((x >> 16) & 0xff) << 8) |
173 (((x >> 8) & 0xff) << 16) |
174 (((x >> 0) & 0xff) << 24) ;
176 return (y);
178 }
180 void cleanup_sa_sp()
181 {
182 int slot, error=0;;
183 /* delete any offloaded rx SA's and policies */
184 /* and delete any offloaded tx SA's */
185 for (slot = 0;slot < 64;slot++)
186 {
187 if(globalDB.rx_sa[slot].in_use)
188 {
189 globalDB.rx_sa[slot].in_use = 0;
190 if(globalDB.rx_sa[slot].spAppId)
191 {
192 netapi_secDelRxPolicy(netapi_handle,
193 (NETCP_CFG_IPSEC_POLICY_T) globalDB.rx_sa[slot].spAppId,
194 &error);
195 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
196 "cleanup_sa_sp: SP deleted: sp_app_id: 0x%x, slot: %d, error: %d\n",
197 globalDB.rx_sa[slot].spAppId, slot, error);
198 }
199 netapi_secDelSA(netapi_handle,
200 NETCP_CFG_NO_INTERFACE,
201 (NETCP_CFG_SA_T) globalDB.rx_sa[slot].saAppId,
202 &error);
203 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
204 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n",
205 globalDB.rx_sa[slot].saAppId, slot, error);
207 }
208 if(globalDB.tx_sa[slot].in_use)
209 {
210 globalDB.tx_sa[slot].in_use = 0;
211 netapi_secDelSA(netapi_handle,
212 NETCP_CFG_NO_INTERFACE,
213 (NETCP_CFG_SA_T) globalDB.tx_sa[slot].saAppId,
214 &error);
215 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
216 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n",
217 globalDB.tx_sa[slot].saAppId, slot, error);
218 }
219 }
220 }
223 static void* snoop_run_thread (void* arg)
224 {
225 cpu_set_t cpu_set;
226 CPU_ZERO( &cpu_set);
227 CPU_SET( 0, &cpu_set);
229 hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
230 ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
231 "snoop_run_thread: daemon entering forever event loop\n");
233 while (1)
234 {
235 /* Poll for message from user application */
236 ipsecmgr_ipc_poll();
238 /* Poll for message from Kernel */
239 ipsecmgr_snoop_run();
240 if (QUIT == 1)
241 break;
242 }
243 ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
244 "snoop_run_thread: calling shutdown\n");
245 ipsecmgr_snoop_shutdown ();
246 cleanup_sa_sp();
247 netapi_shutdown(netapi_handle);
249 if (use_rm)
250 closeRm();
251 return ((void*)NULL);
252 }
254 /**
255 * @b Description
256 * @n
257 * SIGTERM handler.
258 *
259 * @param[in] signum
260 * signal number to terminate deamon.
261 */
262 static void sig_term_handler(int signum)
263 {
264 QUIT = 1;
265 }
267 /**
268 * @b Description
269 * @n
270 * Function to implement task sleep functionality
271 * for IPSecMgr
272 *
273 * @param[in] time_in_msec
274 * Time in milliseconds to sleep
275 *
276 * @retval
277 * Not Applicable.
278 */
279 static void task_sleep(uint32_t time_in_msec)
280 {
281 pthread_mutex_t fake_mutex = PTHREAD_MUTEX_INITIALIZER;
282 pthread_cond_t fake_cond = PTHREAD_COND_INITIALIZER;
283 struct timespec ts;
284 int rt;
285 unsigned int sec, nsec;
287 sec = time_in_msec/1000;
288 nsec = (time_in_msec - (sec*1000)) * 1000000;
290 /* Use the wall-clock time */
291 clock_gettime(CLOCK_REALTIME, &ts);
293 ts.tv_sec += sec;
294 ts.tv_nsec += nsec;
296 pthread_mutex_lock(&fake_mutex);
297 rt = pthread_cond_timedwait(&fake_cond, &fake_mutex, &ts);
298 pthread_mutex_unlock(&fake_mutex);
299 }
302 /**
303 * @b Description
304 * @n
305 * NETAPI Proxy's IPSecMgr Start Offload Response
306 * message handler.
307 *
308 * This function is called by the IPSecMgr library
309 * when it has a response ready corresponding to an
310 * Start Offload SP request issued by the user application.
311 *
312 * @param[in] rsp
313 * IPSecMgr's Start Offload SP response
314 * @param[in] addr
315 * Destination address (user application) to send
316 * the response to
317 * @param[in] addr_size
318 * Size of destination address passed
319 *
320 * @retval
321 * Success - 0
322 * @retval
323 * ERROR - <0
324 */
325 static int offload_sp_rsp_send
326 (
327 ipsecmgr_snoop_offload_sp_rsp_param_t *rsp,
328 void *addr,
329 uint32_t addr_size
330 )
331 {
332 ipsecmgr_ipc_offload_sp_rsp_param_t offload_sp_rsp;
334 offload_sp_rsp.type = rsp->type;
335 offload_sp_rsp.result = rsp->result;
336 offload_sp_rsp.trans_id = rsp->trans_id;
337 offload_sp_rsp.err_code = rsp->err_code;
338 offload_sp_rsp.sp_handle = rsp->sp_handle;
339 offload_sp_rsp.sa_handle = rsp->sa_handle;
341 if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
342 ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
343 "offload_sp_rsp_send: addr size not correct\n");
344 return -1;
345 }
347 return send_iface->offload_sp_rsp(&offload_sp_rsp,
348 (ipsecmgr_ipc_addr_t *)addr);
349 }
350 static void offload_sp_req_recv
351 (
352 ipsecmgr_ipc_offload_sp_req_param_t *req,
353 ipsecmgr_ipc_addr_t *src_addr
354 )
355 {
356 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"offload_sp_req_recv called for policy id\n",
357 req->policy_id);
358 ipsecmgr_snoop_offload_sp_rsp_param_t rsp;
359 uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
360 ipsecmgr_snoop_offload_sp_req_param_t offload_sp_req;
362 offload_sp_req.trans_id = req->trans_id;
363 offload_sp_req.policy_id = req->policy_id;
364 offload_sp_req.sa_flags = req->sa_flags;
365 offload_sp_req.if_name = req->if_name;
366 offload_sp_req.dscp_cfg = req->dscp_cfg;
367 offload_sp_req.l5_selector = req->l5_selector;
368 //offload_sp_req.oseq_offset = req->oseq_offset;
370 memset(&rsp, 0, sizeof(rsp));
371 rsp.trans_id = req->trans_id;
373 if (ipsecmgr_snoop_offload_sp_req(&offload_sp_req, (void*)src_addr,
374 addr_size)) {
375 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
376 "offload_sp_req_recv: snoop_offload_sp_req failed\n");
377 rsp.result = RESULT_FAILURE;
378 rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
379 }
380 else
381 {
382 rsp.result = RESULT_SUCCESS;
383 rsp.type = RSP_TYPE_ACK;
384 }
386 if (offload_sp_rsp_send(&rsp, (void *)src_addr, addr_size))
387 {
388 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
389 "offload_sp_req_recv: failed to send ACK for offload_sp\n");
390 }
391 return;
392 }
395 /**
396 * @b Description
397 * @n
398 * NETAPI Proxy's IPSecMgr Stop Offload response message
399 * handler.
400 *
401 * This function is called by the IPSecMgr library
402 * when it has a response ready corresponding to an
403 * Stop Offload SP request issued by the user application.
404 *
405 * @param[in] rsp
406 * IPSecMgr's Stop Offload SP response
407 * @param[in] addr
408 * Destination address (user application) to send
409 * the response to
410 * @param[in] addr_size
411 * Size of destination address passed
412 *
413 * @retval
414 * Success - 0
415 * @retval
416 * ERROR - <0
417 */
418 static int stop_offload_rsp_send
419 (
420 ipsecmgr_snoop_stop_offload_rsp_param_t *rsp,
421 void *addr,
422 uint32_t addr_size
423 )
424 {
425 ipsecmgr_ipc_stop_offload_rsp_param_t stop_offload_rsp;
427 stop_offload_rsp.type = rsp->type;
428 stop_offload_rsp.result = rsp->result;
429 stop_offload_rsp.trans_id = rsp->trans_id;
431 if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
432 ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
433 "stop_offload_rsp_send: addr size not correct\n");
434 return -1;
435 }
437 return send_iface->stop_offload_rsp(&stop_offload_rsp,
438 (ipsecmgr_ipc_addr_t *)addr);
439 }
441 static void stop_offload_req_recv
442 (
443 ipsecmgr_ipc_stop_offload_req_param_t *req,
444 ipsecmgr_ipc_addr_t *src_addr
445 )
446 {
447 ipsecmgr_snoop_stop_offload_req_param_t stop_offload_req;
448 uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
449 ipsecmgr_snoop_stop_offload_rsp_param_t rsp;
451 stop_offload_req.trans_id = req->trans_id;
452 stop_offload_req.policy_id = req->policy_id;
453 stop_offload_req.no_expire_sa = req->no_expire_sa;
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;
477 }
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)
490 {
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;
578 }
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)
590 {
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 }
654 if (lockf (lock_fp, F_TLOCK, 0) < 0)
655 exit(-1); /* can not lock */
657 /* Record pid to lockfile */
658 snprintf (str, 10,"%d\n", getpid());
659 write (lock_fp, str, strlen(str));
660 close(lock_fp);
661 }
662 /* Cancel certain signals */
663 signal (SIGCHLD, SIG_DFL); /* A child process dies */
664 signal (SIGTSTP, SIG_IGN); /* Various TTY signals */
665 signal (SIGTTOU, SIG_IGN);
666 signal (SIGTTIN, SIG_IGN);
667 signal (SIGHUP, SIG_IGN); /* Ignore hangup signal */
668 signal (SIGTERM, sig_term_handler); /* catch SIGTERM */
670 /* Redirect standard files to /dev/null */
671 freopen( "/dev/null", "r", stdin);
672 freopen( "/dev/null", "w", stdout);
673 freopen( "/dev/null", "w", stderr);
675 /* Done setting up the daemon */
676 return;
677 }
679 int get_kernel_config()
680 {
681 uint32_t temp=0;
682 FILE *pDts = NULL;
684 pDts = fopen(DTS_LOG_FILE_QUEUE_ETHx[0], "rb");
686 if(pDts)
687 {
688 if(fread((void*)&temp, sizeof(uint32_t), 1, pDts))
689 {
690 globalDB.qNum = (int)swap32(temp);
691 }
692 fclose(pDts);
693 }
694 else
695 {
696 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
697 "main: error opening device tree file: %s\n",DTS_LOG_FILE_QUEUE_ETHx[0]);
698 return -1;
699 }
701 pDts = NULL;
702 pDts = fopen(DTS_LOG_FILE_FLOW_ETHx[0], "rb");
704 if(pDts)
705 {
706 if (fread((void*)&temp, sizeof(uint32_t), 1, pDts))
707 {
708 globalDB.flowId = (int)swap32(temp);
709 }
710 fclose(pDts);
711 }
712 else
713 {
714 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
715 "main: error opening device tree file: %s\n",DTS_LOG_FILE_FLOW_ETHx[0]);
716 return -1;
717 }
718 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
719 "get_kernel_config: flow: 0x%x, qNum: 0x%x\n",
720 globalDB.flowId, globalDB.qNum);
721 return 0;
722 }
724 int create_pktio_channel()
725 {
726 static int count = 0;
727 int error = 0;
728 char name[19];
729 PKTIO_HANDLE_T *pktio_channel;
730 PKTIO_CFG_T pktio_cfg;
731 NETCP_CFG_ROUTE_T route;
732 NETCP_CFG_FLOW_T flow;
733 NETCP_CFG_EXCEPTION_PKT_T expPkt_appid = 0;
735 memset(&pktio_cfg,0,sizeof(PKTIO_CFG_T));
736 memset((void *)&route, 0, sizeof (NETCP_CFG_ROUTE_T));
737 memset((void *)&flow, 0, sizeof (NETCP_CFG_FLOW_T));
739 snprintf(&name[0],PKTIO_MAX_NAME, "%s","offload_0");
740 pktio_cfg.qnum = globalDB.qNum;
741 pktio_cfg.flags1 = PKTIO_RX;
742 pktio_cfg.flags2 = PKTIO_GLOBAL | PKTIO_PKT;
743 pktio_cfg.max_n = 8;
744 pktio_cfg.queueType = Qmss_QueueType_GIC400_QUEUE;
746 globalDB.pktio_channel = netapi_pktioCreate(netapi_handle,
747 &name[0],
748 (PKTIO_CB)recv_cb,
749 &pktio_cfg,
750 &error);
751 if (!globalDB.pktio_channel)
752 {
753 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
754 "create_pktio_channel: failed\n");
755 return -1;
756 }
759 flow.dma_engine= 1;
760 flow.flowid = globalDB.flowId;
761 route.p_dest_q = globalDB.pktio_channel;
762 route.p_flow = &flow;
763 route.valid_params |= NETCP_CFG_VALID_PARAM_ROUTE_TYPE;
764 route.routeType = NWAL_ROUTE_RX_INTF_W_FLOW;
765 /* enable exception packet handling for fragmented packets */
766 expPkt_appid = netapi_netcpCfgExceptions(netapi_handle,
767 7,
768 NETCP_CFG_ACTION_TO_SW,
769 (NETCP_CFG_ROUTE_HANDLE_T) &route);
771 return 0;
772 }
773 /**
774 * @b Description
775 * @n
776 * Entry point for the NETAPI Proxy application.
777 *
778 * @param[in] argc
779 * Number of arguments passed to the application
780 * @param[in] argv
781 * Arguments passed to the application.
782 *
783 * @retval
784 * Success - 0
785 * @retval
786 * ERROR - >0
787 */
788 int32_t main (int argc, char* argv[])
789 {
790 int32_t retVal;
791 int i, iface;
792 char* pTok = NULL;
793 int ip_entry_count = 0;
794 struct ifaddrs *ifaddr, *ifa;
795 int family, s;
796 char host[NI_MAXHOST];
797 struct sockaddr_in6 ipv6_addr;
798 cpu_set_t cpu_set;
799 int c;
800 static char usage[] = "usage: %s -r < use Resource manager: no/yes> -s <outbound sequence number> -f <SA transmit flow Id>\n";
802 ipsecmgr_syslog_init();
805 memset(&globalDB, 0, sizeof(globalDB));
806 globalDB.sa_tx_flow = -1;
807 int temp;
808 while ((c = getopt (argc, argv, "s:f:r:")) != -1)
809 {
810 switch (c)
811 {
812 case 'r':
813 if(strncmp("yes", optarg,1) == 0)
814 {
815 use_rm = 1;
816 }
817 break;
819 case 's':
820 /* check is user input 0 for oseq_offset (valid but also default)*/
821 if(strncmp("0", optarg,1) == 0)
822 {
823 globalDB.oseq_offset = 0;
824 }
825 else
826 {
827 globalDB.oseq_offset = (uint32_t)strtol(optarg, NULL,0);
828 if(!globalDB.oseq_offset)
829 {
830 printf(usage, argv[0]);
831 exit(EXIT_FAILURE);
832 }
833 }
834 break;
835 case 'f':
836 /* check is user input 0 for sa_tx_flow(valid) */
837 if(strncmp("0", optarg,1) == 0)
838 {
839 globalDB.sa_tx_flow= 0;
840 }
841 else
842 {
843 globalDB.sa_tx_flow = (uint32_t)strtol(optarg, NULL,0);
844 if(!globalDB.sa_tx_flow)
845 {
846 printf(usage, argv[0]);
847 exit(EXIT_FAILURE);
848 }
849 }
850 break;
851 case '?':
852 printf(usage, argv[0]);
853 exit(EXIT_FAILURE);
854 default:
855 break;
856 }
857 }
858 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
859 "main: oseq_offset: %d, sa_tx_flow: %d\n",
860 globalDB.oseq_offset, globalDB.sa_tx_flow);
862 if (use_rm)
863 {
864 if (initRm())
865 {
866 exit(EXIT_FAILURE);
867 }
868 }
870 /* assign main net_test thread to run on core 0 */
871 CPU_ZERO( &cpu_set);
872 CPU_SET( 0, &cpu_set);
873 hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
874 /* create netapi */
875 our_netapi_default_cfg.rmHandle = rmClientServiceHandle;
876 netapi_handle = netapi_init(NETAPI_SYS_MASTER,
877 &our_netapi_default_cfg);
878 if(netapi_handle == NULL)
879 {
880 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
881 "ERROR: netapi_init failed\n");
882 return -1;
883 }
884 else
885 netapi_netcpCfgExceptions(netapi_handle,
886 NETCP_CFG_ALL_EXCEPTIONS,
887 NETCP_CFG_ACTION_DISCARD,
888 (NETCP_CFG_ROUTE_HANDLE_T) NULL);
890 if (get_kernel_config())
891 {
892 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
893 "ERROR: main: get_kernel_config() failed\n");
894 return -1;
895 }
896 else
897 {
898 /* create pktio channel */
899 if(create_pktio_channel())
900 {
901 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
902 "ERROR: main: pktio channel creation failed\n");
903 return -1;
904 }
905 }
906 /*Create the proxy daemon. */
907 ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO, "main: calling daemonize\n");
908 daemonize (LOCK_FILE);
910 /* Initialize and start the IPSec Mgr Snoop functionality */
911 if ((retVal = init_ipsecmgr ()) < 0)
912 {
913 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
914 "ERROR: IPSec Mgr init failed, error code %d \n",
915 retVal);
916 return -1;
917 }
918 else
919 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
920 "main: ipsecmgr daemon shutdonw complete\n");
922 exit(EXIT_SUCCESS);
924 }