FD.io VPP  v20.01-48-g3e0dafb74
Vector Packet Processing
ipsec_api.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * ipsec_api.c - ipsec api
4  *
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:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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  *------------------------------------------------------------------
18  */
19 
20 #include <vnet/vnet.h>
21 #include <vlibmemory/api.h>
22 
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>
28 #include <vnet/fib/fib.h>
29 #include <vnet/ipip/ipip.h>
30 
31 #include <vnet/vnet_msg_enum.h>
32 
33 #if WITH_LIBSSL > 0
34 #include <vnet/ipsec/ipsec.h>
35 #include <vnet/ipsec/ipsec_tun.h>
36 #endif /* IPSEC */
37 
38 #define vl_typedefs /* define message structures */
39 #include <vnet/vnet_all_api_h.h>
40 #undef vl_typedefs
41 
42 #define vl_endianfun /* define message structures */
43 #include <vnet/vnet_all_api_h.h>
44 #undef vl_endianfun
45 
46 /* instantiate all the print functions we know about */
47 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
48 #define vl_printfun
49 #include <vnet/vnet_all_api_h.h>
50 #undef vl_printfun
51 
53 
54 #define foreach_vpe_api_msg \
55 _(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \
56 _(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \
57 _(IPSEC_SPD_ENTRY_ADD_DEL, ipsec_spd_entry_add_del) \
58 _(IPSEC_SAD_ENTRY_ADD_DEL, ipsec_sad_entry_add_del) \
59 _(IPSEC_SA_DUMP, ipsec_sa_dump) \
60 _(IPSEC_SPDS_DUMP, ipsec_spds_dump) \
61 _(IPSEC_SPD_DUMP, ipsec_spd_dump) \
62 _(IPSEC_SPD_INTERFACE_DUMP, ipsec_spd_interface_dump) \
63 _(IPSEC_TUNNEL_IF_ADD_DEL, ipsec_tunnel_if_add_del) \
64 _(IPSEC_TUNNEL_IF_SET_SA, ipsec_tunnel_if_set_sa) \
65 _(IPSEC_SELECT_BACKEND, ipsec_select_backend) \
66 _(IPSEC_BACKEND_DUMP, ipsec_backend_dump) \
67 _(IPSEC_TUNNEL_PROTECT_UPDATE, ipsec_tunnel_protect_update) \
68 _(IPSEC_TUNNEL_PROTECT_DEL, ipsec_tunnel_protect_del) \
69 _(IPSEC_TUNNEL_PROTECT_DUMP, ipsec_tunnel_protect_dump)
70 
71 static void
73 {
74 #if WITH_LIBSSL == 0
75  clib_warning ("unimplemented");
76 #else
77 
78  vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
79  vl_api_ipsec_spd_add_del_reply_t *rmp;
80  int rv;
81 
82  rv = ipsec_add_del_spd (vm, ntohl (mp->spd_id), mp->is_add);
83 
84  REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_REPLY);
85 #endif
86 }
87 
90 {
91  vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
92  vl_api_ipsec_interface_add_del_spd_reply_t *rmp;
93  int rv;
94  u32 sw_if_index __attribute__ ((unused));
95  u32 spd_id __attribute__ ((unused));
96 
97  sw_if_index = ntohl (mp->sw_if_index);
98  spd_id = ntohl (mp->spd_id);
99 
101 
102 #if WITH_LIBSSL > 0
103  rv = ipsec_set_interface_spd (vm, sw_if_index, spd_id, mp->is_add);
104 #else
105  rv = VNET_API_ERROR_UNIMPLEMENTED;
106 #endif
107 
109 
110  REPLY_MACRO (VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY);
111 }
112 
115 {
116  vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
117  vl_api_ipsec_tunnel_protect_update_reply_t *rmp;
118  u32 sw_if_index, ii, *sa_ins = NULL;
119  int rv;
120 
121  sw_if_index = ntohl (mp->tunnel.sw_if_index);
122 
123  VALIDATE_SW_IF_INDEX (&(mp->tunnel));
124 
125 #if WITH_LIBSSL > 0
126 
127  for (ii = 0; ii < mp->tunnel.n_sa_in; ii++)
128  vec_add1 (sa_ins, ntohl (mp->tunnel.sa_in[ii]));
129 
130  rv = ipsec_tun_protect_update (sw_if_index,
131  ntohl (mp->tunnel.sa_out), sa_ins);
132 #else
133  rv = VNET_API_ERROR_UNIMPLEMENTED;
134 #endif
135 
137 
138  REPLY_MACRO (VL_API_IPSEC_TUNNEL_PROTECT_UPDATE_REPLY);
139 }
140 
143 {
144  vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
145  vl_api_ipsec_tunnel_protect_del_reply_t *rmp;
146  int rv;
148 
149  sw_if_index = ntohl (mp->sw_if_index);
150 
152 
153 #if WITH_LIBSSL > 0
154  rv = ipsec_tun_protect_del (sw_if_index);
155 #else
156  rv = VNET_API_ERROR_UNIMPLEMENTED;
157 #endif
158 
160 
161  REPLY_MACRO (VL_API_IPSEC_TUNNEL_PROTECT_DEL_REPLY);
162 }
163 
165 {
169 
170 static walk_rc_t
172 {
173  ipsec_dump_walk_ctx_t *ctx = arg;
175  ipsec_tun_protect_t *itp;
176  u32 sai, ii = 0;
177 
178  itp = ipsec_tun_protect_get (itpi);
179 
180 
181  mp = vl_msg_api_alloc (sizeof (*mp) + (sizeof (u32) * itp->itp_n_sa_in));
182  clib_memset (mp, 0, sizeof (*mp));
183  mp->_vl_msg_id = ntohs (VL_API_IPSEC_TUNNEL_PROTECT_DETAILS);
184  mp->context = ctx->context;
185 
186  mp->tun.sw_if_index = htonl (itp->itp_sw_if_index);
187 
188  mp->tun.sa_out = htonl (itp->itp_out_sa);
189  mp->tun.n_sa_in = itp->itp_n_sa_in;
190  /* *INDENT-OFF* */
192  ({
193  mp->tun.sa_in[ii++] = htonl (sai);
194  }));
195  /* *INDENT-ON* */
196 
197  vl_api_send_msg (ctx->reg, (u8 *) mp);
198 
199  return (WALK_CONTINUE);
200 }
201 
202 static void
204  * mp)
205 {
208 
209 #if WITH_LIBSSL > 0
211  if (!reg)
212  return;
213 
215  .reg = reg,
216  .context = mp->context,
217  };
218 
219  sw_if_index = ntohl (mp->sw_if_index);
220 
221  if (~0 == sw_if_index)
222  {
224  }
225  else
226  {
227  index_t itpi;
228 
229  itpi = ipsec_tun_protect_find (sw_if_index);
230 
231  if (INDEX_INVALID != itpi)
233  }
234 #else
235  clib_warning ("unimplemented");
236 #endif
237 }
238 
239 static int
240 ipsec_spd_action_decode (vl_api_ipsec_spd_action_t in,
241  ipsec_policy_action_t * out)
242 {
243  in = clib_net_to_host_u32 (in);
244 
245  switch (in)
246  {
247 #define _(v,f,s) case IPSEC_API_SPD_ACTION_##f: \
248  *out = IPSEC_POLICY_ACTION_##f; \
249  return (0);
251 #undef _
252  }
253  return (VNET_API_ERROR_UNIMPLEMENTED);
254 }
255 
258 {
259  vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
261  ip46_type_t itype;
262  u32 stat_index;
263  int rv;
264 
265  stat_index = ~0;
266 
267 #if WITH_LIBSSL > 0
268  ipsec_policy_t p;
269 
270  clib_memset (&p, 0, sizeof (p));
271 
272  p.id = ntohl (mp->entry.spd_id);
273  p.priority = ntohl (mp->entry.priority);
274 
275  itype = ip_address_decode (&mp->entry.remote_address_start, &p.raddr.start);
276  ip_address_decode (&mp->entry.remote_address_stop, &p.raddr.stop);
277  ip_address_decode (&mp->entry.local_address_start, &p.laddr.start);
278  ip_address_decode (&mp->entry.local_address_stop, &p.laddr.stop);
279 
280  p.is_ipv6 = (itype == IP46_TYPE_IP6);
281 
282  p.protocol = mp->entry.protocol;
283  p.rport.start = ntohs (mp->entry.remote_port_start);
284  p.rport.stop = ntohs (mp->entry.remote_port_stop);
285  p.lport.start = ntohs (mp->entry.local_port_start);
286  p.lport.stop = ntohs (mp->entry.local_port_stop);
287 
288  rv = ipsec_spd_action_decode (mp->entry.policy, &p.policy);
289 
290  if (rv)
291  goto out;
292 
293  /* policy action resolve unsupported */
294  if (p.policy == IPSEC_POLICY_ACTION_RESOLVE)
295  {
296  clib_warning ("unsupported action: 'resolve'");
297  rv = VNET_API_ERROR_UNIMPLEMENTED;
298  goto out;
299  }
300  p.sa_id = ntohl (mp->entry.sa_id);
301  rv =
302  ipsec_policy_mk_type (mp->entry.is_outbound, p.is_ipv6, p.policy,
303  &p.type);
304  if (rv)
305  goto out;
306 
307  rv = ipsec_add_del_policy (vm, &p, mp->is_add, &stat_index);
308  if (rv)
309  goto out;
310 
311 #else
312  rv = VNET_API_ERROR_UNIMPLEMENTED;
313  goto out;
314 #endif
315 
316 out:
317  /* *INDENT-OFF* */
318  REPLY_MACRO2 (VL_API_IPSEC_SPD_ENTRY_ADD_DEL_REPLY,
319  ({
320  rmp->stat_index = ntohl(stat_index);
321  }));
322  /* *INDENT-ON* */
323 }
324 
327 {
328  vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
330  ip46_address_t tun_src = { }, tun_dst =
331  {
332  };
333  ipsec_key_t crypto_key, integ_key;
334  ipsec_crypto_alg_t crypto_alg;
335  ipsec_integ_alg_t integ_alg;
338  u32 id, spi, sa_index = ~0;
339  int rv;
340 
341 #if WITH_LIBSSL > 0
342 
343  id = ntohl (mp->entry.sad_id);
344  spi = ntohl (mp->entry.spi);
345 
346  rv = ipsec_proto_decode (mp->entry.protocol, &proto);
347 
348  if (rv)
349  goto out;
350 
351  rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &crypto_alg);
352 
353  if (rv)
354  goto out;
355 
356  rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &integ_alg);
357 
358  if (rv)
359  goto out;
360 
361  ipsec_key_decode (&mp->entry.crypto_key, &crypto_key);
362  ipsec_key_decode (&mp->entry.integrity_key, &integ_key);
363 
364  flags = ipsec_sa_flags_decode (mp->entry.flags);
365 
366  ip_address_decode (&mp->entry.tunnel_src, &tun_src);
367  ip_address_decode (&mp->entry.tunnel_dst, &tun_dst);
368 
369  if (mp->is_add)
370  rv = ipsec_sa_add_and_lock (id, spi, proto,
371  crypto_alg, &crypto_key,
372  integ_alg, &integ_key, flags,
373  0, mp->entry.salt, &tun_src, &tun_dst,
374  &sa_index);
375  else
376  rv = ipsec_sa_unlock_id (id);
377 
378 #else
379  rv = VNET_API_ERROR_UNIMPLEMENTED;
380 #endif
381 
382 out:
383  /* *INDENT-OFF* */
384  REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_REPLY,
385  {
386  rmp->stat_index = htonl (sa_index);
387  });
388  /* *INDENT-ON* */
389 }
390 
391 static void
393  u32 context)
394 {
396  u32 n_policies = 0;
397 
398  mp = vl_msg_api_alloc (sizeof (*mp));
399  clib_memset (mp, 0, sizeof (*mp));
400  mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPDS_DETAILS);
401  mp->context = context;
402 
403  mp->spd_id = htonl (spd->id);
404 #define _(s, n) n_policies += vec_len (spd->policies[IPSEC_SPD_POLICY_##s]);
406 #undef _
407  mp->npolicies = htonl (n_policies);
408 
409  vl_api_send_msg (reg, (u8 *) mp);
410 }
411 
412 static void
414 {
416  ipsec_main_t *im = &ipsec_main;
417  ipsec_spd_t *spd;
418 #if WITH_LIBSSL > 0
420  if (!reg)
421  return;
422 
423  /* *INDENT-OFF* */
424  pool_foreach (spd, im->spds, ({
425  send_ipsec_spds_details (spd, reg, mp->context);
426  }));
427  /* *INDENT-ON* */
428 #else
429  clib_warning ("unimplemented");
430 #endif
431 }
432 
433 vl_api_ipsec_spd_action_t
435 {
436  vl_api_ipsec_spd_action_t out = IPSEC_API_SPD_ACTION_BYPASS;
437 
438  switch (in)
439  {
440 #define _(v,f,s) case IPSEC_POLICY_ACTION_##f: \
441  out = IPSEC_API_SPD_ACTION_##f; \
442  break;
444 #undef _
445  }
446  return (clib_host_to_net_u32 (out));
447 }
448 
449 static void
451  u32 context)
452 {
454 
455  mp = vl_msg_api_alloc (sizeof (*mp));
456  clib_memset (mp, 0, sizeof (*mp));
457  mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_DETAILS);
458  mp->context = context;
459 
460  mp->entry.spd_id = htonl (p->id);
461  mp->entry.priority = htonl (p->priority);
462  mp->entry.is_outbound = ((p->type == IPSEC_SPD_POLICY_IP6_OUTBOUND) ||
463  (p->type == IPSEC_SPD_POLICY_IP4_OUTBOUND));
464 
466  &mp->entry.local_address_start);
468  &mp->entry.local_address_stop);
470  &mp->entry.remote_address_start);
472  &mp->entry.remote_address_stop);
473  mp->entry.local_port_start = htons (p->lport.start);
474  mp->entry.local_port_stop = htons (p->lport.stop);
475  mp->entry.remote_port_start = htons (p->rport.start);
476  mp->entry.remote_port_stop = htons (p->rport.stop);
477  mp->entry.protocol = p->protocol;
478  mp->entry.policy = ipsec_spd_action_encode (p->policy);
479  mp->entry.sa_id = htonl (p->sa_id);
480 
481  vl_api_send_msg (reg, (u8 *) mp);
482 }
483 
484 static void
486 {
488  ipsec_main_t *im = &ipsec_main;
491  ipsec_spd_t *spd;
492  uword *p;
493  u32 spd_index, *ii;
494 #if WITH_LIBSSL > 0
496  if (!reg)
497  return;
498 
499  p = hash_get (im->spd_index_by_spd_id, ntohl (mp->spd_id));
500  if (!p)
501  return;
502 
503  spd_index = p[0];
504  spd = pool_elt_at_index (im->spds, spd_index);
505 
506  /* *INDENT-OFF* */
508  vec_foreach(ii, spd->policies[ptype])
509  {
510  policy = pool_elt_at_index(im->policies, *ii);
511 
512  if (mp->sa_id == ~(0) || ntohl (mp->sa_id) == policy->sa_id)
513  send_ipsec_spd_details (policy, reg, mp->context);
514  }
515  }
516  /* *INDENT-ON* */
517 #else
518  clib_warning ("unimplemented");
519 #endif
520 }
521 
522 static void
525 {
527 
528  mp = vl_msg_api_alloc (sizeof (*mp));
529  clib_memset (mp, 0, sizeof (*mp));
530  mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_INTERFACE_DETAILS);
531  mp->context = context;
532 
533  mp->spd_index = htonl (spd_index);
534  mp->sw_if_index = htonl (sw_if_index);
535 
536  vl_api_send_msg (reg, (u8 *) mp);
537 }
538 
539 static void
541  mp)
542 {
543  ipsec_main_t *im = &ipsec_main;
545  u32 k, v, spd_index;
546 
547 #if WITH_LIBSSL > 0
549  if (!reg)
550  return;
551 
552  if (mp->spd_index_valid)
553  {
554  spd_index = ntohl (mp->spd_index);
555  /* *INDENT-OFF* */
557  if (v == spd_index)
558  send_ipsec_spd_interface_details(reg, v, k, mp->context);
559  }));
560  /* *INDENT-ON* */
561  }
562  else
563  {
564  /* *INDENT-OFF* */
566  send_ipsec_spd_interface_details(reg, v, k, mp->context);
567  }));
568  /* *INDENT-ON* */
569  }
570 
571 #else
572  clib_warning ("unimplemented");
573 #endif
574 }
575 
576 static u32
578 {
579  return (0x80000000 | ti);
580 }
581 
582 static u32
584 {
585  return (0xc0000000 | ti);
586 }
587 
588 static void
590  mp)
591 {
593  u32 sw_if_index = ~0;
594  int rv;
595 
596 #if WITH_LIBSSL > 0
597  ip46_address_t local_ip = ip46_address_initializer;
598  ip46_address_t remote_ip = ip46_address_initializer;
599  ipsec_key_t crypto_key, integ_key;
601  ip46_type_t local_ip_type, remote_ip_type;
602  ipip_transport_t transport;
603  u32 fib_index;
604 
605  local_ip_type = ip_address_decode (&mp->local_ip, &local_ip);
606  remote_ip_type = ip_address_decode (&mp->remote_ip, &remote_ip);
607  transport = (IP46_TYPE_IP6 == local_ip_type ?
609 
610  if (local_ip_type != remote_ip_type)
611  {
612  rv = VNET_API_ERROR_INVALID_VALUE;
613  goto done;
614  }
615 
616  flags = IPSEC_SA_FLAG_NONE;
617 
618  if (mp->udp_encap)
619  flags |= IPSEC_SA_FLAG_UDP_ENCAP;
620  if (mp->esn)
621  flags |= IPSEC_SA_FLAG_USE_ESN;
622  if (mp->anti_replay)
623  flags |= IPSEC_SA_FLAG_USE_ANTI_REPLAY;
624 
625  ipsec_mk_key (&crypto_key, mp->remote_crypto_key,
627  ipsec_mk_key (&integ_key, mp->remote_integ_key, mp->remote_integ_key_len);
628  ipsec_mk_key (&crypto_key, mp->local_crypto_key, mp->local_crypto_key_len);
629  ipsec_mk_key (&integ_key, mp->local_integ_key, mp->local_integ_key_len);
630 
631  fib_index =
632  fib_table_find (fib_proto_from_ip46 (local_ip_type),
633  ntohl (mp->tx_table_id));
634 
635  if (~0 == fib_index)
636  {
637  rv = VNET_API_ERROR_NO_SUCH_FIB;
638  goto done;
639  }
640 
641  if (mp->is_add)
642  {
643  // remote = input, local = output
644  /* create an ip-ip tunnel, then the two SA, then bind them */
645  rv = ipip_add_tunnel (transport,
646  (mp->renumber ? ntohl (mp->show_instance) : ~0),
647  &local_ip,
648  &remote_ip, fib_index,
649  IPIP_TUNNEL_FLAG_NONE, IP_DSCP_CS0, &sw_if_index);
650 
651  if (rv)
652  goto done;
653 
655  ntohl (mp->remote_spi),
657  mp->crypto_alg,
658  &crypto_key,
659  mp->integ_alg,
660  &integ_key,
661  (flags | IPSEC_SA_FLAG_IS_INBOUND),
662  ntohl (mp->tx_table_id),
663  mp->salt, &remote_ip, &local_ip, NULL);
664 
665  if (rv)
666  goto done;
667 
669  ntohl (mp->local_spi),
671  mp->crypto_alg,
672  &crypto_key,
673  mp->integ_alg,
674  &integ_key,
675  flags,
676  ntohl (mp->tx_table_id),
677  mp->salt, &local_ip, &remote_ip, NULL);
678 
679  if (rv)
680  goto done;
681 
682  rv = ipsec_tun_protect_update_one (sw_if_index,
684  (sw_if_index),
686  (sw_if_index));
687  if (rv)
688  goto done;
689 
690  /* the SAs are locked as a result of being used for proection,
691  * they cannot be removed from the API, since they cannot be refered
692  * to by the API. unlock them now, so that if the tunnel is rekeyed
693  * they-ll disapper
694  */
697  }
698  else
699  {
700  /* *INDENT-OFF* */
702  .transport = transport,
703  .fib_index = fib_index,
704  .src = local_ip,
705  .dst = remote_ip
706  };
707  /* *INDENT-ON* */
708 
710 
711  if (NULL != t)
712  {
715  }
716  else
717  rv = VNET_API_ERROR_NO_SUCH_ENTRY;
718  }
719 
720 #else
721  rv = VNET_API_ERROR_UNIMPLEMENTED;
722 #endif
723 done:
724  /* *INDENT-OFF* */
725  REPLY_MACRO2 (VL_API_IPSEC_TUNNEL_IF_ADD_DEL_REPLY,
726  ({
727  rmp->sw_if_index = htonl (sw_if_index);
728  }));
729  /* *INDENT-ON* */
730 }
731 
733 {
737 
738 static walk_rc_t
740 {
742  ipsec_tun_protect_t *itp;
743  index_t sai;
744 
745  itp = ipsec_tun_protect_get (itpi);
746 
747  if (itp->itp_out_sa == ctx->sai)
748  {
749  ctx->sw_if_index = itp->itp_sw_if_index;
750  return (WALK_STOP);
751  }
752  /* *INDENT-OFF* */
754  ({
755  if (sai == ctx->sai)
756  {
757  ctx->sw_if_index = itp->itp_sw_if_index;
758  return (WALK_STOP);
759  }
760  }));
761  /* *INDENT-OFF* */
762 
763  return (WALK_CONTINUE);
764 }
765 
766 static walk_rc_t
768 {
769  ipsec_dump_walk_ctx_t *ctx = arg;
771  ipsec_main_t *im = &ipsec_main;
772 
773  mp = vl_msg_api_alloc (sizeof (*mp));
774  clib_memset (mp, 0, sizeof (*mp));
775  mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_DETAILS);
776  mp->context = ctx->context;
777 
778  mp->entry.sad_id = htonl (sa->id);
779  mp->entry.spi = htonl (sa->spi);
780  mp->entry.protocol = ipsec_proto_encode (sa->protocol);
781  mp->entry.tx_table_id =
783 
784  mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
785  ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
786 
787  mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
788  ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
789 
790  mp->entry.flags = ipsec_sad_flags_encode (sa);
791  mp->entry.salt = clib_host_to_net_u32 (sa->salt);
792 
793  if (ipsec_sa_is_set_IS_PROTECT (sa))
794  {
796  .sai = sa - im->sad,
797  .sw_if_index = ~0,
798  };
800 
801  mp->sw_if_index = htonl (ctx.sw_if_index);
802  }
803  else
804  mp->sw_if_index = ~0;
805 
806  if (ipsec_sa_is_set_IS_TUNNEL (sa))
807  {
809  &mp->entry.tunnel_src);
811  &mp->entry.tunnel_dst);
812  }
813 
814  mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
815  mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
816  if (ipsec_sa_is_set_USE_ESN (sa))
817  {
818  mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
819  mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
820  }
821  if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
822  mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
823 
824  vl_api_send_msg (ctx->reg, (u8 *) mp);
825 
826  return (WALK_CONTINUE);
827 }
828 
829 static void
831 {
833 
834 #if WITH_LIBSSL > 0
836  if (!reg)
837  return;
838 
840  .reg = reg,
841  .context = mp->context,
842  };
843 
845 
846 #else
847  clib_warning ("unimplemented");
848 #endif
849 }
850 
851 static void
853 {
854  vl_api_ipsec_tunnel_if_set_sa_reply_t *rmp;
855  int rv;
856 
857 #if WITH_LIBSSL > 0
859 
860  if (mp->is_outbound)
861  rv = ipsec_tun_protect_update_out (ntohl (mp->sw_if_index),
862  ntohl (mp->sa_id));
863  else
864  rv = ipsec_tun_protect_update_in (ntohl (mp->sw_if_index),
865  ntohl (mp->sa_id));
866 
867 #else
868  clib_warning ("unimplemented");
869 #endif
870 
872 
873  REPLY_MACRO (VL_API_IPSEC_TUNNEL_IF_SET_SA_REPLY);
874 }
875 
876 static void
878 {
880  ipsec_main_t *im = &ipsec_main;
881  u32 context = mp->context;
882 
884 
885  if (rp == 0)
886  {
887  clib_warning ("Client %d AWOL", mp->client_index);
888  return;
889  }
890 
891  ipsec_ah_backend_t *ab;
893  /* *INDENT-OFF* */
894  pool_foreach (ab, im->ah_backends, {
895  vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
896  clib_memset (mp, 0, sizeof (*mp));
897  mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS);
898  mp->context = context;
899  snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (ab->name),
900  ab->name);
901  mp->protocol = ntohl (IPSEC_API_PROTO_AH);
902  mp->index = ab - im->ah_backends;
903  mp->active = mp->index == im->ah_current_backend ? 1 : 0;
904  vl_api_send_msg (rp, (u8 *)mp);
905  });
906  pool_foreach (eb, im->esp_backends, {
907  vl_api_ipsec_backend_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
908  clib_memset (mp, 0, sizeof (*mp));
909  mp->_vl_msg_id = ntohs (VL_API_IPSEC_BACKEND_DETAILS);
910  mp->context = context;
911  snprintf ((char *)mp->name, sizeof (mp->name), "%.*s", vec_len (eb->name),
912  eb->name);
913  mp->protocol = ntohl (IPSEC_API_PROTO_ESP);
914  mp->index = eb - im->esp_backends;
915  mp->active = mp->index == im->esp_current_backend ? 1 : 0;
916  vl_api_send_msg (rp, (u8 *)mp);
917  });
918  /* *INDENT-ON* */
919 }
920 
921 static void
923 {
924  ipsec_main_t *im = &ipsec_main;
925  vl_api_ipsec_select_backend_reply_t *rmp;
927  int rv = 0;
928  if (pool_elts (im->sad) > 0)
929  {
930  rv = VNET_API_ERROR_INSTANCE_IN_USE;
931  goto done;
932  }
933 
934  rv = ipsec_proto_decode (mp->protocol, &protocol);
935 
936  if (rv)
937  goto done;
938 
939 #if WITH_LIBSSL > 0
940  switch (protocol)
941  {
942  case IPSEC_PROTOCOL_ESP:
943  rv = ipsec_select_esp_backend (im, mp->index);
944  break;
945  case IPSEC_PROTOCOL_AH:
946  rv = ipsec_select_ah_backend (im, mp->index);
947  break;
948  default:
949  rv = VNET_API_ERROR_INVALID_PROTOCOL;
950  break;
951  }
952 #else
953  clib_warning ("unimplemented"); /* FIXME */
954 #endif
955 done:
956  REPLY_MACRO (VL_API_IPSEC_SELECT_BACKEND_REPLY);
957 }
958 
959 /*
960  * ipsec_api_hookup
961  * Add vpe's API message handlers to the table.
962  * vlib has already mapped shared memory and
963  * added the client registration handlers.
964  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
965  */
966 #define vl_msg_name_crc_list
967 #include <vnet/vnet_all_api_h.h>
968 #undef vl_msg_name_crc_list
969 
970 static void
972 {
973 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
974  foreach_vl_msg_name_crc_ipsec;
975 #undef _
976 }
977 
978 static clib_error_t *
980 {
981  api_main_t *am = vlibapi_get_main ();
982 
983 #define _(N,n) \
984  vl_msg_api_set_handlers(VL_API_##N, #n, \
985  vl_api_##n##_t_handler, \
986  vl_noop_handler, \
987  vl_api_##n##_t_endian, \
988  vl_api_##n##_t_print, \
989  sizeof(vl_api_##n##_t), 1);
991 #undef _
992 
993  /*
994  * Set up the (msg_name, crc, message-id) table
995  */
997 
998  return 0;
999 }
1000 
1002 
1003 /*
1004  * fd.io coding-style-patch-verification: ON
1005  *
1006  * Local Variables:
1007  * eval: (c-set-style "gnu")
1008  * End:
1009  */
u32 spi
ipsec_spd_t * spds
Definition: ipsec.h:100
IPsec: Add/delete Security Policy Database entry.
Definition: ipsec.api:118
u8 proto
Definition: acl_types.api:47
vl_api_ipsec_spd_action_t ipsec_spd_action_encode(ipsec_policy_action_t in)
Definition: ipsec_api.c:434
void ipsec_key_decode(const vl_api_key_t *key, ipsec_key_t *out)
ip46_address_t tunnel_src_addr
Definition: ipsec_sa.h:156
enum ipsec_spd_policy_t_ ipsec_spd_policy_type_t
IPsec: SPD interface response.
Definition: ipsec.api:299
A representation of a IPIP tunnel.
Definition: ipip.h:92
Dump IPsec backends.
Definition: ipsec.api:447
ipsec_integ_alg_t
Definition: ipsec_sa.h:58
VLIB_API_INIT_FUNCTION(ipsec_api_hookup)
int ipip_add_tunnel(ipip_transport_t transport, u32 instance, ip46_address_t *src, ip46_address_t *dst, u32 fib_index, ipip_tunnel_flags_t flags, ip_dscp_t dscp, u32 *sw_if_indexp)
Definition: ipip.c:414
unsigned long u64
Definition: types.h:89
ip46_address_range_t laddr
#define REPLY_MACRO2(t, body)
#define NULL
Definition: clib.h:58
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
#define FOR_EACH_IPSEC_SPD_POLICY_TYPE(_t)
Definition: ipsec_spd.h:36
int ipsec_policy_mk_type(bool is_outbound, bool is_ipv6, ipsec_policy_action_t action, ipsec_spd_policy_type_t *type)
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:35
ipsec_key_t crypto_key
Definition: ipsec_sa.h:149
ipsec_integ_alg_t integ_alg
Definition: ipsec_sa.h:152
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
ipsec_protocol_t
Definition: ipsec_sa.h:66
static void setup_message_id_table(api_main_t *am)
Definition: ipsec_api.c:971
int ipsec_integ_algo_decode(vl_api_ipsec_integ_alg_t in, ipsec_integ_alg_t *out)
vl_api_ipsec_spd_action_t policy
Definition: ipsec.api:96
static void vl_api_ipsec_sa_dump_t_handler(vl_api_ipsec_sa_dump_t *mp)
Definition: ipsec_api.c:830
int ipsec_select_ah_backend(ipsec_main_t *im, u32 backend_idx)
Definition: ipsec.c:225
A Secruity Policy Database.
Definition: ipsec_spd.h:44
void * vl_msg_api_alloc(int nbytes)
void ipsec_tun_protect_walk(ipsec_tun_protect_walk_cb_t fn, void *ctx)
Definition: ipsec_tun.c:511
void ipsec_mk_key(ipsec_key_t *key, const u8 *data, u8 len)
Definition: ipsec_sa.c:56
u8 is_add
Definition: ipsec.api:122
unsigned char u8
Definition: types.h:56
#define foreach_vpe_api_msg
Definition: ipsec_api.c:54
vl_api_interface_index_t sw_if_index
Definition: ipsec.api:271
vl_api_address_t remote_ip
Definition: ipsec.api:343
u8 id[64]
Definition: dhcp.api:160
struct ipsec_sa_dump_match_ctx_t_ ipsec_sa_dump_match_ctx_t
u32 seq_hi
Definition: ipsec_sa.h:121
uword * spd_index_by_sw_if_index
Definition: ipsec.h:114
static void vl_api_ipsec_interface_add_del_spd_t_handler(vl_api_ipsec_interface_add_del_spd_t *mp)
Definition: ipsec_api.c:89
enum walk_rc_t_ walk_rc_t
Walk return code.
vl_api_interface_index_t sw_if_index
Definition: ipsec.api:261
u64 replay_window
Definition: ipsec_sa.h:124
vl_api_ip_proto_t protocol
Definition: lb_types.api:71
void ipsec_sa_walk(ipsec_sa_walk_cb_t cb, void *ctx)
Definition: ipsec_sa.c:378
Select IPsec backend.
Definition: ipsec.api:472
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:498
vl_api_interface_index_t sw_if_index
Definition: gre.api:59
ipsec_main_t ipsec_main
Definition: ipsec.c:28
Definition: ipsec.api:195
static void vl_api_ipsec_tunnel_if_add_del_t_handler(vl_api_ipsec_tunnel_if_add_del_t *mp)
Definition: ipsec_api.c:589
static void vl_api_ipsec_backend_dump_t_handler(vl_api_ipsec_backend_dump_t *mp)
Definition: ipsec_api.c:877
int ipsec_select_esp_backend(ipsec_main_t *im, u32 backend_idx)
Definition: ipsec.c:248
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:442
static void vl_api_ipsec_spd_dump_t_handler(vl_api_ipsec_spd_dump_t *mp)
Definition: ipsec_api.c:485
static void vl_api_ipsec_spd_interface_dump_t_handler(vl_api_ipsec_spd_interface_dump_t *mp)
Definition: ipsec_api.c:540
vl_api_address_t local_ip
Definition: ipsec.api:342
int ipsec_sa_unlock_id(u32 id)
Definition: ipsec_sa.c:356
port_range_t rport
Dump all tunnel protections.
Definition: ipsec.api:267
unsigned int u32
Definition: types.h:88
vl_api_ipsec_crypto_alg_t ipsec_crypto_algo_encode(ipsec_crypto_alg_t c)
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1097
IPsec: Reply Add/delete Security Policy Database entry.
Definition: ipsec.api:132
ip46_type_t ip_address_decode(const vl_api_address_t *in, ip46_address_t *out)
Definition: ip_types_api.c:161
static void vl_api_ipsec_spd_add_del_t_handler(vl_api_ipsec_spd_add_del_t *mp)
Definition: ipsec_api.c:72
fib_protocol_t fib_proto_from_ip46(ip46_type_t iproto)
Convert from ip46_type to fib_protocol.
Definition: fib_types.c:326
u32 last_seq
Definition: ipsec_sa.h:122
#define hash_get(h, key)
Definition: hash.h:249
IPsec: Add/delete Security Association Database entry.
Definition: ipsec.api:188
u32 tx_fib_index
Definition: ipsec_sa.h:162
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:519
Dump IPsec all SPD IDs response.
Definition: ipsec.api:153
int ipsec_tun_protect_update_in(u32 sw_if_index, u32 sa_in)
Definition: ipsec_tun.c:318
Add/delete IPsec tunnel interface response.
Definition: ipsec.api:368
ipip_tunnel_t * ipip_tunnel_db_find(ipip_tunnel_key_t *key)
Definition: ipip.c:370
long ctx[MAX_CONNS]
Definition: main.c:144
IPsec: Add/delete Security Policy Database.
Definition: ipsec.api:29
u32 salt
Definition: ipsec_sa.h:165
vl_api_ipsec_tunnel_protect_t tun
Definition: ipsec.api:277
vl_api_ipsec_proto_t ipsec_proto_encode(ipsec_protocol_t p)
int ipsec_add_del_policy(vlib_main_t *vm, ipsec_policy_t *policy, int is_add, u32 *stat_index)
Add/Delete a SPD.
u32 last_seq_hi
Definition: ipsec_sa.h:123
static int ipsec_spd_action_decode(vl_api_ipsec_spd_action_t in, ipsec_policy_action_t *out)
Definition: ipsec_api.c:240
#define REPLY_MACRO(t)
vl_api_ipsec_tunnel_protect_t tunnel
Definition: ipsec.api:253
ipsec_spd_policy_type_t type
int ipsec_tun_protect_del(u32 sw_if_index)
Definition: ipsec_tun.c:480
vlib_main_t * vm
Definition: in2out_ed.c:1810
ipsec_policy_action_t
uword * spd_index_by_spd_id
Definition: ipsec.h:113
static void vl_api_ipsec_tunnel_if_set_sa_t_handler(vl_api_ipsec_tunnel_if_set_sa_t *mp)
Definition: ipsec_api.c:852
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:225
ip46_address_t tunnel_dst_addr
Definition: ipsec_sa.h:157
An API client registration, only in vpp/vlib.
Definition: api_common.h:46
#define BAD_SW_IF_INDEX_LABEL
IPsec: Add/delete SPD from interface.
Definition: ipsec.api:47
ipip_transport_t
IPIP Tunnel key.
Definition: ipip.h:47
u32 flags
Definition: vhost_user.h:141
static walk_rc_t ipsec_sa_dump_match_sa(index_t itpi, void *arg)
Definition: ipsec_api.c:739
int ipsec_tun_protect_update(u32 sw_if_index, u32 sa_out, u32 *sas_in)
Definition: ipsec_tun.c:362
ipsec_ah_backend_t * ah_backends
Definition: ipsec.h:158
vl_api_ipsec_sad_flags_t ipsec_sad_flags_encode(const ipsec_sa_t *sa)
Dump IPsec all SPD IDs.
Definition: ipsec.api:143
vl_api_ipsec_sad_entry_t entry
Definition: ipsec.api:193
ipsec_policy_action_t policy
ip46_address_t start
#define clib_warning(format, args...)
Definition: error.h:59
vl_api_key_t crypto_key
enum ipsec_sad_flags_t_ ipsec_sa_flags_t
vl_api_ipsec_proto_t protocol
Definition: ipsec.api:475
#define FOR_EACH_IPSEC_PROTECT_INPUT_SAI(_itp, _sai, body)
Definition: ipsec_tun.h:82
static u32 ipsec_tun_mk_input_sa_id(u32 ti)
Definition: ipsec_api.c:577
Set new SA on IPsec interface.
Definition: ipsec.api:435
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:57
A Secruity Policy.
static void vl_api_ipsec_spds_dump_t_handler(vl_api_ipsec_spds_dump_t *mp)
Definition: ipsec_api.c:413
static void vl_api_ipsec_tunnel_protect_dump_t_handler(vl_api_ipsec_tunnel_protect_dump_t *mp)
Definition: ipsec_api.c:203
static void send_ipsec_spd_interface_details(vl_api_registration_t *reg, u32 spd_index, u32 sw_if_index, u32 context)
Definition: ipsec_api.c:523
vl_api_ipsec_sad_entry_t entry
Definition: ipsec.api:414
static void send_ipsec_spd_details(ipsec_policy_t *p, vl_api_registration_t *reg, u32 context)
Definition: ipsec_api.c:450
static void vl_api_ipsec_spd_entry_add_del_t_handler(vl_api_ipsec_spd_entry_add_del_t *mp)
Definition: ipsec_api.c:257
ipsec_policy_t * policies
Definition: ipsec.h:104
Dump IPsec security association.
Definition: ipsec.api:379
int ipsec_tun_protect_update_out(u32 sw_if_index, u32 sa_out)
Definition: ipsec_tun.c:268
ipsec_sa_t * sad
Definition: ipsec.h:102
u32 fib_table_get_table_id(u32 fib_index, fib_protocol_t proto)
Get the Table-ID of the FIB from protocol and index.
Definition: fib_table.c:1086
static ipsec_tun_protect_t * ipsec_tun_protect_get(u32 index)
Definition: ipsec_tun.h:138
vl_api_ipsec_integ_alg_t ipsec_integ_algo_encode(ipsec_integ_alg_t i)
u32 * policies[IPSEC_SPD_POLICY_N_TYPES]
vectors for each of the policy types
Definition: ipsec_spd.h:49
ipsec_sa_flags_t ipsec_sa_flags_decode(vl_api_ipsec_sad_flags_t in)
Dump ipsec policy database data.
Definition: ipsec.api:165
u32 stat_index
Definition: ipsec.api:136
ipsec_protocol_t protocol
Definition: ipsec_sa.h:146
static void vl_api_ipsec_tunnel_protect_update_t_handler(vl_api_ipsec_tunnel_protect_update_t *mp)
Definition: ipsec_api.c:114
static void send_ipsec_spds_details(ipsec_spd_t *spd, vl_api_registration_t *reg, u32 context)
Definition: ipsec_api.c:392
u32 sw_if_index
Definition: ipip.h:104
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
IPsec policy database response.
Definition: ipsec.api:178
IPsec: Get SPD interfaces.
Definition: ipsec.api:287
vl_api_ipsec_spd_entry_t entry
Definition: ipsec.api:180
typedef key
Definition: ipsec_types.api:83
vl_api_ipsec_spd_entry_t entry
Definition: ipsec.api:123
struct ipsec_dump_walk_ctx_t_ ipsec_dump_walk_ctx_t
static walk_rc_t send_ipsec_sa_details(ipsec_sa_t *sa, void *arg)
Definition: ipsec_api.c:767
int ipsec_sa_add_and_lock(u32 id, u32 spi, ipsec_protocol_t proto, ipsec_crypto_alg_t crypto_alg, const ipsec_key_t *ck, ipsec_integ_alg_t integ_alg, const ipsec_key_t *ik, ipsec_sa_flags_t flags, u32 tx_table_id, u32 salt, const ip46_address_t *tun_src, const ip46_address_t *tun_dst, u32 *sa_out_index)
Definition: ipsec_sa.c:127
static u32 ipsec_tun_mk_output_sa_id(u32 ti)
Definition: ipsec_api.c:583
ip46_address_range_t raddr
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
u64 uword
Definition: types.h:112
int ipsec_tun_protect_update_one(u32 sw_if_index, u32 sa_out, u32 sa_in)
Definition: ipsec_tun.c:256
ipsec_crypto_alg_t
Definition: ipsec_sa.h:36
u8 is_add
Definition: ipsec.api:192
int ipip_del_tunnel(u32 sw_if_index)
Definition: ipip.c:512
int ipsec_set_interface_spd(vlib_main_t *vm, u32 sw_if_index, u32 spd_id, int is_add)
Bind/attach a SPD to an interface.
Definition: ipsec_spd.c:63
void ip_address_encode(const ip46_address_t *in, ip46_type_t type, vl_api_address_t *out)
Definition: ip_types_api.c:178
u32 id
the User&#39;s ID for this policy
Definition: ipsec_spd.h:47
static api_main_t * vlibapi_get_main(void)
Definition: api_common.h:378
vl_api_registration_t * reg
Definition: ipsec_api.c:166
ipsec_crypto_alg_t crypto_alg
Definition: ipsec_sa.h:148
port_range_t lport
index_t ipsec_tun_protect_find(u32 sw_if_index)
Definition: ipsec_tun.c:247
int ipsec_add_del_spd(vlib_main_t *vm, u32 spd_id, int is_add)
Add/Delete a SPD.
Definition: ipsec_spd.c:20
static clib_error_t * ipsec_api_hookup(vlib_main_t *vm)
Definition: ipsec_api.c:979
#define foreach_ipsec_spd_policy_type
Definition: ipsec_spd.h:20
static void vl_api_ipsec_tunnel_protect_del_t_handler(vl_api_ipsec_tunnel_protect_del_t *mp)
Definition: ipsec_api.c:142
#define vec_foreach(var, vec)
Vector iterator.
static walk_rc_t send_ipsec_tunnel_protect_details(index_t itpi, void *arg)
Definition: ipsec_api.c:171
static void vl_api_ipsec_select_backend_t_handler(vl_api_ipsec_select_backend_t *mp)
Definition: ipsec_api.c:922
IPsec security association database response.
Definition: ipsec.api:412
ipsec_esp_backend_t * esp_backends
Definition: ipsec.h:160
int ipsec_crypto_algo_decode(vl_api_ipsec_crypto_alg_t in, ipsec_crypto_alg_t *out)
ipsec_key_t integ_key
Definition: ipsec_sa.h:153
Add or delete IPsec tunnel interface.
Definition: ipsec.api:336
#define ip46_address_initializer
Definition: ip46_address.h:52
int ipsec_proto_decode(vl_api_ipsec_proto_t in, ipsec_protocol_t *out)
Encode/decode function from/to API to internal types.
#define VALIDATE_SW_IF_INDEX(mp)
ip46_type_t
Definition: ip46_address.h:22
u32 stat_index
Definition: ipsec.api:199
static void vl_api_ipsec_sad_entry_add_del_t_handler(vl_api_ipsec_sad_entry_add_del_t *mp)
Definition: ipsec_api.c:326
void ipsec_key_encode(const ipsec_key_t *in, vl_api_key_t *out)
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128