Line data Source code
1 : /*
2 : * Copyright (c) 2015 Cisco and/or its affiliates.
3 : * Licensed under the Apache License, Version 2.0 (the "License");
4 : * you may not use this file except in compliance with the License.
5 : * You may obtain a copy of the License at:
6 : *
7 : * http://www.apache.org/licenses/LICENSE-2.0
8 : *
9 : * Unless required by applicable law or agreed to in writing, software
10 : * distributed under the License is distributed on an "AS IS" BASIS,
11 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : * See the License for the specific language governing permissions and
13 : * limitations under the License.
14 : */
15 : #ifndef __included_ikev2_priv_h__
16 : #define __included_ikev2_priv_h__
17 :
18 : #include <vnet/vnet.h>
19 : #include <vnet/ip/ip.h>
20 : #include <vnet/ethernet/ethernet.h>
21 :
22 : #include <plugins/ikev2/ikev2.h>
23 :
24 : #include <vppinfra/hash.h>
25 : #include <vppinfra/elog.h>
26 : #include <vppinfra/error.h>
27 :
28 : #include <openssl/rand.h>
29 : #include <openssl/dh.h>
30 : #include <openssl/hmac.h>
31 : #include <openssl/evp.h>
32 :
33 : #define foreach_ikev2_log_level \
34 : _(0x00, LOG_NONE) \
35 : _(0x01, LOG_ERROR) \
36 : _(0x02, LOG_WARNING) \
37 : _(0x03, LOG_INFO) \
38 : _(0x04, LOG_DEBUG) \
39 : _(0x05, LOG_DETAIL) \
40 :
41 :
42 : typedef enum ikev2_log_level_t_
43 : {
44 : #define _(n,f) IKEV2_##f = n,
45 : foreach_ikev2_log_level
46 : #undef _
47 : IKEV2_LOG_MAX
48 : } ikev2_log_level_t;
49 :
50 : /* dataplane logging */
51 : #define _ikev2_elog(_level, _msg) \
52 : do { \
53 : ikev2_main_t *km = &ikev2_main; \
54 : if (PREDICT_FALSE (km->log_level >= _level)) \
55 : { \
56 : ELOG_TYPE_DECLARE (e) = \
57 : { \
58 : .format = "ikev2 " _msg, \
59 : .format_args = "", \
60 : }; \
61 : ELOG_DATA (&vlib_global_main.elog_main, e); \
62 : } \
63 : } while (0)
64 :
65 : #define ikev2_elog_sa_state(_format, _ispi) \
66 : do { \
67 : ikev2_main_t *km = &ikev2_main; \
68 : if (PREDICT_FALSE (km->log_level >= IKEV2_LOG_DEBUG)) \
69 : { \
70 : ELOG_TYPE_DECLARE (e) = \
71 : { \
72 : .format = "ikev2: " _format, \
73 : .format_args = "i8", \
74 : }; \
75 : CLIB_PACKED(struct \
76 : { \
77 : u64 ispi; \
78 : }) *ed; \
79 : ed = ELOG_DATA (&vlib_global_main.elog_main, e); \
80 : ed->ispi = _ispi; \
81 : } \
82 : } while (0) \
83 :
84 : #define ikev2_elog_exchange_internal(_format, _ispi, _rspi, _addr) \
85 : do { \
86 : ikev2_main_t *km = &ikev2_main; \
87 : if (PREDICT_FALSE (km->log_level >= IKEV2_LOG_DEBUG)) \
88 : { \
89 : ELOG_TYPE_DECLARE (e) = \
90 : { \
91 : .format = "ikev2: " _format, \
92 : .format_args = "i8i8i1i1i1i1", \
93 : }; \
94 : CLIB_PACKED(struct \
95 : { \
96 : u64 ispi; \
97 : u64 rspi; \
98 : u8 oct1; \
99 : u8 oct2; \
100 : u8 oct3; \
101 : u8 oct4; \
102 : }) *ed; \
103 : ed = ELOG_DATA (&vlib_global_main.elog_main, e); \
104 : ed->ispi = _ispi; \
105 : ed->rspi = _rspi; \
106 : ed->oct4 = (_addr) >> 24; \
107 : ed->oct3 = (_addr) >> 16; \
108 : ed->oct2 = (_addr) >> 8; \
109 : ed->oct1 = (_addr); \
110 : } \
111 : } while (0) \
112 :
113 : #define IKE_ELOG_IP4_FMT "%d.%d.%d.%d"
114 : #define IKE_ELOG_IP6_FMT "[v6]:%x%x:%x%x"
115 :
116 : #define ikev2_elog_exchange(_fmt, _ispi, _rspi, _addr, _v4) \
117 : do { \
118 : if (_v4) \
119 : ikev2_elog_exchange_internal (_fmt IKE_ELOG_IP4_FMT, _ispi, _rspi, _addr);\
120 : else \
121 : ikev2_elog_exchange_internal (_fmt IKE_ELOG_IP6_FMT, _ispi, _rspi, _addr);\
122 : } while (0)
123 :
124 : #define ikev2_elog_uint(_level, _format, _val) \
125 : do { \
126 : ikev2_main_t *km = &ikev2_main; \
127 : if (PREDICT_FALSE (km->log_level >= _level)) \
128 : { \
129 : ELOG_TYPE_DECLARE (e) = \
130 : { \
131 : .format = "ikev2: " _format, \
132 : .format_args = "i8", \
133 : }; \
134 : CLIB_PACKED(struct \
135 : { \
136 : u64 val; \
137 : }) *ed; \
138 : ed = ELOG_DATA (&vlib_global_main.elog_main, e); \
139 : ed->val = _val; \
140 : } \
141 : } while (0)
142 :
143 : #define ikev2_elog_uint_peers(_level, _format, _val, _ip1, _ip2) \
144 : do { \
145 : ikev2_main_t *km = &ikev2_main; \
146 : if (PREDICT_FALSE (km->log_level >= _level)) \
147 : { \
148 : ELOG_TYPE_DECLARE (e) = \
149 : { \
150 : .format = "ikev2: " _format, \
151 : .format_args = "i8i1i1i1i1i1i1i1i1", \
152 : }; \
153 : CLIB_PACKED(struct { \
154 : u64 val; \
155 : u8 i11; u8 i12; u8 i13; u8 i14; \
156 : u8 i21; u8 i22; u8 i23; u8 i24; }) *ed; \
157 : ed = ELOG_DATA (&vlib_global_main.elog_main, e); \
158 : ed->val = _val; \
159 : ed->i14 = (_ip1) >> 24; \
160 : ed->i13 = (_ip1) >> 16; \
161 : ed->i12 = (_ip1) >> 8; \
162 : ed->i11 = (_ip1); \
163 : ed->i24 = (_ip2) >> 24; \
164 : ed->i23 = (_ip2) >> 16; \
165 : ed->i22 = (_ip2) >> 8; \
166 : ed->i21 = (_ip2); \
167 : } \
168 : } while (0)
169 :
170 : #define ikev2_elog_error(_msg) \
171 : _ikev2_elog(IKEV2_LOG_ERROR, "[error] " _msg)
172 : #define ikev2_elog_warning(_msg) \
173 : _ikev2_elog(IKEV2_LOG_WARNING, "[warning] " _msg)
174 : #define ikev2_elog_debug(_msg) \
175 : _ikev2_elog(IKEV2_LOG_DEBUG, "[debug] " _msg)
176 : #define ikev2_elog_detail(_msg) \
177 : _ikev2_elog(IKEV2_LOG_DETAIL, "[detail] " _msg)
178 :
179 : /* logging for main thread */
180 : #define ikev2_log_error(...) \
181 : vlib_log(VLIB_LOG_LEVEL_ERR, ikev2_main.log_class, __VA_ARGS__)
182 : #define ikev2_log_warning(...) \
183 : vlib_log(VLIB_LOG_LEVEL_WARNING, ikev2_main.log_class, __VA_ARGS__)
184 : #define ikev2_log_debug(...) \
185 : vlib_log(VLIB_LOG_LEVEL_DEBUG, ikev2_main.log_class, __VA_ARGS__)
186 :
187 : #define foreach_ikev2_state \
188 : _ (0, UNKNOWN, "UNKNOWN") \
189 : _ (1, SA_INIT, "SA_INIT") \
190 : _ (2, DELETED, "DELETED") \
191 : _ (3, AUTH_FAILED, "AUTH_FAILED") \
192 : _ (4, AUTHENTICATED, "AUTHENTICATED") \
193 : _ (5, NOTIFY_AND_DELETE, "NOTIFY_AND_DELETE") \
194 : _ (6, TS_UNACCEPTABLE, "TS_UNACCEPTABLE") \
195 : _ (7, NO_PROPOSAL_CHOSEN, "NO_PROPOSAL_CHOSEN")
196 :
197 : typedef enum
198 : {
199 : #define _(v, f, s) IKEV2_STATE_##f = v,
200 : foreach_ikev2_state
201 : #undef _
202 : } ikev2_state_t;
203 :
204 : typedef struct
205 : {
206 : ikev2_auth_method_t method:8;
207 : u8 *data;
208 : u8 hex; /* hex encoding of the shared secret */
209 : EVP_PKEY *key;
210 : } ikev2_auth_t;
211 :
212 : typedef enum
213 : {
214 : IKEV2_DH_GROUP_MODP = 0,
215 : IKEV2_DH_GROUP_ECP = 1,
216 : } ikev2_dh_group_t;
217 :
218 : typedef struct
219 : {
220 : ikev2_transform_type_t type;
221 : union
222 : {
223 : u16 transform_id;
224 : ikev2_transform_encr_type_t encr_type:16;
225 : ikev2_transform_prf_type_t prf_type:16;
226 : ikev2_transform_integ_type_t integ_type:16;
227 : ikev2_transform_dh_type_t dh_type:16;
228 : ikev2_transform_esn_type_t esn_type:16;
229 : };
230 : u8 *attrs;
231 : u16 key_len;
232 : u16 key_trunc;
233 : u16 block_size;
234 : u8 dh_group;
235 : int nid;
236 : const char *dh_p;
237 : const char *dh_g;
238 : const void *md;
239 : const void *cipher;
240 : } ikev2_sa_transform_t;
241 :
242 : typedef struct
243 : {
244 : u8 proposal_num;
245 : ikev2_protocol_id_t protocol_id:8;
246 : u32 spi;
247 : ikev2_sa_transform_t *transforms;
248 : } ikev2_sa_proposal_t;
249 :
250 : typedef struct
251 : {
252 : ikev2_traffic_selector_type_t ts_type;
253 : u8 protocol_id;
254 : u16 selector_len;
255 : u16 start_port;
256 : u16 end_port;
257 : ip_address_t start_addr;
258 : ip_address_t end_addr;
259 : } ikev2_ts_t;
260 :
261 : typedef struct
262 : {
263 : u32 sw_if_index;
264 : ip_address_t addr;
265 : u8 *hostname;
266 : u8 is_resolved;
267 : } ikev2_responder_t;
268 :
269 : typedef struct
270 : {
271 : ikev2_transform_encr_type_t crypto_alg;
272 : ikev2_transform_integ_type_t integ_alg;
273 : ikev2_transform_dh_type_t dh_type;
274 : u32 crypto_key_size;
275 : } ikev2_transforms_set;
276 :
277 :
278 : typedef struct
279 : {
280 : ikev2_id_type_t type:8;
281 : u8 *data;
282 : } ikev2_id_t;
283 :
284 : typedef struct
285 : {
286 : /* sa proposals vectors */
287 : ikev2_sa_proposal_t *i_proposals;
288 : ikev2_sa_proposal_t *r_proposals;
289 :
290 : /* Traffic Selectors */
291 : ikev2_ts_t *tsi;
292 : ikev2_ts_t *tsr;
293 :
294 : /* keys */
295 : u8 *sk_ai;
296 : u8 *sk_ar;
297 : u8 *sk_ei;
298 : u8 *sk_er;
299 : u32 salt_ei;
300 : u32 salt_er;
301 :
302 : /* installed data */
303 : u32 local_sa_id;
304 : u32 remote_sa_id;
305 :
306 : /* lifetime data */
307 : f64 time_to_expiration;
308 : u8 is_expired;
309 : i8 rekey_retries;
310 : } ikev2_child_sa_t;
311 :
312 : typedef struct
313 : {
314 : u8 protocol_id;
315 : u32 spi; /*for ESP and AH SPI size is 4, for IKE size is 0 */
316 : } ikev2_delete_t;
317 :
318 : typedef struct
319 : {
320 : u16 notify_type;
321 : u8 kex;
322 : u8 protocol_id;
323 : u32 spi;
324 : u32 ispi;
325 : ikev2_sa_proposal_t *i_proposal;
326 : ikev2_sa_proposal_t *r_proposal;
327 : ikev2_ts_t *tsi;
328 : ikev2_ts_t *tsr;
329 : } ikev2_rekey_t;
330 :
331 : typedef struct
332 : {
333 : u16 msg_type;
334 : u8 protocol_id;
335 : u32 spi;
336 : u8 *data;
337 : } ikev2_notify_t;
338 :
339 : typedef struct
340 : {
341 : u8 *name;
342 :
343 : ikev2_auth_t auth;
344 : ikev2_id_t loc_id;
345 : ikev2_id_t rem_id;
346 : ikev2_ts_t loc_ts;
347 : ikev2_ts_t rem_ts;
348 : ikev2_responder_t responder;
349 : ikev2_transforms_set ike_ts;
350 : ikev2_transforms_set esp_ts;
351 : u64 lifetime;
352 : u64 lifetime_maxdata;
353 : u32 lifetime_jitter;
354 : u32 handover;
355 : u16 ipsec_over_udp_port;
356 :
357 : u32 tun_itf;
358 : u8 udp_encap;
359 : u8 natt_disabled;
360 : } ikev2_profile_t;
361 :
362 : typedef enum
363 : {
364 : /* SA will switch to port 4500 when NAT is detected.
365 : * This is the default. */
366 : IKEV2_NATT_ENABLED,
367 :
368 : /* Do nothing when NAT is detected */
369 : IKEV2_NATT_DISABLED,
370 :
371 : /* NAT was detected and port switched to 4500 */
372 : IKEV2_NATT_ACTIVE,
373 : } ikev2_natt_state_t;
374 :
375 : #define ikev2_natt_active(_sa) ((_sa)->natt_state == IKEV2_NATT_ACTIVE)
376 :
377 : typedef struct
378 : {
379 : u16 n_keepalives;
380 : u16 n_rekey_req;
381 : u16 n_sa_auth_req;
382 : u16 n_sa_init_req;
383 : u16 n_init_retransmit;
384 : u16 n_retransmit;
385 : } ikev2_stats_t;
386 :
387 : typedef struct
388 : {
389 : ikev2_state_t state;
390 : u8 unsupported_cp;
391 : u8 initial_contact;
392 : ip_address_t iaddr;
393 : ip_address_t raddr;
394 : u64 ispi;
395 : u64 rspi;
396 : u8 *i_nonce;
397 : u8 *r_nonce;
398 :
399 : /* DH data */
400 : u16 dh_group;
401 : u8 *dh_shared_key;
402 : u8 *dh_private_key;
403 : u8 *i_dh_data;
404 : u8 *r_dh_data;
405 :
406 : /* sa proposals vectors */
407 : ikev2_sa_proposal_t *i_proposals;
408 : ikev2_sa_proposal_t *r_proposals;
409 :
410 : /* keys */
411 : u8 *sk_d;
412 : u8 *sk_ai;
413 : u8 *sk_ar;
414 : u8 *sk_ei;
415 : u8 *sk_er;
416 : u8 *sk_pi;
417 : u8 *sk_pr;
418 :
419 : /* auth */
420 : ikev2_auth_t i_auth;
421 : ikev2_auth_t r_auth;
422 :
423 : /* ID */
424 : ikev2_id_t i_id;
425 : ikev2_id_t r_id;
426 :
427 : /* pending deletes */
428 : ikev2_delete_t *del;
429 :
430 : /* pending rekeyings */
431 : ikev2_rekey_t *rekey;
432 :
433 : ikev2_rekey_t *new_child;
434 :
435 : /* packet data */
436 : u8 *last_sa_init_req_packet_data;
437 : u8 *last_sa_init_res_packet_data;
438 :
439 : /* retransmit */
440 : /* message id expected in the request from the other peer */
441 : u32 last_msg_id;
442 : u8 *last_res_packet_data;
443 :
444 : u8 is_initiator;
445 : /* last message id that was used for an initiated request */
446 : u32 last_init_msg_id;
447 : u32 profile_index;
448 : u8 is_tun_itf_set;
449 : u32 tun_itf;
450 : u8 udp_encap;
451 : u16 ipsec_over_udp_port;
452 :
453 : f64 old_id_expiration;
454 : u32 current_remote_id_mask;
455 : u32 old_remote_id;
456 : u8 old_remote_id_present;
457 : u8 init_response_received;
458 :
459 : ikev2_child_sa_t *childs;
460 :
461 : u8 liveness_retries;
462 : f64 liveness_period_check;
463 :
464 : u16 dst_port;
465 : u32 sw_if_index;
466 :
467 : /* is NAT traversal mode */
468 : ikev2_natt_state_t natt_state;
469 : u8 keys_generated;
470 :
471 : ikev2_stats_t stats;
472 : } ikev2_sa_t;
473 :
474 :
475 : typedef struct
476 : {
477 : CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
478 :
479 : /* pool of IKEv2 Security Associations */
480 : ikev2_sa_t *sas;
481 :
482 : /* hash */
483 : uword *sa_by_rspi;
484 :
485 : EVP_CIPHER_CTX *evp_ctx;
486 : HMAC_CTX *hmac_ctx;
487 : #if OPENSSL_VERSION_NUMBER < 0x10100000L
488 : HMAC_CTX _hmac_ctx;
489 : EVP_CIPHER_CTX _evp_ctx;
490 : #endif
491 : } ikev2_main_per_thread_data_t;
492 :
493 : typedef struct
494 : {
495 : /* pool of IKEv2 profiles */
496 : ikev2_profile_t *profiles;
497 :
498 : /* vector of supported transform types */
499 : ikev2_sa_transform_t *supported_transforms;
500 :
501 : /* hash */
502 : mhash_t profile_index_by_name;
503 :
504 : /* local private key */
505 : EVP_PKEY *pkey;
506 :
507 : /* convenience */
508 : vlib_main_t *vlib_main;
509 : vnet_main_t *vnet_main;
510 :
511 : /* pool of IKEv2 Security Associations created in initiator mode */
512 : ikev2_sa_t *sais;
513 : /* hash */
514 : uword *sa_by_ispi;
515 :
516 : ikev2_main_per_thread_data_t *per_thread_data;
517 :
518 : /* interface indices managed by IKE */
519 : uword *sw_if_indices;
520 :
521 : /* API message ID base */
522 : u16 msg_id_base;
523 :
524 : /* log class used for main thread */
525 : vlib_log_class_t log_class;
526 :
527 : /* logging level */
528 : ikev2_log_level_t log_level;
529 :
530 : /* how often a liveness check will be performed */
531 : u32 liveness_period;
532 :
533 : /* max number of retries before considering peer dead */
534 : u32 liveness_max_retries;
535 :
536 : /* dead peer detection */
537 : u8 dpd_disabled;
538 :
539 : /* pointer to name resolver function in dns plugin */
540 : void *dns_resolve_name_ptr;
541 :
542 : /* flag indicating whether lazy init is done or not */
543 : int lazy_init_done;
544 :
545 : /* refcount for IKEv2 udp ports and IPsec NATT punt registration */
546 : int bind_refcount;
547 :
548 : /* punt handle for IPsec NATT IPSEC_PUNT_IP4_SPI_UDP_0 reason */
549 : vlib_punt_hdl_t punt_hdl;
550 :
551 : } ikev2_main_t;
552 :
553 : extern ikev2_main_t ikev2_main;
554 :
555 : void ikev2_sa_free_proposal_vector (ikev2_sa_proposal_t ** v);
556 : ikev2_sa_transform_t *ikev2_sa_get_td_for_type (ikev2_sa_proposal_t * p,
557 : ikev2_transform_type_t type);
558 :
559 : /* ikev2_crypto.c */
560 : v8 *ikev2_calc_prf (ikev2_sa_transform_t * tr, v8 * key, v8 * data);
561 : u8 *ikev2_calc_prfplus (ikev2_sa_transform_t * tr, u8 * key, u8 * seed,
562 : int len);
563 : v8 *ikev2_calc_integr (ikev2_sa_transform_t * tr, v8 * key, u8 * data,
564 : int len);
565 : int ikev2_decrypt_data (ikev2_main_per_thread_data_t * ptd, ikev2_sa_t * sa,
566 : ikev2_sa_transform_t * tr_encr, u8 * data, int len,
567 : u32 * out_len);
568 : int ikev2_encrypt_data (ikev2_main_per_thread_data_t * ptd, ikev2_sa_t * sa,
569 : ikev2_sa_transform_t * tr_encr, v8 * src, u8 * dst);
570 : int ikev2_encrypt_aead_data (ikev2_main_per_thread_data_t * ptd,
571 : ikev2_sa_t * sa, ikev2_sa_transform_t * tr_encr,
572 : v8 * src, u8 * dst, u8 * aad,
573 : u32 aad_len, u8 * tag);
574 : int ikev2_decrypt_aead_data (ikev2_main_per_thread_data_t * ptd,
575 : ikev2_sa_t * sa, ikev2_sa_transform_t * tr_encr,
576 : u8 * data, int data_len, u8 * aad, u32 aad_len,
577 : u8 * tag, u32 * out_len);
578 : void ikev2_generate_dh (ikev2_sa_t * sa, ikev2_sa_transform_t * t);
579 : void ikev2_complete_dh (ikev2_sa_t * sa, ikev2_sa_transform_t * t);
580 : int ikev2_verify_sign (EVP_PKEY * pkey, u8 * sigbuf, u8 * data);
581 : u8 *ikev2_calc_sign (EVP_PKEY * pkey, u8 * data);
582 : EVP_PKEY *ikev2_load_cert_file (u8 * file);
583 : EVP_PKEY *ikev2_load_key_file (u8 * file);
584 : void ikev2_crypto_init (ikev2_main_t * km);
585 :
586 : /* ikev2_payload.c */
587 : typedef struct
588 : {
589 : u8 first_payload_type;
590 : u16 last_hdr_off;
591 : u8 *data;
592 : } ikev2_payload_chain_t;
593 :
594 : #define ikev2_payload_new_chain(V) vec_validate (V, 0)
595 : #define ikev2_payload_destroy_chain(V) do { \
596 : vec_free((V)->data); \
597 : vec_free(V); \
598 : } while (0)
599 :
600 : void ikev2_payload_add_notify (ikev2_payload_chain_t * c, u16 msg_type,
601 : u8 * data);
602 : void ikev2_payload_add_notify_2 (ikev2_payload_chain_t * c, u16 msg_type,
603 : u8 * data, ikev2_notify_t * notify);
604 : void ikev2_payload_add_sa (ikev2_payload_chain_t * c,
605 : ikev2_sa_proposal_t * proposals);
606 : void ikev2_payload_add_ke (ikev2_payload_chain_t * c, u16 dh_group,
607 : u8 * dh_data);
608 : void ikev2_payload_add_nonce (ikev2_payload_chain_t * c, u8 * nonce);
609 : void ikev2_payload_add_id (ikev2_payload_chain_t * c, ikev2_id_t * id,
610 : u8 type);
611 : void ikev2_payload_add_auth (ikev2_payload_chain_t * c, ikev2_auth_t * auth);
612 : void ikev2_payload_add_ts (ikev2_payload_chain_t * c, ikev2_ts_t * ts,
613 : u8 type);
614 : void ikev2_payload_add_delete (ikev2_payload_chain_t * c, ikev2_delete_t * d);
615 : void ikev2_payload_chain_add_padding (ikev2_payload_chain_t * c, int bs);
616 : void ikev2_parse_vendor_payload (ike_payload_header_t * ikep);
617 : ikev2_sa_proposal_t *ikev2_parse_sa_payload (ike_payload_header_t * ikep,
618 : u32 rlen);
619 : ikev2_ts_t *ikev2_parse_ts_payload (ike_payload_header_t * ikep, u32 rlen);
620 : ikev2_delete_t *ikev2_parse_delete_payload (ike_payload_header_t * ikep,
621 : u32 rlen);
622 : ikev2_notify_t *ikev2_parse_notify_payload (ike_payload_header_t * ikep,
623 : u32 rlen);
624 : int ikev2_set_log_level (ikev2_log_level_t log_level);
625 : u8 *ikev2_find_ike_notify_payload (ike_header_t * ike, u32 msg_type);
626 : void ikev2_disable_dpd (void);
627 : clib_error_t *ikev2_profile_natt_disable (u8 * name);
628 :
629 : static_always_inline ikev2_main_per_thread_data_t *
630 893 : ikev2_get_per_thread_data ()
631 : {
632 893 : u32 thread_index = vlib_get_thread_index ();
633 893 : return vec_elt_at_index (ikev2_main.per_thread_data, thread_index);
634 : }
635 : #endif /* __included_ikev2_priv_h__ */
636 :
637 :
638 : /*
639 : * fd.io coding-style-patch-verification: ON
640 : *
641 : * Local Variables:
642 : * eval: (c-set-style "gnu")
643 : * End:
644 : */
|