9c6c6a2d00fc627fdbc55b3cde1e09041f48a66b
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 NETAPI_SA_INFO_LOCAL_T netapi_sa_db[TUNE_NETAPI_MAX_SA];
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 = 0;
73 uint32_t swInfo1 = 0;
74 int sa_db_slot;
75 int free_sa_db_slot = 0;
76 nwalCreateSAParams_t createParam =
77 {
78 /* mac handle */
79 NULL, //to be filled in
80 4,
81 /*nwalSaIpSecParam_t */
82 {
83 0,/* validParams */
84 nwal_SA_MODE_TUNNEL, //update from input
85 64,/* replayWindow */\
86 NWAL_SA_DIR_INBOUND,
87 0,
88 0,
89 NWAL_SA_AALG_HMAC_SHA1,/* update from input */
90 NWAL_SA_EALG_AES_CTR, /* update from input */
91 { 0x00}, /* remMacAddr: NA */
92 12, /* update from input, mac size */
93 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,/* Continue parsing to next route for match */
94 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,/* For next route fail action by default is route to host */
95 CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */
96 QMSS_PARAM_NOT_SPECIFIED, /* Use default queue configured to NWAL if packet is routed to host */
97 0 /* route type */
98 },
99 /* nwalSaIpSecKeyParams_t */
100 {0}
101 };
104 void * mac_handle = netapip_netcpCfgGetMacHandle(&netapi_get_global()->nwal_context,iface_no);
105 *perr =NETAPI_ERR_OK;
106 if ((!n) || (!sa_info) || (!p_data_mode_handle))
107 {
108 *perr = NETAPI_ERR_BAD_INPUT;
109 return -1;
110 }
112 /* prior to building table, will need to store SA entry in local database,
113 * and make sure this SA has not been already offloaded, if already off-loaded,
114 * just return app_id associated with the SA */
116 for(sa_db_slot=0; sa_db_slot < TUNE_NETAPI_MAX_SA; sa_db_slot++)
117 {
118 if (netapi_sa_db[sa_db_slot].inUse)
119 {
120 if (sa_info->ipType == nwal_IPV4)
121 {
122 if (netapi_sa_db[sa_db_slot].spi != sa_info->spi)
123 continue;
124 if(memcmp(&netapi_sa_db[sa_db_slot].dst.ipv4,
125 &sa_info->dst.ipv4, sizeof(sa_info->dst.ipv4)))
126 continue;
128 netapi_sa_db[sa_db_slot].ref_count++;
129 return netapi_sa_db[sa_db_slot].app_id;
130 }
131 else if (sa_info->ipType == nwal_IPV6)
132 {
133 if (netapi_sa_db[sa_db_slot].spi != sa_info->spi)
134 continue;
135 if(memcmp(&netapi_sa_db[sa_db_slot].dst.ipv6,
136 &sa_info->dst.ipv6, sizeof(sa_info->dst.ipv6)))
137 continue;
139 netapi_sa_db[sa_db_slot].ref_count++;
140 return netapi_sa_db[sa_db_slot].app_id;
141 }
142 else
143 {
144 *perr = NETAPI_ERR_BAD_INPUT;
145 return -1;
146 }
147 }
148 else
149 {
150 /* found free slot */
151 free_sa_db_slot = sa_db_slot;
152 }
153 }
154 saInfo.spi = sa_info->spi;
156 memcpy(&saInfo.dst, &sa_info->dst, sizeof( nwalIpAddr_t));
158 /* reserve a slot */
159 tunnelId = netapip_netcpCfgFindSaSlot(n,
160 &netapi_get_global()->nwal_context,
161 iface_no);
163 if (tunnelId <0)
164 {
165 *perr= NETAPI_ERR_NOMEM;
166 return -1;
167 }
168 appId |= (tunnelId << NETAPI_NETCP_MATCH_ID_SHIFT);
170 *p_data_mode_handle= NULL;
171 *p_inflow_mode_handle= NULL;
175 if (inflow_mode & NETAPI_SEC_SA_INFLOW)
176 {
177 pTransInfo = netapip_getFreeTransInfo(n,
178 (NETAPI_PROC_GLOBAL_T *) n->proc_global,
179 &trans_id);
180 if (!pTransInfo)
181 {
182 *perr = NETAPI_ERR_BUSY;
183 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
184 return -1;
185 }
186 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
187 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
188 pTransInfo->inUse = nwal_TRUE;
189 pTransInfo->netapi_handle = h;
191 /* build SA parameters */
192 saInfo.spi = sa_info->spi;
193 memcpy(&saInfo.dst, &sa_info->dst, sizeof( nwalIpAddr_t));
194 memcpy(&saInfo.src, &sa_info->src, sizeof( nwalIpAddr_t));
195 saInfo.proto = sa_info->proto;
196 createParam.macHandle = mac_handle;
197 createParam.ipType = sa_info->ipType;
198 createParam.saIpSecParam.dir = sa_info->dir;
199 createParam.saIpSecParam.saMode = sa_info->saMode;
200 createParam.saIpSecParam.replayWindow = sa_info->replayWindow;
201 createParam.saIpSecParam.authMode = sa_info->authMode;
202 createParam.saIpSecParam.cipherMode = sa_info->cipherMode;
203 createParam.saIpSecParam.esnLo = sa_info->esnLo;
204 createParam.saIpSecParam.esnHi = sa_info->esnHi;
205 if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
206 (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
207 (sa_info->authMode == NWAL_SA_AALG_GMAC) ||
208 (sa_info->authMode == NWAL_SA_AALG_HMAC_SHA2_256) ||
209 (sa_info->authMode == NWAL_SA_AALG_HMAC_SHA2_256_RFC4868))
210 {
211 createParam.saIpSecParam.macSize = 16;
212 }
213 if ((sa_info->authMode == NWAL_SA_AALG_NULL) &&
214 (!((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
215 (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM))))
216 {
217 createParam.saIpSecParam.replayWindow = 0;
218 createParam.saIpSecParam.macSize = 0;
219 }
220 memcpy(&createParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
222 if (route != NULL)
223 {
224 if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
225 NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
226 {
227 createParam.saIpSecParam.validParams |=
228 NWAL_SA_INFO_VALID_PARAM_ROUTE_TYPE;
229 }
230 netapip_netcpCfgBuildRoute(route,
231 &createParam.saIpSecParam.appRxPktFlowId,
232 &createParam.saIpSecParam.appRxPktQueue,
233 &createParam.saIpSecParam.routeType);
234 }
236 /* fire off config message */
237 retValue = nwal_setSecAssoc (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
238 trans_id,
239 (nwal_AppId) appId,
240 &saInfo,
241 &createParam,
242 &pTransInfo->handle);
243 if(retValue == nwal_TRANS_COMPLETE)
244 {
245 have_to_wait=0;
246 }
247 else if(retValue != nwal_OK)
248 {
249 *perr = NETAPI_ERR_NWAL_ERR0;
250 netapip_freeTransInfo(pTransInfo);
251 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
252 return -1;
253 }
255 if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
256 {
257 n->nwal_local.numPendingCfg++;
258 while ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
259 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
260 {
261 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
262 }
263 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
264 {
265 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
266 pTransInfo->inUse = nwal_FALSE;
267 *perr = NETAPI_ERR_PA_FW;
268 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
269 return -1;
270 }
271 }
273 *p_inflow_mode_handle=pTransInfo->handle;
274 netapip_freeTransInfo(pTransInfo);
276 if (sa_info->dir == NWAL_SA_DIR_OUTBOUND)
277 {
278 memset(&nwalSaIpSecId, 0, sizeof(nwalSaIpSecId_t));
279 nwalSaIpSecId.spi = sa_info->spi;
280 memcpy(&(nwalSaIpSecId.src), &sa_info->src,sizeof( nwalIpAddr_t));
281 memcpy(&(nwalSaIpSecId.dst), &sa_info->dst,sizeof( nwalIpAddr_t));
282 nwalSaIpSecId.proto = sa_info->proto;
283 if (nwal_getSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
284 &nwalSaIpSecId,
285 NWAL_SA_DIR_OUTBOUND,
286 p_inflow_mode_handle,
287 &swInfo0,
288 &swInfo1) != nwal_TRUE)
289 netapi_Log("netapisecAddSA: call to nwal_getSecAssoc() returned error\n");
290 }
291 }
293 /* sideband mode */
294 if (inflow_mode &NETAPI_SEC_SA_SIDEBAND)
295 {
296 nwalCreateDmSAParams_t dmSaParam;
297 void * dm_handle;
298 memset(&dmSaParam,0,sizeof(nwalCreateDmSAParams_t));
299 dmSaParam.dmSaParam.dmChnType= (sa_info->dir==NWAL_SA_DIR_INBOUND)? NWAL_DM_CHAN_DECRYPT: NWAL_DM_CHAN_ENCRYPT; /**direction*/
300 dmSaParam.dmSaParam.replayWindow=sa_info->replayWindow;
301 dmSaParam.dmSaParam.authMode=sa_info->authMode;
302 dmSaParam.dmSaParam.cipherMode=sa_info->cipherMode;
303 dmSaParam.dmSaParam.macSize=12;
304 dmSaParam.dmSaParam.aadSize=0;
305 dmSaParam.dmSaParam.enc1st = (sa_info->dir ==NWAL_SA_DIR_OUTBOUND) ? nwal_TRUE : nwal_FALSE; //encypt 1st for outbound
306 if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
307 (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
308 (sa_info->authMode == NWAL_SA_AALG_GMAC))
309 {
310 dmSaParam.dmSaParam.macSize = 16;
311 dmSaParam.dmSaParam.aadSize=8;
312 /* Enc1st needs to always be true for combined mode algorithms */
313 dmSaParam.dmSaParam.enc1st = nwal_TRUE;
314 }
315 else
316 {
317 dmSaParam.dmSaParam.macSize=12;
318 dmSaParam.dmSaParam.aadSize=0;
319 }
321 if (sa_info->authMode == NWAL_SA_AALG_NULL)
322 {
323 dmSaParam.dmSaParam.enc1st = nwal_TRUE;
324 }
325 /* todo; allow app q for Sideband return */
326 memcpy(&dmSaParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
327 retValue = nwal_setDMSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
328 (nwal_AppId)appId,
329 &dmSaParam,
330 &dm_handle);
331 if(retValue != nwal_OK)
332 {
333 *perr = NETAPI_ERR_NWAL_ERR0;
334 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
335 return -1;
336 }
338 *p_data_mode_handle = dm_handle;
339 memset(&dmPSCmdInfo, 0, sizeof(nwalTxDmPSCmdInfo_t));
340 retValue = nwal_initDMPSCmdInfo(netapip_returnNwalInstanceHandle(h),
341 *p_data_mode_handle,
342 &dmPSCmdInfo);
343 }
345 netapip_netcpCfgInsertSa(&netapi_get_global()->nwal_context,
346 tunnelId,
347 (sa_info->dir == NWAL_SA_DIR_INBOUND) ? NETAPI_TRUE: NETAPI_FALSE,
348 inflow_mode,
349 &saInfo,
350 &createParam,
351 *p_inflow_mode_handle,
352 *p_data_mode_handle,
353 &dmPSCmdInfo,
354 swInfo0,
355 swInfo1,
356 p_user_data);
357 netapi_sa_db[free_sa_db_slot].app_id = appId;
358 netapi_sa_db[free_sa_db_slot].inUse = 1;
359 netapi_sa_db[free_sa_db_slot].spi = sa_info->spi;
360 netapi_sa_db[free_sa_db_slot].ref_count++;
361 memcpy(&(netapi_sa_db[free_sa_db_slot].dst), &sa_info->dst,sizeof( nwalIpAddr_t));
362 return (appId);
363 }
365 /********************************************************************
366 * FUNCTION PURPOSE: Internal function to dynamically switch between inflow
367 * and sideband mode
368 ********************************************************************
369 * DESCRIPTION: Internal function to dynamically switch between inflow
370 * and sideband mode
371 ********************************************************************/
372 void netapi_secInflowMode(int iface,
373 NETCP_CFG_SA_T sa,
374 int on)
375 {
376 /* NOT_IMPLEMENTED */
377 }
379 /********************************************************************
380 * FUNCTION PURPOSE: Internal function to delete an IPSEC SA
381 ********************************************************************
382 * DESCRIPTION: Internal function to delete an IPSEC SA
383 ********************************************************************/
384 static void netapi_secDelSA_internal(NETAPI_T h,
385 int iface_no,
386 NETCP_CFG_SA_T sa_app_id,
387 int flags,
388 int *perr)
389 {
390 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
391 nwal_RetValue retValue;
392 NetapiNwalTransInfo_t *pTransInfo;
393 nwal_TransID_t trans_id;
394 int tunnelId = (sa_app_id >> NETAPI_NETCP_MATCH_ID_SHIFT) &NETAPI_NETCP_MATCH_ID_MASK;
395 void * handle_inflow;
396 void * handle_sideband;
397 int have_to_wait = 1;
398 int sa_db_slot;
400 *perr =0;
401 for(sa_db_slot=0; sa_db_slot < TUNE_NETAPI_MAX_SA; sa_db_slot++)
402 {
403 if((netapi_sa_db[sa_db_slot].inUse) &&
404 (netapi_sa_db[sa_db_slot].app_id == sa_app_id))
405 {
406 if(!netapi_sa_db[sa_db_slot].ref_count)
407 {
408 *perr = NETAPI_ERR_NOTFOUND;
409 return;
410 }
411 netapi_sa_db[sa_db_slot].ref_count--;
412 if(netapi_sa_db[sa_db_slot].ref_count)
413 {
414 return;
415 }
416 else
417 {
418 netapi_sa_db[sa_db_slot].inUse = 0;
419 break;
420 }
421 }
422 }
423 handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
424 tunnelId, &handle_sideband);
427 if(handle_inflow)
428 {
429 /* get a transaction id */
430 pTransInfo = netapip_getFreeTransInfo(n,
431 (NETAPI_PROC_GLOBAL_T *) n->proc_global,
432 &trans_id);
433 if (!pTransInfo)
434 {
435 *perr = NETAPI_ERR_BUSY;
436 return;
437 }
438 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
439 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
440 pTransInfo->inUse = nwal_TRUE;
441 pTransInfo->netapi_handle = h;
443 retValue = nwal_delSecAssoc(
444 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
445 trans_id,
446 handle_inflow);
447 if(retValue == nwal_TRANS_COMPLETE)
448 {
449 have_to_wait=0;
450 }
451 else if(retValue != nwal_OK)
452 {
453 *perr = NETAPI_ERR_NWAL_ERR0;
454 netapip_freeTransInfo(pTransInfo);
455 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
456 }
457 if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
458 {
459 n->nwal_local.numPendingCfg++;
461 while ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
462 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
463 {
464 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
465 }
466 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
467 {
468 netapip_freeTransInfo(pTransInfo);
469 *perr = NETAPI_ERR_PA_FW;
470 if (!flags)
471 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context, tunnelId);
472 return;
473 }
474 }
475 netapip_freeTransInfo(pTransInfo);
476 }
477 if (handle_sideband)
478 {
479 retValue=nwal_delDMSecAssoc( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
480 handle_sideband);
481 if(retValue != nwal_OK)
482 {
483 *perr = NETAPI_ERR_NWAL_ERR0;
484 }
485 }
487 /* zap the entry */
488 if (!flags)
489 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context, tunnelId);
490 }
492 /********************************************************************
493 * FUNCTION PURPOSE: API to delete an IPSEC SA
494 ********************************************************************
495 * DESCRIPTION: API to delete an IPSEC SA
496 ********************************************************************/
497 void netapi_secDelSA(NETAPI_T h,
498 int iface_no,
499 NETCP_CFG_SA_T sa_app_id,
500 int *perr)
501 {
502 netapi_secDelSA_internal( h, iface_no, sa_app_id, 0x00, perr);
503 }
506 /********************************************************************
507 * FUNCTION PURPOSE: API to add a receive security policy
508 ********************************************************************
509 * DESCRIPTION: API to add a receive security policy
510 ********************************************************************/
511 NETCP_CFG_IPSEC_POLICY_T netapi_secAddRxPolicy(NETAPI_T h,
512 NETCP_CFG_SA_T sa,
513 nwal_IpType ipType,
514 nwalIpAddr_t * src_ip_addr,
515 nwalIpAddr_t * dst_ip_addr,
516 nwalIpOpt_t * ip_qualifiers,
517 NETCP_CFG_ROUTE_HANDLE_T route,
518 void * user_data,
519 int * perr)
520 {
521 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
522 nwal_RetValue retValue;
523 NetapiNwalTransInfo_t *pTransInfo;
524 nwal_TransID_t trans_id;
525 unsigned int appId = NETAPI_NETCP_MATCH_IPSEC_POLICY;
526 int policyId;
527 int tunnelId= netapi_cfgGetMatchId(sa);
528 void * blah;
529 int iface_no = netapi_cfgGetMatchLogicalMacIface(sa);
531 nwalSecPolParams_t createParam =
532 {
533 0, /* handle */
534 0, /* valid params */
535 NWAL_SA_DIR_INBOUND,
536 4, /* IP Type */
537 {0}, /* dst */
538 {0}, /* src */
539 {0 },/* IP Options */
540 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */
541 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */
542 CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */
543 QMSS_PARAM_NOT_SPECIFIED, /* Use default queue configured to NWAL if packet is routed to host */
544 0 /* Optional: route type */
545 };
547 void * sa_handle = NULL;
548 *perr =0;
550 if ((!n) )
551 {
552 *perr = NETAPI_ERR_BAD_INPUT;
553 return -1;
554 }
556 sa_handle = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,tunnelId,&blah);
557 if (!sa_handle)
558 {
559 *perr = NETAPI_ERR_BAD_INPUT;
560 return -1;
561 }
563 /* get a transaction id */
564 pTransInfo = netapip_getFreeTransInfo(n,
565 (NETAPI_PROC_GLOBAL_T *) n->proc_global,
566 &trans_id);
567 if (!pTransInfo)
568 {
569 *perr = NETAPI_ERR_BUSY;
570 return -1;
571 }
572 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
573 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
574 pTransInfo->inUse = nwal_TRUE;
575 pTransInfo->netapi_handle = h;
576 createParam.handle = sa_handle;
577 createParam.ipType = ipType;
578 if (dst_ip_addr) memcpy(&createParam.dst, dst_ip_addr, sizeof(nwalIpAddr_t));
579 if (src_ip_addr) memcpy(&createParam.src, src_ip_addr, sizeof(nwalIpAddr_t));
580 if (ip_qualifiers) memcpy(&createParam.ipOpt,ip_qualifiers ,sizeof(nwalIpOpt_t));
581 if (route != NULL)
582 {
583 if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
584 NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
585 {
586 createParam.validParams |=
587 NWAL_SET_SEC_POLICY_VALID_PARAM_ROUTE_TYPE;
588 }
589 netapip_netcpCfgBuildRoute(route,
590 &createParam.appRxPktFlowId,
591 &createParam.appRxPktQueue,
592 &createParam.routeType);
593 }
594 /* reserve a slot */
595 policyId = netapip_netcpCfgFindPolicySlot(n,
596 &netapi_get_global()->nwal_context,
597 tunnelId);
598 if (policyId <0)
599 {
600 *perr= NETAPI_ERR_NOMEM;
601 netapip_freeTransInfo(pTransInfo);
602 return -1;
603 }
604 appId |= (policyId <<8);
606 /* fire off config message */
607 retValue = nwal_setSecPolicy (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
608 trans_id,
609 (nwal_AppId) appId,
610 &createParam,
611 &pTransInfo->handle);
612 if(retValue != nwal_OK)
613 {
614 *perr = NETAPI_ERR_NWAL_ERR0;
615 netapip_freeTransInfo(pTransInfo);
617 netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context,policyId);
618 return -1;
619 }
621 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
622 {
623 n->nwal_local.numPendingCfg++;
624 while ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
625 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
626 {
627 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
628 }
629 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
630 {
631 netapip_freeTransInfo(pTransInfo);
632 *perr = NETAPI_ERR_PA_FW;
633 netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context,policyId);
634 return -1;
635 }
636 }
638 /* save stuff */
639 netapip_netcpCfgInsertPolicy(&netapi_get_global()->nwal_context,
640 policyId,
641 (void *) pTransInfo->handle,
642 user_data);
643 netapip_freeTransInfo(pTransInfo);
644 return (appId);
645 }
647 /********************************************************************
648 * FUNCTION PURPOSE: Internal function to delete a receive security policy
649 ********************************************************************
650 * DESCRIPTION: Internal function to delete a receive security policy
651 ********************************************************************/
652 static void netapi_secDelRxPolicy_internal(NETAPI_T h,
653 NETCP_CFG_IPSEC_POLICY_T policy_app_id,
654 int flags,
655 int *perr)
656 {
657 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
658 nwal_RetValue retValue;
659 NetapiNwalTransInfo_t *pTransInfo;
660 nwal_TransID_t trans_id;
661 int policyId = netapi_cfgGetMatchId(policy_app_id);
662 void * handle_policy=NULL;
664 handle_policy = netapip_netcpCfgGetPolicy(&netapi_get_global()->nwal_context,policyId);
665 ;
666 if (!handle_policy)
667 {
668 *perr = NETAPI_ERR_BAD_INPUT;
669 goto ERR_netapi_secDelRxPolicy_internal;
670 }
671 *perr =0;
673 /* get a transaction id */
674 pTransInfo = netapip_getFreeTransInfo(n,
675 (NETAPI_PROC_GLOBAL_T *) n->proc_global,
676 &trans_id);
677 if (!pTransInfo)
678 {
679 *perr = NETAPI_ERR_BUSY;
680 goto ERR_netapi_secDelRxPolicy_internal;
681 }
682 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
683 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
684 pTransInfo->inUse = nwal_TRUE;
685 pTransInfo->netapi_handle = h;
687 /* issue request */
688 retValue = nwal_delSecPolicy(
689 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
690 trans_id,
691 handle_policy);
692 if(retValue != nwal_OK)
693 {
694 *perr = NETAPI_ERR_NWAL_ERR0;
695 netapip_freeTransInfo(pTransInfo);
696 goto ERR_netapi_secDelRxPolicy_internal;
697 }
699 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
700 {
701 n->nwal_local.numPendingCfg++;
702 while ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
703 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
704 {
705 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
706 }
707 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
708 {
709 netapip_freeTransInfo(pTransInfo);
710 *perr = NETAPI_ERR_PA_FW;
711 //zap the entry
712 if (!flags)
713 netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context, policyId);
714 goto ERR_netapi_secDelRxPolicy_internal;
716 }
717 }
718 netapip_freeTransInfo(pTransInfo);
719 /* zap the entry */
720 if (!flags)
721 {
722 netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context, policyId);
723 }
724 ERR_netapi_secDelRxPolicy_internal:
725 return;
726 }
728 /********************************************************************
729 * FUNCTION PURPOSE: API to delete a receive security policy
730 ********************************************************************
731 * DESCRIPTION: API to delete a receive security policy
732 ********************************************************************/
733 void netapi_secDelRxPolicy(NETAPI_T h,
734 NETCP_CFG_IPSEC_POLICY_T policy_app_id,
735 int *perr)
736 {
737 netapi_secDelRxPolicy_internal(h, policy_app_id, 0, perr);
738 }
740 /********************************************************************
741 * FUNCTION PURPOSE: API to retrieve SA statistics via NWAL
742 ********************************************************************
743 * DESCRIPTION: API to retrieve SA statistics via NWAL
744 ********************************************************************/
745 void netapi_getSaStats (NETAPI_T h,
746 NETCP_CFG_SA_T handle,
747 NETAPI_SA_STATS_T* pSaStats)
748 {
749 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
750 void * handle_inflow;
751 void * handle_sideband;
752 int tunnelId = (handle >> NETAPI_NETCP_MATCH_ID_SHIFT) &0xffff;
753 int have_to_wait = 1;
754 handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
755 tunnelId, &handle_sideband);
756 if(handle_inflow)
757 {
758 nwal_getSecAssocStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
759 handle_inflow, &(pSaStats->saIpsecStats));
760 pSaStats->validParams |= NETAPI_IPSEC_STAT_VALID;
761 }
762 if(handle_sideband)
763 {
764 nwal_getDataModeStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
765 handle_sideband, &(pSaStats->dataModeStats));
766 pSaStats->validParams |= NETAPI_SIDEBAND_DATA_MODE_STAT_VALID;
767 }
768 }
771 /**********************************************************************************
772 * FUNCTION PURPOSE: API to API to retrieve local channel context information
773 **********************************************************************************
774 * DESCRIPTION: API to retrieve API to retrieve local channel context information
775 *********************************************************************************/
776 void netapi_secGetChanCtxInfo(NETAPI_T h,
777 NETCP_CFG_APP_ID_T appId,
778 nwalChanCxtInfo_t* pInfo)
779 {
781 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
782 void * handle_inflow;
783 void * handle_sideband = NULL;
784 void * handle_policy=NULL;
785 nwalChanCxtInfo_t info;
786 uint32_t stage = 0;
787 int policyId;
788 int tunnelId;
790 if(!pInfo)
791 return;
792 memset(pInfo, 0, sizeof(nwalChanCxtInfo_t));
794 stage = netapi_cfgGetMatchStage(appId);
796 switch (stage)
797 {
798 case 1:
799 /* this is for SA, need SA and OUTER IP handle */
800 tunnelId = netapi_cfgGetMatchId(appId);
801 handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
802 tunnelId, &handle_sideband);
803 if(handle_inflow)
804 {
805 nwal_getChanCxtInfo(&netapi_get_global()->nwal_context,
806 handle_inflow,
807 pInfo);
808 }
809 break;
810 case 2:
811 /* this is for policy, need SA inner IP */
812 policyId = netapi_cfgGetMatchId(appId);
813 handle_policy = netapip_netcpCfgGetPolicy(&netapi_get_global()->nwal_context,
814 policyId);
815 if (handle_policy)
816 {
817 nwal_getChanCxtInfo(&netapi_get_global()->nwal_context,
818 handle_policy,
819 pInfo);
820 }
821 break;
822 default:
823 break;
824 }
825 return;
826 }