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 send_ipsec_itf_details (ipsec_itf_t *itf, void *arg)
702 ipsec_dump_walk_ctx_t *ctx = arg;
703 vl_api_ipsec_itf_details_t *mp;
705 mp = vl_msg_api_alloc (sizeof (*mp));
706 clib_memset (mp, 0, sizeof (*mp));
707 mp->_vl_msg_id = ntohs (VL_API_IPSEC_ITF_DETAILS);
708 mp->context = ctx->context;
710 mp->itf.mode = tunnel_mode_encode (itf->ii_mode);
711 mp->itf.user_instance = htonl (itf->ii_user_instance);
712 mp->itf.sw_if_index = htonl (itf->ii_sw_if_index);
713 vl_api_send_msg (ctx->reg, (u8 *) mp);
715 return (WALK_CONTINUE);
719 vl_api_ipsec_itf_dump_t_handler (vl_api_ipsec_itf_dump_t * mp)
721 vl_api_registration_t *reg;
723 reg = vl_api_client_index_to_registration (mp->client_index);
727 ipsec_dump_walk_ctx_t ctx = {
729 .context = mp->context,
732 ipsec_itf_walk (send_ipsec_itf_details, &ctx);
735 typedef struct ipsec_sa_dump_match_ctx_t_
739 } ipsec_sa_dump_match_ctx_t;
742 ipsec_sa_dump_match_sa (index_t itpi, void *arg)
744 ipsec_sa_dump_match_ctx_t *ctx = arg;
745 ipsec_tun_protect_t *itp;
748 itp = ipsec_tun_protect_get (itpi);
750 if (itp->itp_out_sa == ctx->sai)
752 ctx->sw_if_index = itp->itp_sw_if_index;
756 FOR_EACH_IPSEC_PROTECT_INPUT_SAI (itp, sai,
760 ctx->sw_if_index = itp->itp_sw_if_index;
765 return (WALK_CONTINUE);
769 send_ipsec_sa_details (ipsec_sa_t * sa, void *arg)
771 ipsec_dump_walk_ctx_t *ctx = arg;
772 vl_api_ipsec_sa_details_t *mp;
774 mp = vl_msg_api_alloc (sizeof (*mp));
775 clib_memset (mp, 0, sizeof (*mp));
776 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_DETAILS);
777 mp->context = ctx->context;
779 mp->entry.sad_id = htonl (sa->id);
780 mp->entry.spi = htonl (sa->spi);
781 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
782 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
784 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
785 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
787 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
788 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
790 mp->entry.flags = ipsec_sad_flags_encode (sa);
791 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
793 if (ipsec_sa_is_set_IS_PROTECT (sa))
795 ipsec_sa_dump_match_ctx_t ctx = {
796 .sai = sa - ipsec_sa_pool,
799 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
801 mp->sw_if_index = htonl (ctx.sw_if_index);
804 mp->sw_if_index = ~0;
806 if (ipsec_sa_is_set_IS_TUNNEL (sa))
808 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
809 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
811 if (ipsec_sa_is_set_UDP_ENCAP (sa))
813 mp->entry.udp_src_port = sa->udp_hdr.src_port;
814 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
817 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
818 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
819 if (ipsec_sa_is_set_USE_ESN (sa))
821 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
822 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
824 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
825 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
827 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
829 vl_api_send_msg (ctx->reg, (u8 *) mp);
831 return (WALK_CONTINUE);
835 vl_api_ipsec_sa_dump_t_handler (vl_api_ipsec_sa_dump_t * mp)
837 vl_api_registration_t *reg;
839 reg = vl_api_client_index_to_registration (mp->client_index);
843 ipsec_dump_walk_ctx_t ctx = {
845 .context = mp->context,
848 ipsec_sa_walk (send_ipsec_sa_details, &ctx);
852 send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg)
854 ipsec_dump_walk_ctx_t *ctx = arg;
855 vl_api_ipsec_sa_v2_details_t *mp;
857 mp = vl_msg_api_alloc (sizeof (*mp));
858 clib_memset (mp, 0, sizeof (*mp));
859 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_V2_DETAILS);
860 mp->context = ctx->context;
862 mp->entry.sad_id = htonl (sa->id);
863 mp->entry.spi = htonl (sa->spi);
864 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
865 mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
867 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
868 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
870 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
871 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
873 mp->entry.flags = ipsec_sad_flags_encode (sa);
874 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
876 if (ipsec_sa_is_set_IS_PROTECT (sa))
878 ipsec_sa_dump_match_ctx_t ctx = {
879 .sai = sa - ipsec_sa_pool,
882 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
884 mp->sw_if_index = htonl (ctx.sw_if_index);
887 mp->sw_if_index = ~0;
889 if (ipsec_sa_is_set_IS_TUNNEL (sa))
891 ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
892 ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
894 if (ipsec_sa_is_set_UDP_ENCAP (sa))
896 mp->entry.udp_src_port = sa->udp_hdr.src_port;
897 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
900 mp->entry.tunnel_flags =
901 tunnel_encap_decap_flags_encode (sa->tunnel.t_encap_decap_flags);
902 mp->entry.dscp = ip_dscp_encode (sa->tunnel.t_dscp);
904 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
905 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
906 if (ipsec_sa_is_set_USE_ESN (sa))
908 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
909 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
911 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
912 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
914 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
916 vl_api_send_msg (ctx->reg, (u8 *) mp);
918 return (WALK_CONTINUE);
922 vl_api_ipsec_sa_v2_dump_t_handler (vl_api_ipsec_sa_v2_dump_t *mp)
924 vl_api_registration_t *reg;
926 reg = vl_api_client_index_to_registration (mp->client_index);
930 ipsec_dump_walk_ctx_t ctx = {
932 .context = mp->context,
935 ipsec_sa_walk (send_ipsec_sa_v2_details, &ctx);
939 send_ipsec_sa_v3_details (ipsec_sa_t *sa, void *arg)
941 ipsec_dump_walk_ctx_t *ctx = arg;
942 vl_api_ipsec_sa_v3_details_t *mp;
944 mp = vl_msg_api_alloc (sizeof (*mp));
945 clib_memset (mp, 0, sizeof (*mp));
946 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_V3_DETAILS);
947 mp->context = ctx->context;
949 mp->entry.sad_id = htonl (sa->id);
950 mp->entry.spi = htonl (sa->spi);
951 mp->entry.protocol = ipsec_proto_encode (sa->protocol);
953 mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
954 ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
956 mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
957 ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
959 mp->entry.flags = ipsec_sad_flags_encode (sa);
960 mp->entry.salt = clib_host_to_net_u32 (sa->salt);
962 if (ipsec_sa_is_set_IS_PROTECT (sa))
964 ipsec_sa_dump_match_ctx_t ctx = {
965 .sai = sa - ipsec_sa_pool,
968 ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
970 mp->sw_if_index = htonl (ctx.sw_if_index);
973 mp->sw_if_index = ~0;
975 if (ipsec_sa_is_set_IS_TUNNEL (sa))
976 tunnel_encode (&sa->tunnel, &mp->entry.tunnel);
978 if (ipsec_sa_is_set_UDP_ENCAP (sa))
980 mp->entry.udp_src_port = sa->udp_hdr.src_port;
981 mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
984 mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
985 mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
986 if (ipsec_sa_is_set_USE_ESN (sa))
988 mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
989 mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
991 if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
992 mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
994 mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
996 vl_api_send_msg (ctx->reg, (u8 *) mp);
998 return (WALK_CONTINUE);
1002 vl_api_ipsec_sa_v3_dump_t_handler (vl_api_ipsec_sa_v3_dump_t *mp)
1004 vl_api_registration_t *reg;
1006 reg = vl_api_client_index_to_registration (mp->client_index);
1010 ipsec_dump_walk_ctx_t ctx = {
1012 .context = mp->context,
1015 ipsec_sa_walk (send_ipsec_sa_v3_details, &ctx);
1019 vl_api_ipsec_backend_dump_t_handler (vl_api_ipsec_backend_dump_t * mp)
1021 vl_api_registration_t *rp;
1022 ipsec_main_t *im = &ipsec_main;
1023 u32 context = mp->context;
1025 rp = vl_api_client_index_to_registration (mp->client_index);
1029 clib_warning ("Client %d AWOL", mp->client_index);
1033 ipsec_ah_backend_t *ab;
1034 ipsec_esp_backend_t *eb;
1036 pool_foreach (ab, im->ah_backends) {
1037 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1038 clib_memset (mp, 0, sizeof (*mp));
1039 mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS);
1040 mp->context = context;
1041 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (ab->name),
1043 mp->protocol = ntohl (IPSEC_API_PROTO_AH);
1044 mp->index = ab - im->ah_backends;
1045 mp->active = mp->index == im->ah_current_backend ? 1 : 0;
1046 vl_api_send_msg (rp, (u8 *)mp);
1048 pool_foreach (eb, im->esp_backends) {
1049 vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
1050 clib_memset (mp, 0, sizeof (*mp));
1051 mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS);
1052 mp->context = context;
1053 snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (eb->name),
1055 mp->protocol = ntohl (IPSEC_API_PROTO_ESP);
1056 mp->index = eb - im->esp_backends;
1057 mp->active = mp->index == im->esp_current_backend ? 1 : 0;
1058 vl_api_send_msg (rp, (u8 *)mp);
1064 vl_api_ipsec_select_backend_t_handler (vl_api_ipsec_select_backend_t * mp)
1066 ipsec_main_t *im = &ipsec_main;
1067 vl_api_ipsec_select_backend_reply_t *rmp;
1068 ipsec_protocol_t protocol;
1070 if (pool_elts (ipsec_sa_pool) > 0)
1072 rv = VNET_API_ERROR_INSTANCE_IN_USE;
1076 rv = ipsec_proto_decode (mp->protocol, &protocol);
1083 case IPSEC_PROTOCOL_ESP:
1084 rv = ipsec_select_esp_backend (im, mp->index);
1086 case IPSEC_PROTOCOL_AH:
1087 rv = ipsec_select_ah_backend (im, mp->index);
1090 rv = VNET_API_ERROR_INVALID_PROTOCOL;
1094 REPLY_MACRO (VL_API_IPSEC_SELECT_BACKEND_REPLY);
1098 vl_api_ipsec_set_async_mode_t_handler (vl_api_ipsec_set_async_mode_t * mp)
1100 vl_api_ipsec_set_async_mode_reply_t *rmp;
1103 ipsec_set_async_mode (mp->async_enable);
1105 REPLY_MACRO (VL_API_IPSEC_SET_ASYNC_MODE_REPLY);
1110 * Add vpe's API message handlers to the table.
1111 * vlib has already mapped shared memory and
1112 * added the client registration handlers.
1113 * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
1115 #define vl_msg_name_crc_list
1116 #include <vnet/vnet_all_api_h.h>
1117 #undef vl_msg_name_crc_list
1120 setup_message_id_table (api_main_t * am)
1122 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
1123 foreach_vl_msg_name_crc_ipsec;
1127 static clib_error_t *
1128 ipsec_api_hookup (vlib_main_t * vm)
1130 api_main_t *am = vlibapi_get_main ();
1133 vl_msg_api_set_handlers(VL_API_##N, #n, \
1134 vl_api_##n##_t_handler, \
1136 vl_api_##n##_t_endian, \
1137 vl_api_##n##_t_print, \
1138 sizeof(vl_api_##n##_t), 1);
1139 foreach_vpe_api_msg;
1143 * Set up the (msg_name, crc, message-id) table
1145 setup_message_id_table (am);
1150 VLIB_API_INIT_FUNCTION (ipsec_api_hookup);
1153 * fd.io coding-style-patch-verification: ON
1156 * eval: (c-set-style "gnu")