Additional fix for SDOCM00107974: Add support for hmac-sha256 in netapi ipsecmgr...
[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.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 = 0;
72     uint32_t    swInfo1 = 0;
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                 0                                 /* route type */
96            },
97            /* nwalSaIpSecKeyParams_t */
98            {0}
99     };
102     void * mac_handle = netapip_netcpCfgGetMacHandle(&netapi_get_global()->nwal_context,iface_no);
103     *perr =NETAPI_ERR_OK;
104     if ((!n) || (!sa_info)  ||  (!p_data_mode_handle))
105     {
106         *perr = NETAPI_ERR_BAD_INPUT;
107         return -1;
108     }
110     /* reserve a slot */
111     tunnelId = netapip_netcpCfgFindSaSlot(n,
112                                           &netapi_get_global()->nwal_context,
113                                           iface_no);
115     if (tunnelId <0)
116     {
117         *perr= NETAPI_ERR_NOMEM;
118         return -1;
119     }
120     appId |=  (tunnelId << NETAPI_NETCP_MATCH_ID_SHIFT);
121     netapi_Log("netapi_secAddSA: app id: 0x%x\n", appId);
123     *p_data_mode_handle= NULL;  
124     *p_inflow_mode_handle= NULL;
128     if (inflow_mode & NETAPI_SEC_SA_INFLOW)
129     {
130         pTransInfo = netapip_getFreeTransInfo(n,
131                                               (NETAPI_PROC_GLOBAL_T *) n->proc_global,
132                                                &trans_id);
133         if (!pTransInfo)
134         {
135             *perr =  NETAPI_ERR_BUSY;
136             netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
137             return -1;
138         }
139         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
140         pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
141         pTransInfo->inUse = nwal_TRUE;
142         pTransInfo->netapi_handle = h;
144         /* build SA parameters */
145         saInfo.spi = sa_info->spi;
146         memcpy(&saInfo.dst, &sa_info->dst, sizeof( nwalIpAddr_t));
147         memcpy(&saInfo.src, &sa_info->src, sizeof( nwalIpAddr_t));
148         saInfo.proto = sa_info->proto;
149         createParam.macHandle = mac_handle;
150         createParam.ipType = sa_info->ipType;
151         createParam.saIpSecParam.dir = sa_info->dir;
152         createParam.saIpSecParam.saMode = sa_info->saMode;
153         createParam.saIpSecParam.replayWindow = sa_info->replayWindow;
154         createParam.saIpSecParam.authMode = sa_info->authMode;
155         createParam.saIpSecParam.cipherMode = sa_info->cipherMode;
156         createParam.saIpSecParam.esnLo = sa_info->esnLo;
157         createParam.saIpSecParam.esnHi = sa_info->esnHi;
158         if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
159             (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
160             (sa_info->authMode == NWAL_SA_AALG_GMAC)      ||
161             (sa_info->authMode == NWAL_SA_AALG_HMAC_SHA2_256)      ||
162             (sa_info->authMode == NWAL_SA_AALG_HMAC_SHA2_256_RFC4868))
163         {
164             createParam.saIpSecParam.macSize = 16;
165         }
166         if  ((sa_info->authMode == NWAL_SA_AALG_NULL) && 
167             (!((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) || 
168                (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM))))
169         {
170             createParam.saIpSecParam.replayWindow = 0;
171             createParam.saIpSecParam.macSize = 0;
172         }
173         memcpy(&createParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
175         if (route != NULL)
176         {
177             if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
178                 NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
179             {
180                createParam.saIpSecParam.validParams |= 
181                         NWAL_SA_INFO_VALID_PARAM_ROUTE_TYPE;
182             }
183             netapip_netcpCfgBuildRoute(route,
184                                        &createParam.saIpSecParam.appRxPktFlowId,
185                                        &createParam.saIpSecParam.appRxPktQueue,
186                                        &createParam.saIpSecParam.routeType);
187         }
189         /* fire off config message */
190         retValue = nwal_setSecAssoc (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
191                                         trans_id,
192                                         (nwal_AppId) appId,
193                                         &saInfo,
194                                         &createParam,
195                                         &pTransInfo->handle);
196         if(retValue == nwal_TRANS_COMPLETE)
197         {
198             have_to_wait=0;
199         }
200         else if(retValue !=  nwal_OK)
201         {
202             *perr = NETAPI_ERR_NWAL_ERR0;
203             netapip_freeTransInfo(pTransInfo);
204             netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
205             return -1;
206         }
208         if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
209         {
210             n->nwal_local.numPendingCfg++;
211             while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
212                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
213             {
214                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
215             }
216             if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
217             {
218                 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
219                 pTransInfo->inUse = nwal_FALSE;
220                 *perr = NETAPI_ERR_PA_FW;
221                 netapi_Log ("netapi_sec - ERROR returned by NETCP PA firmware %d\n",
222                         *perr);
223                 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
224                 return -1;
225             }
226         }
228         *p_inflow_mode_handle=pTransInfo->handle;
229         netapip_freeTransInfo(pTransInfo);
231         if (sa_info->dir == NWAL_SA_DIR_OUTBOUND)
232         {
233             memset(&nwalSaIpSecId, 0, sizeof(nwalSaIpSecId_t));
234             nwalSaIpSecId.spi = sa_info->spi;
235             memcpy(&(nwalSaIpSecId.src), &sa_info->src,sizeof( nwalIpAddr_t));
236             memcpy(&(nwalSaIpSecId.dst), &sa_info->dst,sizeof( nwalIpAddr_t));
237             nwalSaIpSecId.proto = sa_info->proto;
238             if (nwal_getSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
239                                      &nwalSaIpSecId, 
240                                      NWAL_SA_DIR_OUTBOUND,
241                                      p_inflow_mode_handle,
242                                      &swInfo0,
243                                      &swInfo1) == nwal_TRUE)
244             {
245                 //netapi_Log("netapisecAddSA swInfo0: 0x%x, swInfo1: 0x%x\n", swInfo0, swInfo1);
246             }
247             else
248                 netapi_Log("netapisecAddSA: call to nwal_getSecAssoc() returned error\n");
249         }
250     }
252     /* sideband mode */
253     if (inflow_mode &NETAPI_SEC_SA_SIDEBAND)
254     {
255         nwalCreateDmSAParams_t  dmSaParam;
256         void * dm_handle;
257         memset(&dmSaParam,0,sizeof(nwalCreateDmSAParams_t));
258         dmSaParam.dmSaParam.dmChnType= (sa_info->dir==NWAL_SA_DIR_INBOUND)?  NWAL_DM_CHAN_DECRYPT: NWAL_DM_CHAN_ENCRYPT; /**direction*/ 
259         dmSaParam.dmSaParam.replayWindow=sa_info->replayWindow;
260         dmSaParam.dmSaParam.authMode=sa_info->authMode;
261         dmSaParam.dmSaParam.cipherMode=sa_info->cipherMode;
262         dmSaParam.dmSaParam.macSize=12;
263         dmSaParam.dmSaParam.aadSize=0;
264         dmSaParam.dmSaParam.enc1st =  (sa_info->dir ==NWAL_SA_DIR_OUTBOUND) ? nwal_TRUE : nwal_FALSE;  //encypt 1st for outbound
265         if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
266             (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
267             (sa_info->authMode == NWAL_SA_AALG_GMAC))
268         {
269             dmSaParam.dmSaParam.macSize = 16;
270             dmSaParam.dmSaParam.aadSize=8;
271             /* Enc1st needs to always be true for combined mode algorithms */
272             dmSaParam.dmSaParam.enc1st = nwal_TRUE;
273         }
274        else
275         {
276             dmSaParam.dmSaParam.macSize=12;
277             dmSaParam.dmSaParam.aadSize=0;
278         }
280        if  (sa_info->authMode == NWAL_SA_AALG_NULL)
281        {
282             dmSaParam.dmSaParam.enc1st = nwal_TRUE;
283        }
284         /* todo; allow app q for Sideband return */
285         memcpy(&dmSaParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
286         retValue = nwal_setDMSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
287                                   (nwal_AppId)appId,
288                                   &dmSaParam,
289                                   &dm_handle);
290         if(retValue != nwal_OK)
291         {
292             *perr = NETAPI_ERR_NWAL_ERR0;
293             netapi_Log ("netapi_secAddSA: nwal_setDMSecAssoc() returned Error Code %d\n",
294             retValue);
295             netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
296             return -1;
297         }
299         //netapi_Log("netapi_secAddSA: Creating sideband mode SA for %d ( mac %d)\n", tunnelId, iface_no); 
300         *p_data_mode_handle = dm_handle;
301         memset(&dmPSCmdInfo, 0, sizeof(nwalTxDmPSCmdInfo_t));
302         retValue =  nwal_initDMPSCmdInfo(netapip_returnNwalInstanceHandle(h),
303                                          *p_data_mode_handle,
304                                          &dmPSCmdInfo); 
305     }
307     netapip_netcpCfgInsertSa(&netapi_get_global()->nwal_context,
308                           tunnelId,
309                           (sa_info->dir ==   NWAL_SA_DIR_INBOUND) ? NETAPI_TRUE: NETAPI_FALSE,
310                           inflow_mode,
311                           &saInfo,
312                           &createParam,
313                           *p_inflow_mode_handle,
314                           *p_data_mode_handle,
315                           &dmPSCmdInfo,
316                           swInfo0,
317                           swInfo1,
318                           p_user_data);
319     return  (appId);
322 /********************************************************************
323  * FUNCTION PURPOSE:  Internal function  to dynamically switch between inflow
324  *                                  and sideband mode
325  ********************************************************************
326  * DESCRIPTION:  Internal function  to dynamically switch between inflow
327  *                                  and sideband mode
328  ********************************************************************/
329 void netapi_secInflowMode(int iface,
330                           NETCP_CFG_SA_T sa,
331                           int on)
333     /* NOT_IMPLEMENTED */
334     netapi_Log("netapi_secInflowMode:  dynamic switch between inflow and sideband is NOT_IMPLEMENTED\n");
337 /********************************************************************
338  * FUNCTION PURPOSE:  Internal function  to delete an IPSEC SA
339  ********************************************************************
340  * DESCRIPTION:  Internal function to delete an IPSEC SA
341  ********************************************************************/
342 static void netapi_secDelSA_internal(NETAPI_T h,
343                                      int iface_no,
344                                      NETCP_CFG_SA_T sa_app_id,
345                                      int flags,
346                                      int *perr)
348     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
349     nwal_RetValue       retValue;
350     NetapiNwalTransInfo_t *pTransInfo;
351     nwal_TransID_t     trans_id;
352     int tunnelId = (sa_app_id >> NETAPI_NETCP_MATCH_ID_SHIFT) &NETAPI_NETCP_MATCH_ID_MASK;
353     void * handle_inflow;
354     void * handle_sideband;
355     int have_to_wait = 1;
357     handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
358                                           tunnelId, &handle_sideband);
359     *perr =0;
361     if(handle_inflow)
362     {
363     /* get a transaction id */
364         pTransInfo = netapip_getFreeTransInfo(n,
365                                               (NETAPI_PROC_GLOBAL_T *) n->proc_global,
366                                               &trans_id);
367         if (!pTransInfo)
368         {
369             *perr =  NETAPI_ERR_BUSY;
370             return;
371         }
372         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
373         pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
374         pTransInfo->inUse = nwal_TRUE;
375         pTransInfo->netapi_handle = h;
377         retValue = nwal_delSecAssoc(
378                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
379                 trans_id,
380                 handle_inflow);
381         if(retValue == nwal_TRANS_COMPLETE)
382         {
383            have_to_wait=0;
384         }
385         else if(retValue !=  nwal_OK)
386         {
387                 *perr = NETAPI_ERR_NWAL_ERR0;
388                 netapi_Log ("netcp_cfg - ERROR: netapi_secDelSA_internal returned Error Code %d\n",
389                             retValue);
390                 netapip_freeTransInfo(pTransInfo);
391                 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
392         }
393         if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
394         {
395             n->nwal_local.numPendingCfg++;
397             while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
398                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
399             {
400                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
401             }
402             if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
403             {
404                 netapip_freeTransInfo(pTransInfo);
405                 *perr = NETAPI_ERR_PA_FW;
406                  if (!flags) 
407                     netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context, tunnelId);
408                 netapi_Log ("netapi_sec - ERROR returned by NETCP PA firmware %d\n",
409                         *perr);
410                 return;
411            }
412         }
413         netapi_Log ("netapi sec: inflow tunnel %d (iface %d) deleted\n",tunnelId,iface_no);
414         netapip_freeTransInfo(pTransInfo);
415     }
416     if (handle_sideband)
417     {
418         retValue=nwal_delDMSecAssoc( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
419                                     handle_sideband);
420         if(retValue !=  nwal_OK)
421         {
422             *perr = NETAPI_ERR_NWAL_ERR0;
423              netapi_Log ("netapi_sec  - ERROR: nwal_delDMSA returned Error Code %d\n",
424                     retValue);
426         }
427         else 
428             netapi_Log("netapi_sec: Sideband SA deleted\n");
429     }
430    
431     /* zap the entry */
432     if (!flags)
433         netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context, tunnelId);
436 /********************************************************************
437  * FUNCTION PURPOSE:  API to delete an IPSEC SA
438  ********************************************************************
439  * DESCRIPTION:  API to delete an IPSEC SA
440  ********************************************************************/
441 void netapi_secDelSA(NETAPI_T h,
442                      int iface_no,
443                      NETCP_CFG_SA_T sa_app_id,
444                      int *perr)
446     netapi_secDelSA_internal( h, iface_no,  sa_app_id, 0x00, perr);
450 /********************************************************************
451  * FUNCTION PURPOSE:  API to add a receive security policy
452  ********************************************************************
453  * DESCRIPTION:  API to add a receive security policy
454  ********************************************************************/
455 NETCP_CFG_IPSEC_POLICY_T netapi_secAddRxPolicy(NETAPI_T h, 
456                                                NETCP_CFG_SA_T sa,
457                                                nwal_IpType ipType,
458                                                nwalIpAddr_t * src_ip_addr,
459                                                nwalIpAddr_t * dst_ip_addr,
460                                                nwalIpOpt_t * ip_qualifiers,
461                                                NETCP_CFG_ROUTE_HANDLE_T  route,
462                                                void * user_data,
463                                                int * perr)
465     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
466     nwal_RetValue       retValue;
467     NetapiNwalTransInfo_t *pTransInfo;
468     nwal_TransID_t     trans_id;
469     unsigned int appId = NETAPI_NETCP_MATCH_IPSEC_POLICY;
470     int policyId;
471     int tunnelId= netapi_cfgGetMatchId(sa);
472     void * blah;
473     int iface_no = netapi_cfgGetMatchLogicalMacIface(sa);
475     nwalSecPolParams_t createParam =
476     {
477         0,  /* handle */
478         0,  /* valid params */
479         NWAL_SA_DIR_INBOUND,
480         4,      /* IP Type */
481         {0},  /* dst */
482         {0},  /* src */
483         {0 },/* IP Options */
484         NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
485         NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
486         CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
487         QMSS_PARAM_NOT_SPECIFIED,                    /* Use default queue configured to NWAL if packet is routed to host */
488         0                                            /* Optional: route type */
489     };
491     void * sa_handle = NULL;
492     *perr =0;
493     
494     if ((!n) )
495     {
496         *perr = NETAPI_ERR_BAD_INPUT;
497         return -1;
498     }
500     sa_handle = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,tunnelId,&blah);
501     if (!sa_handle)
502     {
503         *perr = NETAPI_ERR_BAD_INPUT;
504         return -1;
505     }
507     /* get a transaction id */
508     pTransInfo = netapip_getFreeTransInfo(n,
509                                           (NETAPI_PROC_GLOBAL_T *) n->proc_global,
510                                           &trans_id);
511     if (!pTransInfo)
512     {
513         *perr =  NETAPI_ERR_BUSY;
514         return -1;
515     }
516     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
517     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
518     pTransInfo->inUse = nwal_TRUE;
519     pTransInfo->netapi_handle = h;
520     createParam.handle = sa_handle;
521     createParam.ipType = ipType;
522     if (dst_ip_addr) memcpy(&createParam.dst, dst_ip_addr, sizeof(nwalIpAddr_t)); 
523     if (src_ip_addr) memcpy(&createParam.src, src_ip_addr, sizeof(nwalIpAddr_t)); 
524     if (ip_qualifiers) memcpy(&createParam.ipOpt,ip_qualifiers ,sizeof(nwalIpOpt_t));
525     if (route != NULL)
526     {
527         if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
528             NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
529         {
530            createParam.validParams |= 
531                     NWAL_SET_SEC_POLICY_VALID_PARAM_ROUTE_TYPE;
532         }
533         netapip_netcpCfgBuildRoute(route,
534                                    &createParam.appRxPktFlowId,
535                                    &createParam.appRxPktQueue,
536                                    &createParam.routeType);
537     }
538     /* reserve a slot */
539     policyId = netapip_netcpCfgFindPolicySlot(n,
540                                               &netapi_get_global()->nwal_context,
541                                               tunnelId);
542     if (policyId <0) 
543     {
544         *perr= NETAPI_ERR_NOMEM;
545         netapip_freeTransInfo(pTransInfo);
546         return -1;
547     }
548     appId |=  (policyId <<8);
550     /* fire off config message */
551     retValue = nwal_setSecPolicy (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
552                                   trans_id,
553                                   (nwal_AppId) appId,
554                                   &createParam,
555                                   &pTransInfo->handle);
556     if(retValue !=  nwal_OK)
557     {
558         *perr = NETAPI_ERR_NWAL_ERR0;
559         printf("netapi_secAddPolicy: error returned: %d\n", retValue);
560         netapi_Log ("netapi sec - ERROR: nwal_setPolicy returned Error Code %d\n",
561                     retValue);
562         netapip_freeTransInfo(pTransInfo);
563         
564         netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context,policyId);
565         return -1;
566     }
568     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
569     {
570         n->nwal_local.numPendingCfg++;
571         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
572                 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
573         {
574             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
575         }
576         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
577         {
578             netapip_freeTransInfo(pTransInfo);
579             *perr = NETAPI_ERR_PA_FW;
580             netapi_Log ("netapi_sec - ERROR2: netapi_secAddRxPolicy returned Error Code %d\n",
581                     *perr);
582             netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context,policyId);
583             return -1;
584         }
585     }
586     netapi_Log ("netapi sec: SA %d added to tunnel %d  mac %d\n", policyId, tunnelId, iface_no);
588     /* save stuff */
589     netapip_netcpCfgInsertPolicy(&netapi_get_global()->nwal_context,
590                            policyId,
591                           (void *) pTransInfo->handle,
592                           user_data);
593     netapip_freeTransInfo(pTransInfo);
594     return  (appId);
597 /********************************************************************
598  * FUNCTION PURPOSE:  Internal function to delete a receive security policy
599  ********************************************************************
600  * DESCRIPTION:  Internal function to delete a receive security policy
601  ********************************************************************/
602 static void netapi_secDelRxPolicy_internal(NETAPI_T h,
603                                            NETCP_CFG_IPSEC_POLICY_T policy_app_id,
604                                            int flags,
605                                            int *perr)
607     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
608     nwal_RetValue       retValue;
609     NetapiNwalTransInfo_t *pTransInfo;
610     nwal_TransID_t     trans_id;
611     int policyId = netapi_cfgGetMatchId(policy_app_id);
612     void * handle_policy=NULL;
614     handle_policy = netapip_netcpCfgGetPolicy(&netapi_get_global()->nwal_context,policyId);
615                                           ;
616     if (!handle_policy)
617     {
618         *perr = NETAPI_ERR_BAD_INPUT;
619         goto ERR_netapi_secDelRxPolicy_internal;
620      }
621     *perr =0;
623     /* get a transaction id */
624     pTransInfo = netapip_getFreeTransInfo(n,
625                                          (NETAPI_PROC_GLOBAL_T *) n->proc_global,
626                                          &trans_id);
627     if (!pTransInfo)
628     {
629         *perr =  NETAPI_ERR_BUSY;
630         goto ERR_netapi_secDelRxPolicy_internal;
631     }
632     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
633     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
634     pTransInfo->inUse = nwal_TRUE;
635     pTransInfo->netapi_handle = h;
637     /* issue request */
638     retValue = nwal_delSecPolicy(
639                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
640                 trans_id,
641                 handle_policy);
642     if(retValue !=  nwal_OK)
643     {
644         *perr = NETAPI_ERR_NWAL_ERR0;
645         netapi_Log ("netapi sec - ERROR: netapi_secDelRxPolicy_internal returned Error Code %d\n",
646                     retValue);
647         netapip_freeTransInfo(pTransInfo);
648         goto ERR_netapi_secDelRxPolicy_internal;
649     }
651     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
652     {
653         n->nwal_local.numPendingCfg++;
654         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
655                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
656         {
657             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
658         }
659         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
660         {
661             netapip_freeTransInfo(pTransInfo);
662             *perr = NETAPI_ERR_PA_FW;
663             netapi_Log ("netapi_sec - ERROR2: netapi_secDelRxPolicy_internal returned Error Code %d\n",
664                     *perr);
665             //zap the entry
666             if (!flags)
667                 netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context, policyId);
668             goto ERR_netapi_secDelRxPolicy_internal;
669             
670         }
671     }
672     netapi_Log ("netapi sec: policy %d (iface %d) deleted\n",policyId,(policy_app_id&0xff));
673     netapip_freeTransInfo(pTransInfo);
674     /* zap the entry */
675     if (!flags)
676     {
677         netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context, policyId);
678     }
679 ERR_netapi_secDelRxPolicy_internal:
680     return;
683 /********************************************************************
684  * FUNCTION PURPOSE:  API to delete a receive security policy
685  ********************************************************************
686  * DESCRIPTION:  API to delete a receive security policy
687  ********************************************************************/
688 void netapi_secDelRxPolicy(NETAPI_T h,
689                            NETCP_CFG_IPSEC_POLICY_T policy_app_id,
690                            int *perr)
692     netapi_secDelRxPolicy_internal(h,  policy_app_id, 0, perr);
695 /********************************************************************
696  * FUNCTION PURPOSE:  API to retrieve SA statistics via NWAL
697  ********************************************************************
698  * DESCRIPTION:  API to retrieve SA statistics via NWAL
699  ********************************************************************/
700 void  netapi_getSaStats (NETAPI_T               h, 
701                          NETCP_CFG_SA_T         handle,
702                          NETAPI_SA_STATS_T*     pSaStats)
704     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
705     void * handle_inflow;
706     void * handle_sideband;
707     int tunnelId = (handle >> NETAPI_NETCP_MATCH_ID_SHIFT) &0xffff;
708     int have_to_wait = 1;
709     handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
710                                           tunnelId, &handle_sideband);
711     if(handle_inflow)
712     {
713         nwal_getSecAssocStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, 
714                                                 handle_inflow, &(pSaStats->saIpsecStats));
715         pSaStats->validParams |= NETAPI_IPSEC_STAT_VALID;
716     }
717     if(handle_sideband)
718     {
719         nwal_getDataModeStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, 
720                                                 handle_sideband, &(pSaStats->dataModeStats));
721         pSaStats->validParams |= NETAPI_SIDEBAND_DATA_MODE_STAT_VALID;
722     }
726 /**********************************************************************************
727  * FUNCTION PURPOSE:  API to  API to retrieve local channel context information
728  **********************************************************************************
729  * DESCRIPTION:  API to retrieve API to retrieve local channel context information
730  *********************************************************************************/
731 void netapi_secGetChanCtxInfo(NETAPI_T h,
732                            NETCP_CFG_APP_ID_T appId,
733                            nwalChanCxtInfo_t* pInfo)
736     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
737     void * handle_inflow;
738     void * handle_sideband = NULL;
739     void * handle_policy=NULL;
740     nwalChanCxtInfo_t info;
741     uint32_t stage = 0;
742     int policyId;
743     int tunnelId;
745     if(!pInfo)
746         return;
747     memset(pInfo, 0, sizeof(nwalChanCxtInfo_t));
749     stage = netapi_cfgGetMatchStage(appId);
750     netapi_Log("netapi_secGetChanCtxInfo: app id: 0x%x, stage: 0x%x\n", appId, stage);
753     switch (stage)
754     {
755         case 1:
756             /* this is for SA, need SA and OUTER IP handle */
757             tunnelId = netapi_cfgGetMatchId(appId);
758             handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
759                                           tunnelId, &handle_sideband);
760             if(handle_inflow)
761             {
762                 nwal_getChanCxtInfo(&netapi_get_global()->nwal_context,
763                             handle_inflow,
764                             pInfo);
765                 netapi_Log("netapi_secGetChanCtxInfo: outerIP: 0x%x, SA chan handle: 0x%x, bitmap: 0x%x\n",
766                     pInfo->paOuterIpHandle, pInfo->saChanHandle, pInfo->validBitMap);
767             }
768             break;
769         case 2:
770             /* this is for policy, need SA inner IP */
771             policyId = netapi_cfgGetMatchId(appId);
772             handle_policy = netapip_netcpCfgGetPolicy(&netapi_get_global()->nwal_context,
773                                                           policyId);
774             if (handle_policy)
775             {
776                 nwal_getChanCxtInfo(&netapi_get_global()->nwal_context,
777                             handle_policy,
778                             pInfo);
779                 netapi_Log("netapi_secGetChanCtxInfo: innerIP: 0x%x, bitmap: 0x%x\n",
780                     pInfo->paInnerIpHandle, pInfo->validBitMap);
781             }
782             break;
783         default:
784             netapi_Log("netapi_secGetChanCtxInfo:Invalid APPID provided\n");
785             break;
786     }
787     return;