437de2ab82536bc779080ce55598e9d5d57ca785
[keystone-rtos/netapi.git] / ti / runtime / netapi / src / netapi_sec.c
1 /**************************************************************
2  * FILE PURPOSE :  NETAPI SECURITY CONFIGURATION-
3  *         user space access to security transport resources on SOC
4  **************************************************************
5  * @file netapi_sec.c
6  * 
7  * @brief DESCRIPTION:  netapi security cfg file for user space transport
8  *               library
9  * 
10  * REVISION HISTORY:
11  *
12  *  Copyright (c) Texas Instruments Incorporated 2013
13  * 
14  *  Redistribution and use in source and binary forms, with or without 
15  *  modification, are permitted provided that the following conditions 
16  *  are met:
17  *
18  *    Redistributions of source code must retain the above copyright 
19  *    notice, this list of conditions and the following disclaimer.
20  *
21  *    Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the 
23  *    documentation and/or other materials provided with the   
24  *    distribution.
25  *
26  *    Neither the name of Texas Instruments Incorporated nor the names of
27  *    its contributors may be used to endorse or promote products derived
28  *    from this software without specific prior written permission.
29  *
30  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
31  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
32  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
34  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
35  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
36  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
39  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
40  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 *****************************************************************************/
43 #include "netapi_sec.h"
45 /********************************************************************
46  * FUNCTION PURPOSE:  API to add an IPSEC SA
47  ********************************************************************
48  * DESCRIPTION:  API to add an IPSEC SA
49  ********************************************************************/
50 NETCP_CFG_SA_T netapi_secAddSA(NETAPI_T h,
51                                int iface_no,
52                                NETAPI_SEC_SA_INFO_T *sa_info,
53                                nwalSecKeyParams_t * key_params,
54                                int inflow_mode,
55                                NETCP_CFG_ROUTE_HANDLE_T  route,
56                                void **p_data_mode_handle,
57                                void **p_inflow_mode_handle,
58                                void * p_user_data,
59                                int * perr)
60 {
61     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
62     nwal_RetValue       retValue;
63     NetapiNwalTransInfo_t *pTransInfo;
64     nwal_TransID_t     trans_id;
65     unsigned int appId = NETAPI_NETCP_MATCH_IPSEC | iface_no;
66     int tunnelId;
67     nwalSaIpSecId_t  saInfo;
68     int have_to_wait=1;
69     nwalTxDmPSCmdInfo_t     dmPSCmdInfo;
70     nwalSaIpSecId_t nwalSaIpSecId;
71     uint32_t    swInfo0;
72     uint32_t    swInfo1;
74     nwalCreateSAParams_t    createParam =
75     {
76         /* mac handle */
77         NULL,  //to be filled in
78         4,
79         /*nwalSaIpSecParam_t */
80             {
81                 0,/* validParams */
82                 nwal_SA_MODE_TUNNEL,  //update from input
83                 64,/* replayWindow */\
84                 NWAL_SA_DIR_INBOUND,
85                 0,
86                 0,
87                 NWAL_SA_AALG_HMAC_SHA1,/* update from input */
88                 NWAL_SA_EALG_AES_CTR,  /* update from input */
89                 { 0x00},      /* remMacAddr:  NA */
90                 12,             /* update from input, mac size */
91                 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,/* Continue parsing to next route for match */
92                 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,/* For next route fail action by default is route to host */
93                 CPPI_PARAM_NOT_SPECIFIED,         /* Use default flow configured to NWAL  if packet is routed to host */
94                 QMSS_PARAM_NOT_SPECIFIED          /* Use default queue configured to NWAL if packet is routed to host */
95            },
96            /* nwalSaIpSecKeyParams_t */
97            {0}
98     };
101     void * mac_handle = netapip_netcpCfgGetMacHandle(&netapi_get_global()->nwal_context,iface_no);
102     *perr =NETAPI_ERR_OK;
103     if ((!n) || (!sa_info)  ||  (!p_data_mode_handle))
104     {
105         *perr = NETAPI_ERR_BAD_INPUT;
106         return -1;
107     }
109     /* reserve a slot */
110     tunnelId = netapip_netcpCfgFindSaSlot(&netapi_get_global()->nwal_context,
111                            iface_no);
113     if (tunnelId <0)
114     {
115         *perr= NETAPI_ERR_NOMEM;
116         return -1;
117     }
118     appId |=  (tunnelId << NETAPI_NETCP_MATCH_ID_SHIFT);
119     netapi_Log("netapi_secAddSA: app id: 0x%x\n", appId);
121     *p_data_mode_handle= NULL;  
122     *p_inflow_mode_handle= NULL;
126     if (inflow_mode & NETAPI_SEC_SA_INFLOW)
127     {
128         pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
129         if (!pTransInfo)
130         {
131             *perr =  NETAPI_ERR_BUSY;
132             netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
133             return -1;
134         }
135         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
136         pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
137         pTransInfo->inUse = nwal_TRUE;
138         pTransInfo->netapi_handle = h;
140         /* build SA parameters */
141         saInfo.spi = sa_info->spi;
142         memcpy(&saInfo.dst, &sa_info->dst, sizeof( nwalIpAddr_t));
143         memcpy(&saInfo.src, &sa_info->src, sizeof( nwalIpAddr_t));
144         saInfo.proto = sa_info->proto;
145         createParam.macHandle = mac_handle;
146         createParam.ipType = sa_info->ipType;
147         createParam.saIpSecParam.dir = sa_info->dir;
148         createParam.saIpSecParam.saMode = sa_info->saMode;
149         createParam.saIpSecParam.replayWindow = sa_info->replayWindow;
150         createParam.saIpSecParam.authMode = sa_info->authMode;
151         createParam.saIpSecParam.cipherMode = sa_info->cipherMode;
152         createParam.saIpSecParam.esnLo = sa_info->esnLo;
153         createParam.saIpSecParam.esnHi = sa_info->esnHi;
154         if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
155             (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
156             (sa_info->authMode == NWAL_SA_AALG_GMAC)      ||
157             (sa_info->authMode == NWAL_SA_AALG_HMAC_SHA2_256_RFC4868))
158         {
159             createParam.saIpSecParam.macSize = 16;
160         }
161         if  ((sa_info->authMode == NWAL_SA_AALG_NULL) && 
162             (!((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) || 
163                (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM))))
164         {
165             createParam.saIpSecParam.replayWindow = 0;
166             createParam.saIpSecParam.macSize = 0;
167         }
168         memcpy(&createParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
170         if (route != NULL)
171         {
172             netapip_netcpCfgBuildRoute(route,&createParam.saIpSecParam.appRxPktFlowId, 
173                                          &createParam.saIpSecParam.appRxPktQueue);
174         }
176         /* fire off config message */
177         retValue = nwal_setSecAssoc (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
178                                         trans_id,
179                                         (nwal_AppId) appId,
180                                         &saInfo,
181                                         &createParam,
182                                         &pTransInfo->handle);
183         if(retValue == nwal_TRANS_COMPLETE)
184         {
185             have_to_wait=0;
186         }
187         else if(retValue !=  nwal_OK)
188         {
189             *perr = NETAPI_ERR_NWAL_ERR0;
190             netapip_freeTransInfo(pTransInfo);
191             netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
192             return -1;
193         }
195         if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
196         {
197             n->nwal_local.numPendingCfg++;
198             while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
199                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
200             {
201                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
202             }
203             if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
204             {
205                 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
206                 pTransInfo->inUse = nwal_FALSE;
207                 *perr = NETAPI_ERR_PA_FW;
208                 netapi_Log ("netapi_sec - ERROR returned by NETCP PA firmware %d\n",
209                         *perr);
210                 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
211                 return -1;
212             }
213         }
215         *p_inflow_mode_handle=pTransInfo->handle;
216         netapip_freeTransInfo(pTransInfo);
218         if (sa_info->dir == NWAL_SA_DIR_OUTBOUND)
219         {
220             memset(&nwalSaIpSecId, 0, sizeof(nwalSaIpSecId_t));
221             nwalSaIpSecId.spi = sa_info->spi;
222             memcpy(&(nwalSaIpSecId.src), &sa_info->src,sizeof( nwalIpAddr_t));
223             memcpy(&(nwalSaIpSecId.dst), &sa_info->dst,sizeof( nwalIpAddr_t));
224             nwalSaIpSecId.proto = sa_info->proto;
225             if (nwal_getSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
226                                      &nwalSaIpSecId, 
227                                      NWAL_SA_DIR_OUTBOUND,
228                                      p_inflow_mode_handle,
229                                      &swInfo0,
230                                      &swInfo1) == nwal_TRUE)
231             {
232                 //netapi_Log("netapisecAddSA swInfo0: 0x%x, swInfo1: 0x%x\n", swInfo0, swInfo1);
233             }
234             else
235                 netapi_Log("netapisecAddSA: call to nwal_getSecAssoc() returned error\n");
236         }
237     }
239     /* sideband mode */
240     if (inflow_mode &NETAPI_SEC_SA_SIDEBAND)
241     {
242         nwalCreateDmSAParams_t  dmSaParam;
243         void * dm_handle;
244         memset(&dmSaParam,0,sizeof(nwalCreateDmSAParams_t));
245         dmSaParam.dmSaParam.dmChnType= (sa_info->dir==NWAL_SA_DIR_INBOUND)?  NWAL_DM_CHAN_DECRYPT: NWAL_DM_CHAN_ENCRYPT; /**direction*/ 
246         dmSaParam.dmSaParam.replayWindow=sa_info->replayWindow;
247         dmSaParam.dmSaParam.authMode=sa_info->authMode;
248         dmSaParam.dmSaParam.cipherMode=sa_info->cipherMode;
249         dmSaParam.dmSaParam.macSize=12;
250         dmSaParam.dmSaParam.aadSize=0;
251         dmSaParam.dmSaParam.enc1st =  (sa_info->dir ==NWAL_SA_DIR_OUTBOUND) ? nwal_TRUE : nwal_FALSE;  //encypt 1st for outbound
252         if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
253             (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
254             (sa_info->authMode == NWAL_SA_AALG_GMAC))
255         {
256             dmSaParam.dmSaParam.macSize = 16;
257             dmSaParam.dmSaParam.aadSize=8;
258             /* Enc1st needs to always be true for combined mode algorithms */
259             dmSaParam.dmSaParam.enc1st = nwal_TRUE;
260         }
261        else
262         {
263             dmSaParam.dmSaParam.macSize=12;
264             dmSaParam.dmSaParam.aadSize=0;
265         }
267        if  (sa_info->authMode == NWAL_SA_AALG_NULL)
268        {
269             dmSaParam.dmSaParam.enc1st = nwal_TRUE;
270        }
271         /* todo; allow app q for Sideband return */
272         memcpy(&dmSaParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
273         retValue = nwal_setDMSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
274                                   (nwal_AppId)appId,
275                                   &dmSaParam,
276                                   &dm_handle);
277         if(retValue != nwal_OK)
278         {
279             *perr = NETAPI_ERR_NWAL_ERR0;
280             netapi_Log ("netapi_secAddSA: nwal_setDMSecAssoc() returned Error Code %d\n",
281             retValue);
282             netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
283             return -1;
284         }
286         //netapi_Log("netapi_secAddSA: Creating sideband mode SA for %d ( mac %d)\n", tunnelId, iface_no); 
287         *p_data_mode_handle = dm_handle;
288         memset(&dmPSCmdInfo, 0, sizeof(nwalTxDmPSCmdInfo_t));
289         retValue =  nwal_initDMPSCmdInfo(netapip_returnNwalInstanceHandle(h),
290                                          *p_data_mode_handle,
291                                          &dmPSCmdInfo); 
292     }
294     netapip_netcpCfgInsertSa(&netapi_get_global()->nwal_context,
295                           tunnelId,
296                           (sa_info->dir ==   NWAL_SA_DIR_INBOUND) ? TRUE: FALSE,
297                           inflow_mode,
298                           &saInfo, &createParam,
299                           *p_inflow_mode_handle,
300                           *p_data_mode_handle,
301                           &dmPSCmdInfo,
302                           swInfo0,
303                           swInfo1,
304                           p_user_data);
305     return  (appId);
308 /********************************************************************
309  * FUNCTION PURPOSE:  Internal function  to dynamically switch between inflow
310  *                                  and sideband mode
311  ********************************************************************
312  * DESCRIPTION:  Internal function  to dynamically switch between inflow
313  *                                  and sideband mode
314  ********************************************************************/
315 void netapi_secInflowMode(int iface,
316                           NETCP_CFG_SA_T sa,
317                           int on)
319     /* NOT_IMPLEMENTED */
320     netapi_Log("netapi_secInflowMode:  dynamic switch between inflow and sideband is NOT_IMPLEMENTED\n");
323 /********************************************************************
324  * FUNCTION PURPOSE:  Internal function  to delete an IPSEC SA
325  ********************************************************************
326  * DESCRIPTION:  Internal function to delete an IPSEC SA
327  ********************************************************************/
328 static void netapi_secDelSA_internal(NETAPI_T h,
329                                      int iface_no,
330                                      NETCP_CFG_SA_T sa_app_id,
331                                      int flags,
332                                      int *perr)
334     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
335     nwal_RetValue       retValue;
336     NetapiNwalTransInfo_t *pTransInfo;
337     nwal_TransID_t     trans_id;
338     int tunnelId = (sa_app_id >> NETAPI_NETCP_MATCH_ID_SHIFT) &NETAPI_NETCP_MATCH_ID_MASK;
339     void * handle_inflow;
340     void * handle_sideband;
341     int have_to_wait = 1;
343     handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
344                                           tunnelId, &handle_sideband);
345     *perr =0;
347     if(handle_inflow)
348     {
349     /* get a transaction id */
350         pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
351         if (!pTransInfo)
352         {
353             *perr =  NETAPI_ERR_BUSY;
354             return;
355         }
356         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
357         pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
358         pTransInfo->inUse = nwal_TRUE;
359         pTransInfo->netapi_handle = h;
361         retValue = nwal_delSecAssoc(
362                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
363                 trans_id,
364                 handle_inflow);
365         if(retValue == nwal_TRANS_COMPLETE)
366         {
367            have_to_wait=0;
368         }
369         else if(retValue !=  nwal_OK)
370         {
371                 *perr = NETAPI_ERR_NWAL_ERR0;
372                 netapi_Log ("netcp_cfg - ERROR: netapi_secDelSA_internal returned Error Code %d\n",
373                             retValue);
374                 netapip_freeTransInfo(pTransInfo);
375                 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
376         }
377         if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
378         {
379             n->nwal_local.numPendingCfg++;
381             while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
382                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
383             {
384                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
385             }
386             if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
387             {
388                 netapip_freeTransInfo(pTransInfo);
389                 *perr = NETAPI_ERR_PA_FW;
390                  if (!flags) 
391                     netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context, tunnelId);
392                 netapi_Log ("netapi_sec - ERROR returned by NETCP PA firmware %d\n",
393                         *perr);
394                 return;
395            }
396         }
397         netapi_Log ("netapi sec: inflow tunnel %d (iface %d) deleted\n",tunnelId,iface_no);
398         netapip_freeTransInfo(pTransInfo);
399     }
400     if (handle_sideband)
401     {
402         retValue=nwal_delDMSecAssoc( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
403                                     handle_sideband);
404         if(retValue !=  nwal_OK)
405         {
406             *perr = NETAPI_ERR_NWAL_ERR0;
407              netapi_Log ("netapi_sec  - ERROR: nwal_delDMSA returned Error Code %d\n",
408                     retValue);
410         }
411         else 
412             netapi_Log("netapi_sec: Sideband SA deleted\n");
413     }
414    
415     /* zap the entry */
416     if (!flags)
417         netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context, tunnelId);
420 /********************************************************************
421  * FUNCTION PURPOSE:  API to delete an IPSEC SA
422  ********************************************************************
423  * DESCRIPTION:  API to delete an IPSEC SA
424  ********************************************************************/
425 void netapi_secDelSA(NETAPI_T h,
426                      int iface_no,
427                      NETCP_CFG_SA_T sa_app_id,
428                      int *perr)
430     netapi_secDelSA_internal( h, iface_no,  sa_app_id, 0x00, perr);
434 /********************************************************************
435  * FUNCTION PURPOSE:  API to add a receive security policy
436  ********************************************************************
437  * DESCRIPTION:  API to add a receive security policy
438  ********************************************************************/
439 NETCP_CFG_IPSEC_POLICY_T netapi_secAddRxPolicy(NETAPI_T h, 
440                                                NETCP_CFG_SA_T sa,
441                                                nwal_IpType ipType,
442                                                nwalIpAddr_t * src_ip_addr,
443                                                nwalIpAddr_t * dst_ip_addr,
444                                                nwalIpOpt_t * ip_qualifiers,
445                                                NETCP_CFG_ROUTE_HANDLE_T  route,
446                                                void * user_data,
447                                                int * perr)
449     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
450     nwal_RetValue       retValue;
451     NetapiNwalTransInfo_t *pTransInfo;
452     nwal_TransID_t     trans_id;
453     unsigned int appId = NETAPI_NETCP_MATCH_IPSEC_POLICY;
454     int policyId;
455     int tunnelId= netapi_cfgGetMatchId(sa);
456     void * blah;
457     int iface_no = netapi_cfgGetMatchLogicalMacIface(sa);
459     nwalSecPolParams_t createParam =
460     {
461         0,  /* handle */
462         NWAL_SA_DIR_INBOUND,
463         4,      /* IP Type */
464         {0},  /* dst */
465         {0},  /* src */
466         {0 },/* IP Options */
467         NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
468         NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
469         CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
470         QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
471     };
473     void * sa_handle = NULL;
474     *perr =0;
475     
476     if ((!n) )
477     {
478         *perr = NETAPI_ERR_BAD_INPUT;
479         return -1;
480     }
482     sa_handle = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,tunnelId,&blah);
483     if (!sa_handle)
484     {
485         *perr = NETAPI_ERR_BAD_INPUT;
486         return -1;
487     }
489     /* get a transaction id */
490     pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
491     if (!pTransInfo)
492     {
493         *perr =  NETAPI_ERR_BUSY;
494         return -1;
495     }
496     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
497     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
498     pTransInfo->inUse = nwal_TRUE;
499     pTransInfo->netapi_handle = h;
500     createParam.handle = sa_handle;
501     createParam.ipType = ipType;
502     if (dst_ip_addr) memcpy(&createParam.dst, dst_ip_addr, sizeof(nwalIpAddr_t)); 
503     if (src_ip_addr) memcpy(&createParam.src, src_ip_addr, sizeof(nwalIpAddr_t)); 
504     if (ip_qualifiers) memcpy(&createParam.ipOpt,ip_qualifiers ,sizeof(nwalIpOpt_t));
505     if (route != NULL)
506     {
507         netapip_netcpCfgBuildRoute(route,&createParam.appRxPktFlowId,
508                                      &createParam.appRxPktQueue);
509     }
510     /* reserve a slot */
511     policyId = netapip_netcpCfgFindPolicySlot(&netapi_get_global()->nwal_context,
512                            tunnelId);
513     if (policyId <0) 
514     {
515         *perr= NETAPI_ERR_NOMEM;
516         netapip_freeTransInfo(pTransInfo);
517         return -1;
518     }
519     appId |=  (policyId <<8);
521     /* fire off config message */
522     retValue = nwal_setSecPolicy (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
523                                   trans_id,
524                                   (nwal_AppId) appId,
525                                   &createParam,
526                                   &pTransInfo->handle);
527     if(retValue !=  nwal_OK)
528     {
529         *perr = NETAPI_ERR_NWAL_ERR0;
530         printf("netapi_secAddPolicy: error returned: %d\n", retValue);
531         netapi_Log ("netapi sec - ERROR: nwal_setPolicy returned Error Code %d\n",
532                     retValue);
533         netapip_freeTransInfo(pTransInfo);
534         
535         netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context,policyId);
536         return -1;
537     }
539     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
540     {
541         n->nwal_local.numPendingCfg++;
542         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
543                 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
544         {
545             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
546         }
547         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
548         {
549             netapip_freeTransInfo(pTransInfo);
550             *perr = NETAPI_ERR_PA_FW;
551             netapi_Log ("netapi_sec - ERROR2: netapi_secAddRxPolicy returned Error Code %d\n",
552                     *perr);
553             netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context,policyId);
554             return -1;
555         }
556     }
557     netapi_Log ("netapi sec: SA %d added to tunnel %d  mac %d\n", policyId, tunnelId, iface_no);
559     /* save stuff */
560     netapip_netcpCfgInsertPolicy(&netapi_get_global()->nwal_context,
561                            policyId,
562                           (void *) pTransInfo->handle,
563                           user_data);
564     netapip_freeTransInfo(pTransInfo);
565     return  (appId);
568 /********************************************************************
569  * FUNCTION PURPOSE:  Internal function to delete a receive security policy
570  ********************************************************************
571  * DESCRIPTION:  Internal function to delete a receive security policy
572  ********************************************************************/
573 static void netapi_secDelRxPolicy_internal(NETAPI_T h,
574                                            NETCP_CFG_IPSEC_POLICY_T policy_app_id,
575                                            int flags,
576                                            int *perr)
578     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
579     nwal_RetValue       retValue;
580     NetapiNwalTransInfo_t *pTransInfo;
581     nwal_TransID_t     trans_id;
582     int policyId = netapi_cfgGetMatchId(policy_app_id);
583     void * handle_policy=NULL;
585     handle_policy = netapip_netcpCfgGetPolicy(&netapi_get_global()->nwal_context,policyId);
586                                           ;
587     if (!handle_policy)
588     {
589         *perr = NETAPI_ERR_BAD_INPUT;
590         goto ERR_netapi_secDelRxPolicy_internal;
591      }
592     *perr =0;
594     /* get a transaction id */
595     pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
596     if (!pTransInfo)
597     {
598         *perr =  NETAPI_ERR_BUSY;
599         goto ERR_netapi_secDelRxPolicy_internal;
600     }
601     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
602     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
603     pTransInfo->inUse = nwal_TRUE;
604     pTransInfo->netapi_handle = h;
606     /* issue request */
607     retValue = nwal_delSecPolicy(
608                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
609                 trans_id,
610                 handle_policy);
611     if(retValue !=  nwal_OK)
612     {
613         *perr = NETAPI_ERR_NWAL_ERR0;
614         netapi_Log ("netapi sec - ERROR: netapi_secDelRxPolicy_internal returned Error Code %d\n",
615                     retValue);
616         netapip_freeTransInfo(pTransInfo);
617         goto ERR_netapi_secDelRxPolicy_internal;
618     }
620     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
621     {
622         n->nwal_local.numPendingCfg++;
623         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
624                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
625         {
626             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
627         }
628         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
629         {
630             netapip_freeTransInfo(pTransInfo);
631             *perr = NETAPI_ERR_PA_FW;
632             netapi_Log ("netapi_sec - ERROR2: netapi_secDelRxPolicy_internal returned Error Code %d\n",
633                     *perr);
634             //zap the entry
635             if (!flags)
636                 netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context, policyId);
637             goto ERR_netapi_secDelRxPolicy_internal;
638             
639         }
640     }
641     netapi_Log ("netapi sec: policy %d (iface %d) deleted\n",policyId,(policy_app_id&0xff));
642     netapip_freeTransInfo(pTransInfo);
643     /* zap the entry */
644     if (!flags)
645     {
646         netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context, policyId);
647     }
648 ERR_netapi_secDelRxPolicy_internal:
649     return;
652 /********************************************************************
653  * FUNCTION PURPOSE:  API to delete a receive security policy
654  ********************************************************************
655  * DESCRIPTION:  API to delete a receive security policy
656  ********************************************************************/
657 void netapi_secDelRxPolicy(NETAPI_T h,
658                            NETCP_CFG_IPSEC_POLICY_T policy_app_id,
659                            int *perr)
661     netapi_secDelRxPolicy_internal(h,  policy_app_id, 0, perr);
664 /********************************************************************
665  * FUNCTION PURPOSE:  API to retrieve SA statistics via NWAL
666  ********************************************************************
667  * DESCRIPTION:  API to retrieve SA statistics via NWAL
668  ********************************************************************/
669 void  netapi_getSaStats (NETAPI_T               h, 
670                          NETCP_CFG_SA_T         handle,
671                          NETAPI_SA_STATS_T*     pSaStats)
673     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
674     void * handle_inflow;
675     void * handle_sideband;
676     int tunnelId = (handle >> NETAPI_NETCP_MATCH_ID_SHIFT) &0xffff;
677     int have_to_wait = 1;
678     handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
679                                           tunnelId, &handle_sideband);
680     if(handle_inflow)
681     {
682         nwal_getSecAssocStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, 
683                                                 handle_inflow, &(pSaStats->saIpsecStats));
684         pSaStats->validParams |= NETAPI_IPSEC_STAT_VALID;
685     }
686     if(handle_sideband)
687     {
688         nwal_getDataModeStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, 
689                                                 handle_sideband, &(pSaStats->dataModeStats));
690         pSaStats->validParams |= NETAPI_SIDEBAND_DATA_MODE_STAT_VALID;
691     }
695 /**********************************************************************************
696  * FUNCTION PURPOSE:  API to  retrieve SA and PA channel handles for security context if already configured
697  **********************************************************************************
698  * DESCRIPTION:  API to retrieve SA and PA channel handles for security context if already configured
699  *********************************************************************************/
700 void netapi_secGetChanHandles(NETAPI_T h,
701                            NETCP_CFG_SA_T sa_app_id,
702                            NETCP_CFG_IPSEC_POLICY_T policy_app_id,
703                            NETCP_CFG_PA_HANDLE_T* pPaHandleOuterIP,
704                            NETCP_CFG_PA_HANDLE_T* pPaHandleInnerIP,
705                            NETCP_CFG_SA_HANDLE_T* pSaHandle)
707     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
708     void * handle_inflow;
709     void * handle_sideband = NULL;
710     void * handle_policy=NULL;
712     int tunnelId = netapi_cfgGetMatchId(sa_app_id);
713     int policyId = netapi_cfgGetMatchId(policy_app_id);
715     handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
716                                           tunnelId, &handle_sideband);
718     if(handle_inflow)
719     {
720         handle_policy = netapip_netcpCfgGetPolicy(&netapi_get_global()->nwal_context,policyId);
722         nwal_secGetChanHandles(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
723                                  handle_inflow,
724                                  handle_policy,
725                                  pPaHandleOuterIP,
726                                  pPaHandleInnerIP,
727                                  pSaHandle);
728         if (pPaHandleOuterIP)
729             printf("netapi_secGetChanHandles: *pa_handle outer IP: 0x%x\n", 
730             (paHandleL2L3_t)*pPaHandleOuterIP);
732         if (pPaHandleInnerIP)
733             printf("netapi_secGetChanHandles: *pa_handle inner IP: 0x%x\n", 
734             (paHandleL2L3_t)*pPaHandleInnerIP);
736         if (pSaHandle)
737             printf("netapi_secGetChanHandles: *sa_handle: 0x%x\n", 
738             (Sa_ChanHandle)*pSaHandle);
739     }
740     else
741     {
742         if (pPaHandleOuterIP)
743             *pPaHandleOuterIP = NULL;
744         if (pPaHandleInnerIP)
745             *pPaHandleInnerIP = NULL;
746         if (pSaHandle)
747             *pSaHandle = NULL;
748     }
749     return;