2 *------------------------------------------------------------------
3 * ipsec_api.c - ipsec api
5 * Copyright (c) 2016 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
20 #include <vnet/vnet.h>
21 #include <vlibmemory/api.h>
23 #include <vnet/interface.h>
24 #include <vnet/api_errno.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_types_api.h>
27 #include <vnet/ipsec/ipsec_types_api.h>
28 #include <vnet/tunnel/tunnel_types_api.h>
29 #include <vnet/fib/fib.h>
30 #include <vnet/ipip/ipip.h>
31 #include <vnet/tunnel/tunnel_types_api.h>
33 #include <vnet/vnet_msg_enum.h>
35 #include <vnet/ipsec/ipsec.h>
36 #include <vnet/ipsec/ipsec_tun.h>
37 #include <vnet/ipsec/ipsec_itf.h>
39 #define vl_typedefs /* define message structures */
40 #include <vnet/vnet_all_api_h.h>
43 #define vl_endianfun /* define message structures */
44 #include <vnet/vnet_all_api_h.h>
47 /* instantiate all the print functions we know about */
48 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
50 #include <vnet/vnet_all_api_h.h>
53 #include <vlibapi/api_helper_macros.h>
55 #define foreach_vpe_api_msg \
56 _ (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \
57 _ (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \
58 _ (IPSEC_SPD_ENTRY_ADD_DEL, ipsec_spd_entry_add_del) \
59 _ (IPSEC_SAD_ENTRY_ADD_DEL, ipsec_sad_entry_add_del) \
60 _ (IPSEC_SAD_ENTRY_ADD_DEL_V2, ipsec_sad_entry_add_del_v2) \
61 _ (IPSEC_SAD_ENTRY_ADD_DEL_V3, ipsec_sad_entry_add_del_v3) \
62 _ (IPSEC_SA_DUMP, ipsec_sa_dump) \
63 _ (IPSEC_SA_V2_DUMP, ipsec_sa_v2_dump) \
64 _ (IPSEC_SA_V3_DUMP, ipsec_sa_v3_dump) \
65 _ (IPSEC_SPDS_DUMP, ipsec_spds_dump) \
66 _ (IPSEC_SPD_DUMP, ipsec_spd_dump) \
67 _ (IPSEC_SPD_INTERFACE_DUMP, ipsec_spd_interface_dump) \
68 _ (IPSEC_ITF_CREATE, ipsec_itf_create) \
69 _ (IPSEC_ITF_DELETE, ipsec_itf_delete) \
70 _ (IPSEC_ITF_DUMP, ipsec_itf_dump) \
71 _ (IPSEC_SELECT_BACKEND, ipsec_select_backend) \
72 _ (IPSEC_BACKEND_DUMP, ipsec_backend_dump) \
73 _ (IPSEC_TUNNEL_PROTECT_UPDATE, ipsec_tunnel_protect_update) \
74 _ (IPSEC_TUNNEL_PROTECT_DEL, ipsec_tunnel_protect_del) \
75 _ (IPSEC_TUNNEL_PROTECT_DUMP, ipsec_tunnel_protect_dump) \
76 _ (IPSEC_SET_ASYNC_MODE, ipsec_set_async_mode)
79 vl_api_ipsec_spd_add_del_t_handler (vl_api_ipsec_spd_add_del_t * mp)
81 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
82 vl_api_ipsec_spd_add_del_reply_t *rmp;
85 rv = ipsec_add_del_spd (vm, ntohl (mp->spd_id), mp->is_add);
87 REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_REPLY);
90 static void vl_api_ipsec_interface_add_del_spd_t_handler
91 (vl_api_ipsec_interface_add_del_spd_t * mp)
93 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
94 vl_api_ipsec_interface_add_del_spd_reply_t *rmp;
96 u32 sw_if_index __attribute__ ((unused));
97 u32 spd_id __attribute__ ((unused));
99 sw_if_index = ntohl (mp->sw_if_index);
100 spd_id = ntohl (mp->spd_id);
102 VALIDATE_SW_IF_INDEX (mp);
104 rv = ipsec_set_interface_spd (vm, sw_if_index, spd_id, mp->is_add);
106 BAD_SW_IF_INDEX_LABEL;
108 REPLY_MACRO (VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY);
111 static void vl_api_ipsec_tunnel_protect_update_t_handler
112 (vl_api_ipsec_tunnel_protect_update_t * mp)
114 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
115 vl_api_ipsec_tunnel_protect_update_reply_t *rmp;
116 u32 sw_if_index, ii, *sa_ins = NULL;
120 sw_if_index = ntohl (mp->tunnel.sw_if_index);
122 VALIDATE_SW_IF_INDEX (&(mp->tunnel));
124 for (ii = 0; ii < mp->tunnel.n_sa_in; ii++)
125 vec_add1 (sa_ins, ntohl (mp->tunnel.sa_in[ii]));
127 ip_address_decode2 (&mp->tunnel.nh, &nh);
129 rv = ipsec_tun_protect_update (sw_if_index, &nh,
130 ntohl (mp->tunnel.sa_out), sa_ins);
132 BAD_SW_IF_INDEX_LABEL;
134 REPLY_MACRO (VL_API_IPSEC_TUNNEL_PROTECT_UPDATE_REPLY);
137 static void vl_api_ipsec_tunnel_protect_del_t_handler
138 (vl_api_ipsec_tunnel_protect_del_t * mp)
140 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
141 vl_api_ipsec_tunnel_protect_del_reply_t *rmp;
146 sw_if_index = ntohl (mp->sw_if_index);
148 VALIDATE_SW_IF_INDEX (mp);
150 ip_address_decode2 (&mp->nh, &nh);
151 rv = ipsec_tun_protect_del (sw_if_index, &nh);
153 BAD_SW_IF_INDEX_LABEL;
155 REPLY_MACRO (VL_API_IPSEC_TUNNEL_PROTECT_DEL_REPLY);
158 typedef struct ipsec_dump_walk_ctx_t_
160 vl_api_registration_t *reg;
162 } ipsec_dump_walk_ctx_t;
165 send_ipsec_tunnel_protect_details (index_t itpi, void *arg)
167 ipsec_dump_walk_ctx_t *ctx = arg;
168 vl_api_ipsec_tunnel_protect_details_t *mp;
169 ipsec_tun_protect_t *itp;
173 itp = ipsec_tun_protect_get (itpi);
175 mp = vl_msg_api_alloc (sizeof (*mp) + (sizeof (u32) * itp->itp_n_sa_in));
176 clib_memset (mp, 0, sizeof (*mp));
177 mp->_vl_msg_id = ntohs (VL_API_IPSEC_TUNNEL_PROTECT_DETAILS);
178 mp->context = ctx->context;
180 mp->tun.sw_if_index = htonl (itp->itp_sw_if_index);
181 ip_address_encode2 (itp->itp_key, &mp->tun.nh);
183 sa = ipsec_sa_get (itp->itp_out_sa);
184 mp->tun.sa_out = htonl (sa->id);
185 mp->tun.n_sa_in = itp->itp_n_sa_in;
187 FOR_EACH_IPSEC_PROTECT_INPUT_SA(itp, sa,
189 mp->tun.sa_in[ii++] = htonl (sa->id);
193 vl_api_send_msg (ctx->reg, (u8 *) mp);
195 return (WALK_CONTINUE);
199 vl_api_ipsec_tunnel_protect_dump_t_handler (vl_api_ipsec_tunnel_protect_dump_t
202 vl_api_registration_t *reg;
205 reg = vl_api_client_index_to_registration (mp->client_index);
209 ipsec_dump_walk_ctx_t ctx = {
211 .context = mp->context,
214 sw_if_index = ntohl (mp->sw_if_index);
216 if (~0 == sw_if_index)
218 ipsec_tun_protect_walk (send_ipsec_tunnel_protect_details, &ctx);
222 ipsec_tun_protect_walk_itf (sw_if_index,
223 send_ipsec_tunnel_protect_details, &ctx);
228 ipsec_spd_action_decode (vl_api_ipsec_spd_action_t in,
229 ipsec_policy_action_t * out)
231 in = clib_net_to_host_u32 (in);
235 #define _(v,f,s) case IPSEC_API_SPD_ACTION_##f: \
236 *out = IPSEC_POLICY_ACTION_##f; \
238 foreach_ipsec_policy_action
241 return (VNET_API_ERROR_UNIMPLEMENTED);
244 static void vl_api_ipsec_spd_entry_add_del_t_handler
245 (vl_api_ipsec_spd_entry_add_del_t * mp)
247 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
248 vl_api_ipsec_spd_entry_add_del_reply_t *rmp;
257 clib_memset (&p, 0, sizeof (p));
259 p.id = ntohl (mp->entry.spd_id);
260 p.priority = ntohl (mp->entry.priority);
262 itype = ip_address_decode (&mp->entry.remote_address_start, &p.raddr.start);
263 ip_address_decode (&mp->entry.remote_address_stop, &p.raddr.stop);
264 ip_address_decode (&mp->entry.local_address_start, &p.laddr.start);
265 ip_address_decode (&mp->entry.local_address_stop, &p.laddr.stop);
267 p.is_ipv6 = (itype == IP46_TYPE_IP6);
269 p.protocol = mp->entry.protocol;
270 p.rport.start = ntohs (mp->entry.remote_port_start);
271 p.rport.stop = ntohs (mp->entry.remote_port_stop);
272 p.lport.start = ntohs (mp->entry.local_port_start);
273 p.lport.stop = ntohs (mp->entry.local_port_stop);
275 rv = ipsec_spd_action_decode (mp->entry.policy, &p.policy);
280 /* policy action resolve unsupported */
281 if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
283 clib_warning ("unsupported action: 'resolve'");
284 rv = VNET_API_ERROR_UNIMPLEMENTED;
287 p.sa_id = ntohl (mp->entry.sa_id);
289 ipsec_policy_mk_type (mp->entry.is_outbound, p.is_ipv6, p.policy,
294 rv = ipsec_add_del_policy (vm, &p, mp->is_add, &stat_index);
300 REPLY_MACRO2 (VL_API_IPSEC_SPD_ENTRY_ADD_DEL_REPLY,
302 rmp->stat_index = ntohl(stat_index);
307 static void vl_api_ipsec_sad_entry_add_del_t_handler
308 (vl_api_ipsec_sad_entry_add_del_t * mp)
310 vl_api_ipsec_sad_entry_add_del_reply_t *rmp;
311 ipsec_key_t crypto_key, integ_key;
312 ipsec_crypto_alg_t crypto_alg;
313 ipsec_integ_alg_t integ_alg;
314 ipsec_protocol_t proto;
315 ipsec_sa_flags_t flags;
316 u32 id, spi, sa_index = ~0;
318 .t_flags = TUNNEL_FLAG_NONE,
319 .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE,
321 .t_mode = TUNNEL_MODE_P2P,
327 id = ntohl (mp->entry.sad_id);
328 spi = ntohl (mp->entry.spi);
330 rv = ipsec_proto_decode (mp->entry.protocol, &proto);
335 rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &crypto_alg);
340 rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &integ_alg);
345 ipsec_key_decode (&mp->entry.crypto_key, &crypto_key);
346 ipsec_key_decode (&mp->entry.integrity_key, &integ_key);
348 flags = ipsec_sa_flags_decode (mp->entry.flags);
350 ip_address_decode2 (&mp->entry.tunnel_src, &tun.t_src);
351 ip_address_decode2 (&mp->entry.tunnel_dst, &tun.t_dst);
354 rv = ipsec_sa_add_and_lock (
355 id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags,
356 mp->entry.salt, htons (mp->entry.udp_src_port),
357 htons (mp->entry.udp_dst_port), &tun, &sa_index);
359 rv = ipsec_sa_unlock_id (id);
363 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_REPLY,
365 rmp->stat_index = htonl (sa_index);
370 static void vl_api_ipsec_sad_entry_add_del_v2_t_handler
371 (vl_api_ipsec_sad_entry_add_del_v2_t * mp)
373 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
374 vl_api_ipsec_sad_entry_add_del_v2_reply_t *rmp;
375 ipsec_key_t crypto_key, integ_key;
376 ipsec_crypto_alg_t crypto_alg;
377 ipsec_integ_alg_t integ_alg;
378 ipsec_protocol_t proto;
379 ipsec_sa_flags_t flags;
380 u32 id, spi, sa_index = ~0;
383 .t_flags = TUNNEL_FLAG_NONE,
384 .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE,
386 .t_mode = TUNNEL_MODE_P2P,
387 .t_table_id = htonl (mp->entry.tx_table_id),
391 id = ntohl (mp->entry.sad_id);
392 spi = ntohl (mp->entry.spi);
394 rv = ipsec_proto_decode (mp->entry.protocol, &proto);
399 rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &crypto_alg);
404 rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &integ_alg);
409 rv = tunnel_encap_decap_flags_decode (mp->entry.tunnel_flags,
410 &tun.t_encap_decap_flags);
415 ipsec_key_decode (&mp->entry.crypto_key, &crypto_key);
416 ipsec_key_decode (&mp->entry.integrity_key, &integ_key);
418 flags = ipsec_sa_flags_decode (mp->entry.flags);
419 tun.t_dscp = ip_dscp_decode (mp->entry.dscp);
421 ip_address_decode2 (&mp->entry.tunnel_src, &tun.t_src);
422 ip_address_decode2 (&mp->entry.tunnel_dst, &tun.t_dst);
425 rv = ipsec_sa_add_and_lock (
426 id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags,
427 mp->entry.salt, htons (mp->entry.udp_src_port),
428 htons (mp->entry.udp_dst_port), &tun, &sa_index);
430 rv = ipsec_sa_unlock_id (id);
434 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_V2_REPLY,
436 rmp->stat_index = htonl (sa_index);
442 vl_api_ipsec_sad_entry_add_del_v3_t_handler (
443 vl_api_ipsec_sad_entry_add_del_v3_t *mp)
445 vl_api_ipsec_sad_entry_add_del_v3_reply_t *rmp;
446 ipsec_key_t crypto_key, integ_key;
447 ipsec_crypto_alg_t crypto_alg;
448 ipsec_integ_alg_t integ_alg;
449 ipsec_protocol_t proto;
450 ipsec_sa_flags_t flags;
451 u32 id, spi, sa_index = ~0;
455 id = ntohl (mp->entry.sad_id);
456 spi = ntohl (mp->entry.spi);
458 rv = ipsec_proto_decode (mp->entry.protocol, &proto);
463 rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &crypto_alg);
468 rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &integ_alg);
473 flags = ipsec_sa_flags_decode (mp->entry.flags);
475 if (flags & IPSEC_SA_FLAG_IS_TUNNEL)
477 rv = tunnel_decode (&mp->entry.tunnel, &tun);
483 ipsec_key_decode (&mp->entry.crypto_key, &crypto_key);
484 ipsec_key_decode (&mp->entry.integrity_key, &integ_key);
487 rv = ipsec_sa_add_and_lock (
488 id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags,
489 mp->entry.salt, htons (mp->entry.udp_src_port),
490 htons (mp->entry.udp_dst_port), &tun, &sa_index);
492 rv = ipsec_sa_unlock_id (id);
495 REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_V3_REPLY,
496 { rmp->stat_index = htonl (sa_index); });
500 send_ipsec_spds_details (ipsec_spd_t * spd, vl_api_registration_t * reg,
503 vl_api_ipsec_spds_details_t *mp;
506 mp = vl_msg_api_alloc (sizeof (*mp));
507 clib_memset (mp, 0, sizeof (*mp));
508 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPDS_DETAILS);
509 mp->context = context;
511 mp->spd_id = htonl (spd->id);
512 #define _(s, n) n_policies += vec_len (spd->policies[IPSEC_SPD_POLICY_##s]);
513 foreach_ipsec_spd_policy_type
515 mp->npolicies = htonl (n_policies);
517 vl_api_send_msg (reg, (u8 *) mp);
521 vl_api_ipsec_spds_dump_t_handler (vl_api_ipsec_spds_dump_t * mp)
523 vl_api_registration_t *reg;
524 ipsec_main_t *im = &ipsec_main;
527 reg = vl_api_client_index_to_registration (mp->client_index);
531 pool_foreach (spd, im->spds) {
532 send_ipsec_spds_details (spd, reg, mp->context);
536 vl_api_ipsec_spd_action_t
537 ipsec_spd_action_encode (ipsec_policy_action_t in)
539 vl_api_ipsec_spd_action_t out = IPSEC_API_SPD_ACTION_BYPASS;
543 #define _(v,f,s) case IPSEC_POLICY_ACTION_##f: \
544 out = IPSEC_API_SPD_ACTION_##f; \
546 foreach_ipsec_policy_action
549 return (clib_host_to_net_u32 (out));
553 send_ipsec_spd_details (ipsec_policy_t * p, vl_api_registration_t * reg,
556 vl_api_ipsec_spd_details_t *mp;
558 mp = vl_msg_api_alloc (sizeof (*mp));
559 clib_memset (mp, 0, sizeof (*mp));
560 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_DETAILS);
561 mp->context = context;
563 mp->entry.spd_id = htonl (p->id);
564 mp->entry.priority = htonl (p->priority);
565 mp->entry.is_outbound = ((p->type == IPSEC_SPD_POLICY_IP6_OUTBOUND) ||
566 (p->type == IPSEC_SPD_POLICY_IP4_OUTBOUND));
568 ip_address_encode (&p->laddr.start, IP46_TYPE_ANY,
569 &mp->entry.local_address_start);
570 ip_address_encode (&p->laddr.stop, IP46_TYPE_ANY,
571 &mp->entry.local_address_stop);
572 ip_address_encode (&p->raddr.start, IP46_TYPE_ANY,
573 &mp->entry.remote_address_start);
574 ip_address_encode (&p->raddr.stop, IP46_TYPE_ANY,
575 &mp->entry.remote_address_stop);
576 mp->entry.local_port_start = htons (p->lport.start);
577 mp->entry.local_port_stop = htons (p->lport.stop);
578 mp->entry.remote_port_start = htons (p->rport.start);
579 mp->entry.remote_port_stop = htons (p->rport.stop);
580 mp->entry.protocol = p->protocol;
581 mp->entry.policy = ipsec_spd_action_encode (p->policy);
582 mp->entry.sa_id = htonl (p->sa_id);
584 vl_api_send_msg (reg, (u8 *) mp);
588 vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp)
590 vl_api_registration_t *reg;
591 ipsec_main_t *im = &ipsec_main;
592 ipsec_spd_policy_type_t ptype;
593 ipsec_policy_t *policy;
598 reg = vl_api_client_index_to_registration (mp->client_index);
602 p = hash_get (im->spd_index_by_spd_id, ntohl (mp->spd_id));
607 spd = pool_elt_at_index (im->spds, spd_index);
609 FOR_EACH_IPSEC_SPD_POLICY_TYPE(ptype) {
610 vec_foreach(ii, spd->policies[ptype])
612 policy = pool_elt_at_index(im->policies, *ii);
614 if (mp->sa_id == ~(0) || ntohl (mp->sa_id) == policy->sa_id)
615 send_ipsec_spd_details (policy, reg, mp->context);
621 send_ipsec_spd_interface_details (vl_api_registration_t * reg, u32 spd_index,
622 u32 sw_if_index, u32 context)
624 vl_api_ipsec_spd_interface_details_t *mp;
626 mp = vl_msg_api_alloc (sizeof (*mp));
627 clib_memset (mp, 0, sizeof (*mp));
628 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_INTERFACE_DETAILS);
629 mp->context = context;
631 mp->spd_index = htonl (spd_index);
632 mp->sw_if_index = htonl (sw_if_index);
634 vl_api_send_msg (reg, (u8 *) mp);
638 vl_api_ipsec_spd_interface_dump_t_handler (vl_api_ipsec_spd_interface_dump_t *
641 ipsec_main_t *im = &ipsec_main;
642 vl_api_registration_t *reg;
645 reg = vl_api_client_index_to_registration (mp->client_index);
649 if (mp->spd_index_valid)
651 spd_index = ntohl (mp->spd_index);
653 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
655 send_ipsec_spd_interface_details(reg, v, k, mp->context);
661 hash_foreach(k, v, im->spd_index_by_sw_if_index, ({
662 send_ipsec_spd_interface_details(reg, v, k, mp->context);
668 vl_api_ipsec_itf_create_t_handler (vl_api_ipsec_itf_create_t * mp)
670 vl_api_ipsec_itf_create_reply_t *rmp;
672 u32 sw_if_index = ~0;
675 rv = tunnel_mode_decode (mp->itf.mode, &mode);
678 rv = ipsec_itf_create (ntohl (mp->itf.user_instance), mode, &sw_if_index);
681 REPLY_MACRO2 (VL_API_IPSEC_ITF_CREATE_REPLY,
683 rmp->sw_if_index = htonl (sw_if_index);
689 vl_api_ipsec_itf_delete_t_handler (vl_api_ipsec_itf_delete_t * mp)
691 vl_api_ipsec_itf_delete_reply_t *rmp;
694 rv = ipsec_itf_delete (ntohl (mp->sw_if_index));
696 REPLY_MACRO (VL_API_IPSEC_ITF_DELETE_REPLY);
700 vl_api_ipsec_itf_dump_t_handler (vl_api_ipsec_itf_dump_t * mp)
704 typedef struct ipsec_sa_dump_match_ctx_t_
708 } ipsec_sa_dump_match_ctx_t;
711 ipsec_sa_dump_match_sa (index_t itpi, void *arg)
713 ipsec_sa_dump_match_ctx_t *ctx = arg;
714 ipsec_tun_protect_t *itp;
717 itp = ipsec_tun_protect_get (itpi);
719 if (itp->itp_out_sa == ctx->sai)
721 ctx->sw_if_index = itp->itp_sw_if_index;
725 FOR_EACH_IPSEC_PROTECT_INPUT_SAI (itp, sai,
729 ctx->sw_if_index = itp->itp_sw_if_index;
734 return (WALK_CONTINUE);
738 send_ipsec_sa_details (ipsec_sa_t * sa, void *arg)
740 ipsec_dump_walk_ctx_t *ctx = arg;
741 vl_api_ipsec_sa_details_t *mp;
743 mp = vl_msg_api_alloc (sizeof (*mp));
744 clib_memset (mp, 0, sizeof (*mp));
745 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_DETAILS);
746 mp->context = ctx->context;
748 mp->entry.sad_id = htonl (sa->id);
749 mp->entry.spi = htonl (sa->spi);
750 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
751 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
753 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
754 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
756 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
757 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
759 mp->entry.flags = ipsec_sad_flags_encode (sa);
760 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
762 if (ipsec_sa_is_set_IS_PROTECT (sa))
764 ipsec_sa_dump_match_ctx_t ctx = {
765 .sai = sa - ipsec_sa_pool,
768 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
770 mp->sw_if_index = htonl (ctx.sw_if_index);
773 mp->sw_if_index = ~0;
775 if (ipsec_sa_is_set_IS_TUNNEL (sa))
777 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
778 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
780 if (ipsec_sa_is_set_UDP_ENCAP (sa))
782 mp->entry.udp_src_port = sa->udp_hdr.src_port;
783 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
786 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
787 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
788 if (ipsec_sa_is_set_USE_ESN (sa))
790 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
791 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
793 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
794 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
796 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
798 vl_api_send_msg (ctx->reg, (u8 *) mp);
800 return (WALK_CONTINUE);
804 vl_api_ipsec_sa_dump_t_handler (vl_api_ipsec_sa_dump_t * mp)
806 vl_api_registration_t *reg;
808 reg = vl_api_client_index_to_registration (mp->client_index);
812 ipsec_dump_walk_ctx_t ctx = {
814 .context = mp->context,
817 ipsec_sa_walk (send_ipsec_sa_details, &ctx);
821 send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg)
823 ipsec_dump_walk_ctx_t *ctx = arg;
824 vl_api_ipsec_sa_v2_details_t *mp;
826 mp = vl_msg_api_alloc (sizeof (*mp));
827 clib_memset (mp, 0, sizeof (*mp));
828 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_V2_DETAILS);
829 mp->context = ctx->context;
831 mp->entry.sad_id = htonl (sa->id);
832 mp->entry.spi = htonl (sa->spi);
833 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
834 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
836 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
837 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
839 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
840 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
842 mp->entry.flags = ipsec_sad_flags_encode (sa);
843 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
845 if (ipsec_sa_is_set_IS_PROTECT (sa))
847 ipsec_sa_dump_match_ctx_t ctx = {
848 .sai = sa - ipsec_sa_pool,
851 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
853 mp->sw_if_index = htonl (ctx.sw_if_index);
856 mp->sw_if_index = ~0;
858 if (ipsec_sa_is_set_IS_TUNNEL (sa))
860 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
861 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
863 if (ipsec_sa_is_set_UDP_ENCAP (sa))
865 mp->entry.udp_src_port = sa->udp_hdr.src_port;
866 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
869 mp->entry.tunnel_flags =
870 tunnel_encap_decap_flags_encode (sa->tunnel.t_encap_decap_flags);
871 mp->entry.dscp = ip_dscp_encode (sa->tunnel.t_dscp);
873 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
874 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
875 if (ipsec_sa_is_set_USE_ESN (sa))
877 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
878 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
880 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
881 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
883 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
885 vl_api_send_msg (ctx->reg, (u8 *) mp);
887 return (WALK_CONTINUE);
891 vl_api_ipsec_sa_v2_dump_t_handler (vl_api_ipsec_sa_v2_dump_t *mp)
893 vl_api_registration_t *reg;
895 reg = vl_api_client_index_to_registration (mp->client_index);
899 ipsec_dump_walk_ctx_t ctx = {
901 .context = mp->context,
904 ipsec_sa_walk (send_ipsec_sa_v2_details, &ctx);
908 send_ipsec_sa_v3_details (ipsec_sa_t *sa, void *arg)
910 ipsec_dump_walk_ctx_t *ctx = arg;
911 vl_api_ipsec_sa_v3_details_t *mp;
913 mp = vl_msg_api_alloc (sizeof (*mp));
914 clib_memset (mp, 0, sizeof (*mp));
915 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_V3_DETAILS);
916 mp->context = ctx->context;
918 mp->entry.sad_id = htonl (sa->id);
919 mp->entry.spi = htonl (sa->spi);
920 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
922 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
923 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
925 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
926 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
928 mp->entry.flags = ipsec_sad_flags_encode (sa);
929 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
931 if (ipsec_sa_is_set_IS_PROTECT (sa))
933 ipsec_sa_dump_match_ctx_t ctx = {
934 .sai = sa - ipsec_sa_pool,
937 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
939 mp->sw_if_index = htonl (ctx.sw_if_index);
942 mp->sw_if_index = ~0;
944 if (ipsec_sa_is_set_IS_TUNNEL (sa))
945 tunnel_encode (&sa->tunnel, &mp->entry.tunnel);
947 if (ipsec_sa_is_set_UDP_ENCAP (sa))
949 mp->entry.udp_src_port = sa->udp_hdr.src_port;
950 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
953 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
954 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
955 if (ipsec_sa_is_set_USE_ESN (sa))
957 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
958 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
960 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
961 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
963 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
965 vl_api_send_msg (ctx->reg, (u8 *) mp);
967 return (WALK_CONTINUE);
971 vl_api_ipsec_sa_v3_dump_t_handler (vl_api_ipsec_sa_v3_dump_t *mp)
973 vl_api_registration_t *reg;
975 reg = vl_api_client_index_to_registration (mp->client_index);
979 ipsec_dump_walk_ctx_t ctx = {
981 .context = mp->context,
984 ipsec_sa_walk (send_ipsec_sa_v3_details, &ctx);
988 vl_api_ipsec_backend_dump_t_handler (vl_api_ipsec_backend_dump_t * mp)
990 vl_api_registration_t *rp;
991 ipsec_main_t *im = &ipsec_main;
992 u32 context = mp->context;
994 rp = vl_api_client_index_to_registration (mp->client_index);
998 clib_warning ("Client %d AWOL", mp->client_index);
1002 ipsec_ah_backend_t *ab;
1003 ipsec_esp_backend_t *eb;
1005 pool_foreach (ab, im->ah_backends) {
1006 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1007 clib_memset (mp, 0, sizeof (*mp));
1008 mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS);
1009 mp->context = context;
1010 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (ab->name),
1012 mp->protocol = ntohl (IPSEC_API_PROTO_AH);
1013 mp->index = ab - im->ah_backends;
1014 mp->active = mp->index == im->ah_current_backend ? 1 : 0;
1015 vl_api_send_msg (rp, (u8 *)mp);
1017 pool_foreach (eb, im->esp_backends) {
1018 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1019 clib_memset (mp, 0, sizeof (*mp));
1020 mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS);
1021 mp->context = context;
1022 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (eb->name),
1024 mp->protocol = ntohl (IPSEC_API_PROTO_ESP);
1025 mp->index = eb - im->esp_backends;
1026 mp->active = mp->index == im->esp_current_backend ? 1 : 0;
1027 vl_api_send_msg (rp, (u8 *)mp);
1033 vl_api_ipsec_select_backend_t_handler (vl_api_ipsec_select_backend_t * mp)
1035 ipsec_main_t *im = &ipsec_main;
1036 vl_api_ipsec_select_backend_reply_t *rmp;
1037 ipsec_protocol_t protocol;
1039 if (pool_elts (ipsec_sa_pool) > 0)
1041 rv = VNET_API_ERROR_INSTANCE_IN_USE;
1045 rv = ipsec_proto_decode (mp->protocol, &protocol);
1052 case IPSEC_PROTOCOL_ESP:
1053 rv = ipsec_select_esp_backend (im, mp->index);
1055 case IPSEC_PROTOCOL_AH:
1056 rv = ipsec_select_ah_backend (im, mp->index);
1059 rv = VNET_API_ERROR_INVALID_PROTOCOL;
1063 REPLY_MACRO (VL_API_IPSEC_SELECT_BACKEND_REPLY);
1067 vl_api_ipsec_set_async_mode_t_handler (vl_api_ipsec_set_async_mode_t * mp)
1069 vl_api_ipsec_set_async_mode_reply_t *rmp;
1072 ipsec_set_async_mode (mp->async_enable);
1074 REPLY_MACRO (VL_API_IPSEC_SET_ASYNC_MODE_REPLY);
1079 * Add vpe's API message handlers to the table.
1080 * vlib has already mapped shared memory and
1081 * added the client registration handlers.
1082 * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
1084 #define vl_msg_name_crc_list
1085 #include <vnet/vnet_all_api_h.h>
1086 #undef vl_msg_name_crc_list
1089 setup_message_id_table (api_main_t * am)
1091 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
1092 foreach_vl_msg_name_crc_ipsec;
1096 static clib_error_t *
1097 ipsec_api_hookup (vlib_main_t * vm)
1099 api_main_t *am = vlibapi_get_main ();
1102 vl_msg_api_set_handlers(VL_API_##N, #n, \
1103 vl_api_##n##_t_handler, \
1105 vl_api_##n##_t_endian, \
1106 vl_api_##n##_t_print, \
1107 sizeof(vl_api_##n##_t), 1);
1108 foreach_vpe_api_msg;
1112 * Set up the (msg_name, crc, message-id) table
1114 setup_message_id_table (am);
1119 VLIB_API_INIT_FUNCTION (ipsec_api_hookup);
1122 * fd.io coding-style-patch-verification: ON
1125 * eval: (c-set-style "gnu")