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);
284 }
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)
296 {
297 /* NOT_IMPLEMENTED */
298 netapi_Log("netapi_secInflowMode: dynamic switch between inflow and sideband is NOT_IMPLEMENTED\n");
299 }
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)
311 {
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 }
393 /* zap the entry */
394 if (!flags)
395 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context, tunnelId);
396 }
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)
407 {
408 netapi_secDelSA_internal( h, iface_no, sa_app_id, 0x00, perr);
409 }
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)
426 {
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;
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);
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);
543 }
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)
554 {
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;
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;
627 }
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)
637 {
638 netapi_secDelRxPolicy_internal(h, policy_app_id, 0, perr);
639 }
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)
649 {
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 }
669 }