]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/netapi.git/blob - ti/runtime/netapi/src/netapi_sec.c
This commit adds the following:
[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"
46 /********************************************************************
47  * FUNCTION PURPOSE:  API to add an IPSEC SA
48  ********************************************************************
49  * DESCRIPTION:  API to add an IPSEC SA
50  ********************************************************************/
51 NETCP_CFG_SA_T netapi_secAddSA(NETAPI_T h,
52                                int iface_no,
53                                NETAPI_SEC_SA_INFO_T *sa_info,
54                                nwalSecKeyParams_t * key_params,
55                                int inflow_mode,
56                                NETCP_CFG_ROUTE_HANDLE_T  route,
57                                void **p_data_mode_handle,
58                                void **p_inflow_mode_handle,
59                                void * p_user_data,
60                                int * perr)
61 {
62     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
63     nwal_RetValue       retValue;
64     NetapiNwalTransInfo_t *pTransInfo;
65     nwal_TransID_t     trans_id;
66     unsigned int appId = NETAPI_NETCP_MATCH_IPSEC | iface_no;
67     int tunnelId;
68     nwalSaIpSecId_t  saInfo;
69     int have_to_wait=1;
70     nwalTxDmPSCmdInfo_t     dmPSCmdInfo;
71     nwalSaIpSecId_t nwalSaIpSecId;
72     uint32_t    swInfo0;
73     uint32_t    swInfo1;
75     nwalCreateSAParams_t    createParam;
77     void * mac_handle = netapip_netcpCfgGetMacHandle(&netapi_get_global()->nwal_context,iface_no);
78     *perr =0;
79     if ((!n) || (!sa_info)  ||  (!p_data_mode_handle))
80     {
81         *perr = NETAPI_ERR_BAD_INPUT;
82         return -1;
83     }
85     /* reserve a slot */
86     tunnelId = netapip_netcpCfgFindSaSlot(&netapi_get_global()->nwal_context,
87                            iface_no);
89     if (tunnelId <0)
90     {
91         *perr= NETAPI_ERR_NOMEM;
92         return -1;
93     }
94     appId |=  (tunnelId << NETAPI_NETCP_MATCH_ID_SHIFT);
95     netapi_Log("netapi_secAddSA: app id: 0x%x\n", appId);
97     *p_data_mode_handle= NULL;  
98     *p_inflow_mode_handle= NULL;
100     /* Initialize defaults, can be updated from inputs to API */
101     memset(&createParam, 0, sizeof(nwalCreateSAParams_t));
102     createParam.saIpSecParam.appRxPktFlowId = CPPI_PARAM_NOT_SPECIFIED;
103     createParam.saIpSecParam.appRxPktQueue = QMSS_PARAM_NOT_SPECIFIED;
105     if (inflow_mode & NETAPI_SEC_SA_INFLOW)
106     {
107         pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
108         if (!pTransInfo)
109         {
110             *perr =  NETAPI_ERR_BUSY;
111             netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
112             return -1;
113         }
114         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
115         pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
116         pTransInfo->inUse = nwal_TRUE;
117         pTransInfo->netapi_handle = h;
119         /* build SA parameters */
120         saInfo.spi = sa_info->spi;
121         memcpy(&saInfo.dst, &sa_info->dst, sizeof( nwalIpAddr_t));
122         memcpy(&saInfo.src, &sa_info->src, sizeof( nwalIpAddr_t));
123         saInfo.proto = sa_info->proto;
124         createParam.macHandle = mac_handle;
125         createParam.ipType = sa_info->ipType;
126         createParam.saIpSecParam.dir = sa_info->dir;
127         createParam.saIpSecParam.saMode = sa_info->saMode;
128         createParam.saIpSecParam.replayWindow = sa_info->replayWindow;
129         createParam.saIpSecParam.authMode = sa_info->authMode;
130         createParam.saIpSecParam.cipherMode = sa_info->cipherMode;
131         createParam.saIpSecParam.esnLo = sa_info->esnLo;
132         createParam.saIpSecParam.esnHi = sa_info->esnHi;
133         if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
134             (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
135             (sa_info->authMode == NWAL_SA_AALG_GMAC))
136         {
137             createParam.saIpSecParam.macSize = 16;
138         }
139         if  ((sa_info->authMode == NWAL_SA_AALG_NULL) && 
140             (!((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) || 
141                (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM))))
142         {
143             createParam.saIpSecParam.replayWindow = 0;
144             createParam.saIpSecParam.macSize = 0;
145         }
146         memcpy(&createParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
148         if (route != NULL)
149         {
150             netapip_netcpCfgBuildRoute(route,&createParam.saIpSecParam.appRxPktFlowId, 
151                                          &createParam.saIpSecParam.appRxPktQueue);
152         }
154         /* fire off config message */
155         retValue = nwal_setSecAssoc (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
156                                         trans_id,
157                                         (nwal_AppId) appId,
158                                         &saInfo,
159                                         &createParam,
160                                         &pTransInfo->handle);
161         if(retValue == nwal_TRANS_COMPLETE)
162         {
163             have_to_wait=0;
164         }
165         else if(retValue !=  nwal_OK)
166         {
167             *perr = NETAPI_ERR_NWAL_ERR0;
168             netapip_freeTransInfo(pTransInfo);
169             netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
170             return -1;
171         }
173         if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
174         {
175             n->nwal_local.numPendingCfg++;
176             while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
177                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
178             {
179                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
180             }
181             if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
182             {
183                 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
184                 pTransInfo->inUse = nwal_FALSE;
185                 *perr = NETAPI_ERR_PA_FW;
186                 netapi_Log ("netapi_sec - ERROR returned by NETCP PA firmware %d\n",
187                         *perr);
188                 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
189                 return -1;
190             }
191         }
193         *p_inflow_mode_handle=pTransInfo->handle;
194         netapip_freeTransInfo(pTransInfo);
196         if (sa_info->dir == NWAL_SA_DIR_OUTBOUND)
197         {
198             memset(&nwalSaIpSecId, 0, sizeof(nwalSaIpSecId_t));
199             nwalSaIpSecId.spi = sa_info->spi;
200             memcpy(&(nwalSaIpSecId.src), &sa_info->src,sizeof( nwalIpAddr_t));
201             memcpy(&(nwalSaIpSecId.dst), &sa_info->dst,sizeof( nwalIpAddr_t));
202             nwalSaIpSecId.proto = sa_info->proto;
203             if (nwal_getSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
204                                      &nwalSaIpSecId, 
205                                      NWAL_SA_DIR_OUTBOUND,
206                                      p_inflow_mode_handle,
207                                      &swInfo0,
208                                      &swInfo1) == nwal_TRUE)
209             {
210                 netapi_Log("netapisecAddSA swInfo0: 0x%x, swInfo1: 0x%x\n", swInfo0, swInfo1);
211             }
212             else
213                 netapi_Log("netapisecAddSA: call to nwal_getSecAssoc() returned error\n");
214         }
215     }
217     /* sideband mode */
218     if (inflow_mode &NETAPI_SEC_SA_SIDEBAND)
219     {
220         nwalCreateDmSAParams_t  dmSaParam;
221         void * dm_handle;
222         memset(&dmSaParam,0,sizeof(nwalCreateDmSAParams_t));
223         dmSaParam.dmSaParam.dmChnType= (sa_info->dir==NWAL_SA_DIR_INBOUND)?  NWAL_DM_CHAN_DECRYPT: NWAL_DM_CHAN_ENCRYPT; /**direction*/ 
224         dmSaParam.dmSaParam.replayWindow=sa_info->replayWindow;
225         dmSaParam.dmSaParam.authMode=sa_info->authMode;
226         dmSaParam.dmSaParam.cipherMode=sa_info->cipherMode;
227         dmSaParam.dmSaParam.macSize=12;
228         dmSaParam.dmSaParam.aadSize=0;
229         dmSaParam.dmSaParam.enc1st =  (sa_info->dir ==NWAL_SA_DIR_OUTBOUND) ? nwal_TRUE : nwal_FALSE;  //encypt 1st for outbound
230         if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
231             (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
232             (sa_info->authMode == NWAL_SA_AALG_GMAC))
233         {
234             dmSaParam.dmSaParam.macSize = 16;
235             dmSaParam.dmSaParam.aadSize=8;
236             /* Enc1st needs to always be true for combined mode algorithms */
237             dmSaParam.dmSaParam.enc1st = nwal_TRUE;
238         }
239        else
240         {
241             dmSaParam.dmSaParam.macSize=12;
242             dmSaParam.dmSaParam.aadSize=0;
243         }
245        if  (sa_info->authMode == NWAL_SA_AALG_NULL)
246        {
247             dmSaParam.dmSaParam.enc1st = nwal_TRUE;
248        }
249         /* todo; allow app q for Sideband return */
250         memcpy(&dmSaParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
251         retValue = nwal_setDMSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
252                                   (nwal_AppId)appId,
253                                   &dmSaParam,
254                                   &dm_handle);
255         if(retValue != nwal_OK)
256         {
257             *perr = NETAPI_ERR_NWAL_ERR0;
258             netapi_Log ("netapi_secAddSA: nwal_setDMSecAssoc() returned Error Code %d\n",
259             retValue);
260             netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
261             return -1;
262         }
264         netapi_Log("netapi_secAddSA: Creating sideband mode SA for %d ( mac %d)\n", tunnelId, iface_no); 
265         *p_data_mode_handle = dm_handle;
266         memset(&dmPSCmdInfo, 0, sizeof(nwalTxDmPSCmdInfo_t));
267         retValue =  nwal_initDMPSCmdInfo(netapip_returnNwalInstanceHandle(h),
268                                          *p_data_mode_handle,
269                                          &dmPSCmdInfo); 
270     }
272     netapip_netcpCfgInsertSa(&netapi_get_global()->nwal_context,
273                           tunnelId,
274                           (sa_info->dir ==   NWAL_SA_DIR_INBOUND) ? TRUE: FALSE,
275                           inflow_mode,
276                           &saInfo, &createParam,
277                           *p_inflow_mode_handle,
278                           *p_data_mode_handle,
279                           &dmPSCmdInfo,
280                           swInfo0,
281                           swInfo1,
282                           p_user_data);
283     return  (appId);
286 /********************************************************************
287  * FUNCTION PURPOSE:  Internal function  to dynamically switch between inflow
288  *                                  and sideband mode
289  ********************************************************************
290  * DESCRIPTION:  Internal function  to dynamically switch between inflow
291  *                                  and sideband mode
292  ********************************************************************/
293 void netapi_secInflowMode(int iface,
294                           NETCP_CFG_SA_T sa,
295                           int on)
297     /* NOT_IMPLEMENTED */
298     netapi_Log("netapi_secInflowMode:  dynamic switch between inflow and sideband is NOT_IMPLEMENTED\n");
301 /********************************************************************
302  * FUNCTION PURPOSE:  Internal function  to delete an IPSEC SA
303  ********************************************************************
304  * DESCRIPTION:  Internal function to delete an IPSEC SA
305  ********************************************************************/
306 static void netapi_secDelSA_internal(NETAPI_T h,
307                                      int iface_no,
308                                      NETCP_CFG_SA_T sa_app_id,
309                                      int flags,
310                                      int *perr)
312     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
313     nwal_RetValue       retValue;
314     NetapiNwalTransInfo_t *pTransInfo;
315     nwal_TransID_t     trans_id;
316     int tunnelId = (sa_app_id >> NETAPI_NETCP_MATCH_ID_SHIFT) &NETAPI_NETCP_MATCH_ID_MASK;
317     void * handle_inflow;
318     void * handle_sideband;
319     int have_to_wait = 1;
321     handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
322                                           tunnelId, &handle_sideband);
323     *perr =0;
325     if(handle_inflow)
326     {
327     /* get a transaction id */
328         pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
329         if (!pTransInfo)
330         {
331             *perr =  NETAPI_ERR_BUSY;
332             return;
333         }
334         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
335         pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
336         pTransInfo->inUse = nwal_TRUE;
337         pTransInfo->netapi_handle = h;
339         retValue = nwal_delSecAssoc(
340                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
341                 trans_id,
342                 handle_inflow);
343         if(retValue == nwal_TRANS_COMPLETE)
344         {
345            have_to_wait=0;
346         }
347         else if(retValue !=  nwal_OK)
348         {
349                 *perr = NETAPI_ERR_NWAL_ERR0;
350                 netapi_Log ("netcp_cfg - ERROR: netapi_secDelSA_internal returned Error Code %d\n",
351                             retValue);
352                 netapip_freeTransInfo(pTransInfo);
353                 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
354         }
355         if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
356         {
357             n->nwal_local.numPendingCfg++;
359             while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
360                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
361             {
362                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
363             }
364             if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
365             {
366                 netapip_freeTransInfo(pTransInfo);
367                 *perr = NETAPI_ERR_PA_FW;
368                  if (!flags) 
369                     netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context, tunnelId);
370                 netapi_Log ("netapi_sec - ERROR returned by NETCP PA firmware %d\n",
371                         *perr);
372                 return;
373            }
374         }
375         netapi_Log ("netapi sec: inflow tunnel %d (iface %d) deleted\n",tunnelId,iface_no);
376         netapip_freeTransInfo(pTransInfo);
377     }
378     if (handle_sideband)
379     {
380         retValue=nwal_delDMSecAssoc( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
381                                     handle_sideband);
382         if(retValue !=  nwal_OK)
383         {
384             *perr = NETAPI_ERR_NWAL_ERR0;
385              netapi_Log ("netapi_sec  - ERROR: nwal_delDMSA returned Error Code %d\n",
386                     retValue);
388         }
389         else 
390             netapi_Log("netapi_sec: Sideband SA deleted\n");
391     }
392    
393     /* zap the entry */
394     if (!flags)
395         netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context, tunnelId);
398 /********************************************************************
399  * FUNCTION PURPOSE:  API to delete an IPSEC SA
400  ********************************************************************
401  * DESCRIPTION:  API to delete an IPSEC SA
402  ********************************************************************/
403 void netapi_secDelSA(NETAPI_T h,
404                      int iface_no,
405                      NETCP_CFG_SA_T sa_app_id,
406                      int *perr)
408     netapi_secDelSA_internal( h, iface_no,  sa_app_id, 0x00, perr);
412 /********************************************************************
413  * FUNCTION PURPOSE:  API to add a recieve security policy
414  ********************************************************************
415  * DESCRIPTION:  API to add a recieve security policy
416  ********************************************************************/
417 NETCP_CFG_IPSEC_POLICY_T netapi_secAddRxPolicy(NETAPI_T h, 
418                                                NETCP_CFG_SA_T sa,
419                                                nwal_IpType ipType,
420                                                nwalIpAddr_t * src_ip_addr,
421                                                nwalIpAddr_t * dst_ip_addr,
422                                                nwalIpOpt_t * ip_qualifiers,
423                                                NETCP_CFG_ROUTE_HANDLE_T  route,
424                                                void * user_data,
425                                                int * perr)
427     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
428     nwal_RetValue       retValue;
429     NetapiNwalTransInfo_t *pTransInfo;
430     nwal_TransID_t     trans_id;
431     unsigned int appId = NETAPI_NETCP_MATCH_IPSEC_POLICY | (sa& NETAPI_NETCP_MATCH_ID_MASK);
432     int policyId;
433     int tunnelId= netapi_cfgGetMatchId(sa);
434     void * blah;
435     int iface_no = netapi_cfgGetMatchLogicalMacIface(sa);
437     nwalSecPolParams_t createParam =
438     {
439         0,  /* handle */
440         NWAL_SA_DIR_INBOUND,
441         4,      /* IP Type */
442         {0},  /* dst */
443         {0},  /* src */
444         {0 },/* IP Options */
445         NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
446         NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
447         CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
448         QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
449     };
451     void * sa_handle = NULL;
452     *perr =0;
453     
454     if ((!n) )
455     {
456         *perr = NETAPI_ERR_BAD_INPUT;
457         return -1;
458     }
460     sa_handle = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,tunnelId,&blah);
461     if (!sa_handle)
462     {
463         *perr = NETAPI_ERR_BAD_INPUT;
464         return -1;
465     }
467     /* get a transaction id */
468     pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
469     if (!pTransInfo)
470     {
471         *perr =  NETAPI_ERR_BUSY;
472         return -1;
473     }
474     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
475     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
476     pTransInfo->inUse = nwal_TRUE;
477     pTransInfo->netapi_handle = h;
478     createParam.handle = sa_handle;
479     createParam.ipType = ipType;
480     if (dst_ip_addr) memcpy(&createParam.dst, dst_ip_addr, sizeof(nwalIpAddr_t)); 
481     if (src_ip_addr) memcpy(&createParam.src, src_ip_addr, sizeof(nwalIpAddr_t)); 
482     if (ip_qualifiers) memcpy(&createParam.ipOpt,ip_qualifiers ,sizeof(nwalIpOpt_t));
483     if (route != NULL)
484     {
485         netapip_netcpCfgBuildRoute(route,&createParam.appRxPktFlowId,
486                                      &createParam.appRxPktQueue);
487     }
488     /* reserve a slot */
489     policyId = netapip_netcpCfgFindPolicySlot(&netapi_get_global()->nwal_context,
490                            tunnelId);
491     if (policyId <0) 
492     {
493         *perr= NETAPI_ERR_NOMEM;
494         netapip_freeTransInfo(pTransInfo);
495         return -1;
496     }
497     appId |=  (policyId<<8);
499     /* fire off config message */
500     retValue = nwal_setSecPolicy (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
501                                   trans_id,
502                                   (nwal_AppId) appId,
503                                   &createParam,
504                                   &pTransInfo->handle);
505     if(retValue !=  nwal_OK)
506     {
507         *perr = NETAPI_ERR_NWAL_ERR0;
508         netapi_Log ("netapi sec - ERROR: nwal_setPolicy returned Error Code %d\n",
509                     retValue);
510         netapip_freeTransInfo(pTransInfo);
511         
512         netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context,policyId);
513         return -1;
514     }
516     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
517     {
518         n->nwal_local.numPendingCfg++;
519         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
520                 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
521         {
522             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
523         }
524         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
525         {
526             netapip_freeTransInfo(pTransInfo);
527             *perr = NETAPI_ERR_PA_FW;
528             netapi_Log ("netapi_sec - ERROR2: netapi_secAddRxPolicy returned Error Code %d\n",
529                     *perr);
530             netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context,policyId);
531             return -1;
532         }
533     }
534     netapi_Log ("netapi sec: SA %d added to tunnel %d  mac %d\n", policyId, tunnelId, iface_no);
536     /* save stuff */
537     netapip_netcpCfgInsertPolicy(&netapi_get_global()->nwal_context,
538                            policyId,
539                           (void *) pTransInfo->handle,
540                           user_data);
541     netapip_freeTransInfo(pTransInfo);
542     return  (appId);
545 /********************************************************************
546  * FUNCTION PURPOSE:  Internal function to delete a recieve security policy
547  ********************************************************************
548  * DESCRIPTION:  Internal function to delete a recieve security policy
549  ********************************************************************/
550 static void netapi_secDelRxPolicy_internal(NETAPI_T h,
551                                            NETCP_CFG_IPSEC_POLICY_T policy_app_id,
552                                            int flags,
553                                            int *perr)
555     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
556     nwal_RetValue       retValue;
557     NetapiNwalTransInfo_t *pTransInfo;
558     nwal_TransID_t     trans_id;
559     int policyId = netapi_cfgGetMatchId(policy_app_id);
560     void * handle_policy=NULL;
562     handle_policy = netapip_netcpCfgGetPolicy(&netapi_get_global()->nwal_context,policyId);
563                                           ;
564     if (!handle_policy)
565     {
566         *perr = NETAPI_ERR_BAD_INPUT;
567         goto ERR_netapi_secDelRxPolicy_internal;
568      }
569     *perr =0;
571     /* get a transaction id */
572     pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
573     if (!pTransInfo)
574     {
575         *perr =  NETAPI_ERR_BUSY;
576         goto ERR_netapi_secDelRxPolicy_internal;
577     }
578     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
579     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
580     pTransInfo->inUse = nwal_TRUE;
581     pTransInfo->netapi_handle = h;
583     /* issue request */
584     retValue = nwal_delSecPolicy(
585                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
586                 trans_id,
587                 handle_policy);
588     if(retValue !=  nwal_OK)
589     {
590         *perr = NETAPI_ERR_NWAL_ERR0;
591         netapi_Log ("netapi sec - ERROR: netapi_secDelRxPolicy_internal returned Error Code %d\n",
592                     retValue);
593         netapip_freeTransInfo(pTransInfo);
594         goto ERR_netapi_secDelRxPolicy_internal;
595     }
597     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
598     {
599         n->nwal_local.numPendingCfg++;
600         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
601                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
602         {
603             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
604         }
605         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
606         {
607             netapip_freeTransInfo(pTransInfo);
608             *perr = NETAPI_ERR_PA_FW;
609             netapi_Log ("netapi_sec - ERROR2: netapi_secDelRxPolicy_internal returned Error Code %d\n",
610                     *perr);
611             //zap the entry
612             if (!flags)
613                 netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context, policyId);
614             goto ERR_netapi_secDelRxPolicy_internal;
615             
616         }
617     }
618     netapi_Log ("netapi sec: policy %d (iface %d) deleted\n",policyId,(policy_app_id&0xff));
619     netapip_freeTransInfo(pTransInfo);
620     /* zap the entry */
621     if (!flags)
622     {
623         netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context, policyId);
624     }
625 ERR_netapi_secDelRxPolicy_internal:
626     return;
629 /********************************************************************
630  * FUNCTION PURPOSE:  API to delete a recieve security policy
631  ********************************************************************
632  * DESCRIPTION:  API to delete a recieve security policy
633  ********************************************************************/
634 void netapi_secDelRxPolicy(NETAPI_T h,
635                            NETCP_CFG_IPSEC_POLICY_T policy_app_id,
636                            int *perr)
638     netapi_secDelRxPolicy_internal(h,  policy_app_id, 0, perr);
641 /********************************************************************
642  * FUNCTION PURPOSE:  API to retrieve SA statistics via NWAL
643  ********************************************************************
644  * DESCRIPTION:  API to retrieve SA statistics via NWAL
645  ********************************************************************/
646 void  netapi_getSaStats (NETAPI_T               h, 
647                          NETCP_CFG_SA_T         handle,
648                          NETAPI_SA_STATS_T*     pSaStats)
650     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
651     void * handle_inflow;
652     void * handle_sideband;
653     int tunnelId = (handle >>8) &0xffff;
654     int have_to_wait = 1;
655     handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
656                                           tunnelId, &handle_sideband);
657     if(handle_inflow)
658     {
659         nwal_getSecAssocStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, 
660                                                 handle_inflow, &(pSaStats->saIpsecStats));
661         pSaStats->validParams |= NETAPI_IPSEC_STAT_VALID;
662     }
663     if(handle_sideband)
664     {
665         nwal_getDataModeStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, 
666                                                 handle_sideband, &(pSaStats->dataModeStats));
667         pSaStats->validParams |= NETAPI_SIDEBAND_DATA_MODE_STAT_VALID;
668     }