FD.io VPP  v19.04.2-12-g66b1689
Vector Packet Processing
ipsec_if.c
Go to the documentation of this file.
1 /*
2  * ipsec_if.c : IPSec interface support
3  *
4  * Copyright (c) 2015 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vnet/vnet.h>
19 #include <vnet/api_errno.h>
20 #include <vnet/ip/ip.h>
21 #include <vnet/fib/fib.h>
22 #include <vnet/udp/udp.h>
23 #include <vnet/adj/adj_midchain.h>
24 
25 #include <vnet/ipsec/ipsec.h>
26 #include <vnet/ipsec/esp.h>
27 
28 void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
29 
30 static u8 *
31 format_ipsec_name (u8 * s, va_list * args)
32 {
33  u32 dev_instance = va_arg (*args, u32);
34  ipsec_main_t *im = &ipsec_main;
35  ipsec_tunnel_if_t *t = im->tunnel_interfaces + dev_instance;
36 
37  return format (s, "ipsec%d", t->show_instance);
38 }
39 
40 /* Statistics (not really errors) */
41 #define foreach_ipsec_if_tx_error \
42 _(TX, "good packets transmitted")
43 
44 static void
46 {
47  ipsec_main_t *ipm = &ipsec_main;
49  ip_adjacency_t *adj;
51 
52  adj = adj_get (ai);
53  sw_if_index = adj->rewrite_header.sw_if_index;
54 
55  if ((vec_len (ipm->ipsec_if_by_sw_if_index) <= sw_if_index) ||
56  (~0 == ipm->ipsec_if_by_sw_if_index[sw_if_index]))
57  return;
58 
60  ipm->ipsec_if_by_sw_if_index[sw_if_index]);
61 
63  {
65  }
66  else
67  {
68  ipsec_sa_t *sa;
69 
70  sa = ipsec_sa_get (it->output_sa_index);
71 
72  /* *INDENT-OFF* */
73  fib_prefix_t pfx = {
74  .fp_addr = sa->tunnel_dst_addr,
75  .fp_len = (ipsec_sa_is_set_IS_TUNNEL_V6(sa) ? 128 : 32),
76  .fp_proto = (ipsec_sa_is_set_IS_TUNNEL_V6(sa) ?
79  };
80  /* *INDENT-ON* */
81 
83  }
84 }
85 
86 /**
87  * @brief Call back when restacking all adjacencies on a GRE interface
88  */
89 static adj_walk_rc_t
91 {
93 
94  return (ADJ_WALK_RC_CONTINUE);
95 }
96 
97 static void
99 {
100  fib_protocol_t proto;
101 
102  /*
103  * walk all the adjacencies on th GRE interface and restack them
104  */
106  {
108  }
109 }
110 
111 static clib_error_t *
113 {
114  ipsec_main_t *im = &ipsec_main;
115  clib_error_t *err = 0;
118  ipsec_sa_t *sa;
119 
120  hi = vnet_get_hw_interface (vnm, hw_if_index);
122  t->flags = flags;
123 
125  {
126  sa = pool_elt_at_index (im->sad, t->input_sa_index);
127 
128  err = ipsec_check_support_cb (im, sa);
129  if (err)
130  return err;
131 
132  err = ipsec_add_del_sa_sess_cb (im, t->input_sa_index, 1);
133  if (err)
134  return err;
135 
136  sa = pool_elt_at_index (im->sad, t->output_sa_index);
137 
138  err = ipsec_check_support_cb (im, sa);
139  if (err)
140  return err;
141 
142  err = ipsec_add_del_sa_sess_cb (im, t->output_sa_index, 1);
143  if (err)
144  return err;
145 
146  vnet_hw_interface_set_flags (vnm, hw_if_index,
148  }
149  else
150  {
151  vnet_hw_interface_set_flags (vnm, hw_if_index, 0 /* down */ );
152  sa = pool_elt_at_index (im->sad, t->input_sa_index);
153  err = ipsec_add_del_sa_sess_cb (im, t->input_sa_index, 0);
154  if (err)
155  return err;
156  sa = pool_elt_at_index (im->sad, t->output_sa_index);
157  err = ipsec_add_del_sa_sess_cb (im, t->output_sa_index, 0);
158  if (err)
159  return err;
160  }
161 
163 
164  return (NULL);
165 }
166 
167 static u8 *
170  vnet_link_t link_type, const void *dst_address)
171 {
172  return (NULL);
173 }
174 
175 static void
177 {
180  ipsec_if_build_rewrite (vnm, sw_if_index, adj_get_link_type (ai), NULL));
181 
183 }
184 
185 /* *INDENT-OFF* */
186 VNET_DEVICE_CLASS (ipsec_device_class) =
187 {
188  .name = "IPSec",
189  .format_device_name = format_ipsec_name,
190  .admin_up_down_function = ipsec_admin_up_down_function,
191 };
192 /* *INDENT-ON* */
193 
194 /* *INDENT-OFF* */
195 VNET_HW_INTERFACE_CLASS (ipsec_hw_class) =
196 {
197  .name = "IPSec",
198  .build_rewrite = default_build_rewrite,
199  .update_adjacency = ipsec_if_update_adj,
201 };
202 /* *INDENT-ON* */
203 
204 static int
206 {
207  vnet_main_t *vnm = vnet_get_main ();
208  ASSERT (vlib_get_thread_index () == 0);
209 
210  return ipsec_add_del_tunnel_if_internal (vnm, a, NULL);
211 }
212 
213 int
215 {
217  (u8 *) args, sizeof (*args));
218  return 0;
219 }
220 
221 static u32
223 {
224  return (0x80000000 | ti);
225 }
226 
227 static u32
229 {
230  return (0xc0000000 | ti);
231 }
232 
233 static void
235 {
236  u8 arc;
237 
238  arc = vnet_get_feature_arc_index ("ip4-output");
239 
242  t->sw_if_index, enable,
243  &t->output_sa_index,
244  sizeof (t->output_sa_index));
245 
246  arc = vnet_get_feature_arc_index ("ip6-output");
247 
250  t->sw_if_index, enable,
251  &t->output_sa_index,
252  sizeof (t->output_sa_index));
253 }
254 
255 int
258  u32 * sw_if_index)
259 {
261  ipsec_main_t *im = &ipsec_main;
263  u32 hw_if_index = ~0;
264  uword *p;
265  u32 dev_instance;
266  ipsec_key_t crypto_key, integ_key;
268  int rv;
269  int is_ip6 = args->is_ip6;
270  ipsec4_tunnel_key_t key4;
271  ipsec6_tunnel_key_t key6;
272 
273  if (!is_ip6)
274  {
275  key4.remote_ip = args->remote_ip.ip4.as_u32;
276  key4.spi = clib_host_to_net_u32 (args->remote_spi);
277  p = hash_get (im->ipsec4_if_pool_index_by_key, key4.as_u64);
278  }
279  else
280  {
281  key6.remote_ip = args->remote_ip.ip6;
282  key6.spi = clib_host_to_net_u32 (args->remote_spi);
283  p = hash_get_mem (im->ipsec6_if_pool_index_by_key, &key6);
284  }
285 
286  if (args->is_add)
287  {
288  /* check if same src/dst pair exists */
289  if (p)
290  return VNET_API_ERROR_INVALID_VALUE;
291 
293 
294  dev_instance = t - im->tunnel_interfaces;
295  if (args->renumber)
296  t->show_instance = args->show_instance;
297  else
298  t->show_instance = dev_instance;
299 
301  {
302  pool_put (im->tunnel_interfaces, t);
303  return VNET_API_ERROR_INSTANCE_IN_USE;
304  }
305 
307  dev_instance);
308 
309  flags = IPSEC_SA_FLAG_IS_TUNNEL;
310  if (args->is_ip6)
311  flags |= IPSEC_SA_FLAG_IS_TUNNEL_V6;
312  if (args->udp_encap)
313  flags |= IPSEC_SA_FLAG_UDP_ENCAP;
314  if (args->esn)
315  flags |= IPSEC_SA_FLAG_USE_ESN;
316  if (args->anti_replay)
317  flags |= IPSEC_SA_FLAG_USE_ANTI_REPLAY;
318 
319  ipsec_mk_key (&crypto_key,
321  ipsec_mk_key (&integ_key,
323 
324  rv = ipsec_sa_add (ipsec_tun_mk_input_sa_id (dev_instance),
325  args->remote_spi,
327  args->crypto_alg,
328  &crypto_key,
329  args->integ_alg,
330  &integ_key,
331  (flags | IPSEC_SA_FLAG_IS_INBOUND),
332  args->tx_table_id,
333  args->salt,
334  &args->remote_ip,
335  &args->local_ip, &t->input_sa_index);
336 
337  if (rv)
338  return VNET_API_ERROR_INVALID_SRC_ADDRESS;
339 
340  ipsec_mk_key (&crypto_key,
342  ipsec_mk_key (&integ_key,
343  args->local_integ_key, args->local_integ_key_len);
344 
345  rv = ipsec_sa_add (ipsec_tun_mk_output_sa_id (dev_instance),
346  args->local_spi,
348  args->crypto_alg,
349  &crypto_key,
350  args->integ_alg,
351  &integ_key,
352  flags,
353  args->tx_table_id,
354  args->salt,
355  &args->local_ip,
356  &args->remote_ip, &t->output_sa_index);
357 
358  if (rv)
359  return VNET_API_ERROR_INVALID_DST_ADDRESS;
360 
361  /* copy the key */
362  if (is_ip6)
364  t - im->tunnel_interfaces);
365  else
366  hash_set (im->ipsec4_if_pool_index_by_key, key4.as_u64,
367  t - im->tunnel_interfaces);
368 
369  hw_if_index = vnet_register_interface (vnm, ipsec_device_class.index,
370  t - im->tunnel_interfaces,
371  ipsec_hw_class.index,
372  t - im->tunnel_interfaces);
373 
374  hi = vnet_get_hw_interface (vnm, hw_if_index);
375 
376  t->hw_if_index = hw_if_index;
377  t->sw_if_index = hi->sw_if_index;
378 
379  /* Standard default jumbo MTU. */
380  vnet_sw_interface_set_mtu (vnm, t->sw_if_index, 9000);
381 
382  /* Add the new tunnel to the DB of tunnels per sw_if_index ... */
384  ~0);
385  im->ipsec_if_by_sw_if_index[t->sw_if_index] = dev_instance;
386 
387  ipsec_tunnel_feature_set (im, t, 1);
388 
389  /*1st interface, register protocol */
390  if (pool_elts (im->tunnel_interfaces) == 1)
391  {
392  ip4_register_protocol (IP_PROTOCOL_IPSEC_ESP,
393  ipsec4_if_input_node.index);
394  ip6_register_protocol (IP_PROTOCOL_IPSEC_ESP,
395  ipsec6_if_input_node.index);
396  }
397 
398  }
399  else
400  {
401  u32 ti;
402 
403  /* check if exists */
404  if (!p)
405  return VNET_API_ERROR_INVALID_VALUE;
406 
407  ti = p[0];
408  t = pool_elt_at_index (im->tunnel_interfaces, ti);
409  hi = vnet_get_hw_interface (vnm, t->hw_if_index);
410  vnet_sw_interface_set_flags (vnm, hi->sw_if_index, 0); /* admin down */
411 
412  ipsec_tunnel_feature_set (im, t, 0);
414 
415  if (is_ip6)
417  else
418  hash_unset (im->ipsec4_if_pool_index_by_key, key4.as_u64);
419 
422 
423  pool_put (im->tunnel_interfaces, t);
424 
425  /* delete input and output SA */
428  }
429 
430  if (sw_if_index)
431  *sw_if_index = hi->sw_if_index;
432 
433  return 0;
434 }
435 
436 int
438  const ipsec_gre_tunnel_add_del_args_t * args)
439 {
440  ipsec_tunnel_if_t *t = 0;
441  ipsec_main_t *im = &ipsec_main;
442  uword *p;
443  ipsec_sa_t *sa;
444  ipsec4_tunnel_key_t key;
445  u32 isa, osa;
446 
447  p = hash_get (im->sa_index_by_sa_id, args->local_sa_id);
448  if (!p)
449  return VNET_API_ERROR_INVALID_VALUE;
450  osa = p[0];
451  sa = pool_elt_at_index (im->sad, p[0]);
452  ipsec_sa_set_IS_GRE (sa);
453 
454  p = hash_get (im->sa_index_by_sa_id, args->remote_sa_id);
455  if (!p)
456  return VNET_API_ERROR_INVALID_VALUE;
457  isa = p[0];
458  sa = pool_elt_at_index (im->sad, p[0]);
459  ipsec_sa_set_IS_GRE (sa);
460 
461  /* we form the key from the input/remote SA whose tunnel is srouce
462  * at the remote end */
463  if (ipsec_sa_is_set_IS_TUNNEL (sa))
464  {
465  key.remote_ip = sa->tunnel_src_addr.ip4.as_u32;
466  key.spi = clib_host_to_net_u32 (sa->spi);
467  }
468  else
469  {
470  key.remote_ip = args->src.as_u32;
471  key.spi = clib_host_to_net_u32 (sa->spi);
472  }
473 
474  p = hash_get (im->ipsec4_if_pool_index_by_key, key.as_u64);
475 
476  if (args->is_add)
477  {
478  /* check if same src/dst pair exists */
479  if (p)
480  return VNET_API_ERROR_INVALID_VALUE;
481 
483  clib_memset (t, 0, sizeof (*t));
484 
485  t->input_sa_index = isa;
486  t->output_sa_index = osa;
487  t->hw_if_index = ~0;
488  hash_set (im->ipsec4_if_pool_index_by_key, key.as_u64,
489  t - im->tunnel_interfaces);
490 
491  /*1st interface, register protocol */
492  if (pool_elts (im->tunnel_interfaces) == 1)
493  {
494  ip4_register_protocol (IP_PROTOCOL_IPSEC_ESP,
495  ipsec4_if_input_node.index);
496  /* TBD, GRE IPSec6
497  *
498  ip6_register_protocol (IP_PROTOCOL_IPSEC_ESP,
499  ipsec6_if_input_node.index);
500  */
501  }
502  }
503  else
504  {
505  /* check if exists */
506  if (!p)
507  return VNET_API_ERROR_INVALID_VALUE;
508 
509  t = pool_elt_at_index (im->tunnel_interfaces, p[0]);
510  hash_unset (im->ipsec4_if_pool_index_by_key, key.as_u64);
511  pool_put (im->tunnel_interfaces, t);
512  }
513  return 0;
514 }
515 
516 int
518  ipsec_if_set_key_type_t type, u8 alg, u8 * key)
519 {
520  ipsec_main_t *im = &ipsec_main;
523  ipsec_sa_t *sa;
524 
525  hi = vnet_get_hw_interface (vnm, hw_if_index);
527 
529  return VNET_API_ERROR_SYSCALL_ERROR_1;
530 
532  {
533  sa = pool_elt_at_index (im->sad, t->output_sa_index);
534  ipsec_sa_set_crypto_alg (sa, alg);
535  ipsec_mk_key (&sa->crypto_key, key, vec_len (key));
536  }
537  else if (type == IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG)
538  {
539  sa = pool_elt_at_index (im->sad, t->output_sa_index);
540  ipsec_sa_set_integ_alg (sa, alg);
541  ipsec_mk_key (&sa->integ_key, key, vec_len (key));
542  }
543  else if (type == IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO)
544  {
545  sa = pool_elt_at_index (im->sad, t->input_sa_index);
546  ipsec_sa_set_crypto_alg (sa, alg);
547  ipsec_mk_key (&sa->crypto_key, key, vec_len (key));
548  }
549  else if (type == IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG)
550  {
551  sa = pool_elt_at_index (im->sad, t->input_sa_index);
552  ipsec_sa_set_integ_alg (sa, alg);
553  ipsec_mk_key (&sa->integ_key, key, vec_len (key));
554  }
555  else
556  return VNET_API_ERROR_INVALID_VALUE;
557 
558  return 0;
559 }
560 
561 
562 int
564  u8 is_outbound)
565 {
566  ipsec_main_t *im = &ipsec_main;
569  ipsec_sa_t *sa, *old_sa;
570  u32 sa_index, old_sa_index;
571  uword *p;
572 
573  hi = vnet_get_hw_interface (vnm, hw_if_index);
575 
576  sa_index = ipsec_get_sa_index_by_sa_id (sa_id);
577  if (sa_index == ~0)
578  {
579  clib_warning ("SA with ID %u not found", sa_id);
580  return VNET_API_ERROR_INVALID_VALUE;
581  }
582 
583  if (ipsec_is_sa_used (sa_index))
584  {
585  clib_warning ("SA with ID %u is already in use", sa_id);
586  return VNET_API_ERROR_INVALID_VALUE;
587  }
588 
589  sa = pool_elt_at_index (im->sad, sa_index);
590 
591  if (!is_outbound)
592  {
593  old_sa_index = t->input_sa_index;
594  old_sa = pool_elt_at_index (im->sad, old_sa_index);
595 
596  if (ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ^
597  ipsec_sa_is_set_IS_TUNNEL_V6 (old_sa))
598  {
599  clib_warning ("IPsec interface SA endpoints type can't be changed");
600  return VNET_API_ERROR_INVALID_VALUE;
601  }
602 
603  if (ipsec_sa_is_set_IS_TUNNEL_V6 (sa))
604  {
605  ipsec6_tunnel_key_t key;
606 
607  /* unset old inbound hash entry. packets should stop arriving */
608  key.remote_ip = old_sa->tunnel_src_addr.ip6;
609  key.spi = clib_host_to_net_u32 (old_sa->spi);
610 
612  if (p)
614 
615  /* set new inbound SA, then set new hash entry */
616  t->input_sa_index = sa_index;
617  key.remote_ip = sa->tunnel_src_addr.ip6;
618  key.spi = clib_host_to_net_u32 (sa->spi);
619 
621  hi->dev_instance);
622  }
623  else
624  {
625  ipsec4_tunnel_key_t key;
626 
627  /* unset old inbound hash entry. packets should stop arriving */
628  key.remote_ip = old_sa->tunnel_src_addr.ip4.as_u32;
629  key.spi = clib_host_to_net_u32 (old_sa->spi);
630 
631  p = hash_get (im->ipsec4_if_pool_index_by_key, key.as_u64);
632  if (p)
633  hash_unset (im->ipsec4_if_pool_index_by_key, key.as_u64);
634 
635  /* set new inbound SA, then set new hash entry */
636  t->input_sa_index = sa_index;
637  key.remote_ip = sa->tunnel_src_addr.ip4.as_u32;
638  key.spi = clib_host_to_net_u32 (sa->spi);
639 
640  hash_set (im->ipsec4_if_pool_index_by_key, key.as_u64,
641  hi->dev_instance);
642  }
643  }
644  else
645  {
646  old_sa_index = t->output_sa_index;
647  old_sa = pool_elt_at_index (im->sad, old_sa_index);
648 
649  if (ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ^
650  ipsec_sa_is_set_IS_TUNNEL_V6 (old_sa))
651  {
652  clib_warning ("IPsec interface SA endpoints type can't be changed");
653  return VNET_API_ERROR_INVALID_VALUE;
654  }
655 
656  /*
657  * re-enable the feature to get the new SA in
658  * the workers are stopped so no packets are sent in the clear
659  */
660  ipsec_tunnel_feature_set (im, t, 0);
661  t->output_sa_index = sa_index;
662  ipsec_tunnel_feature_set (im, t, 1);
663  }
664 
665  /* remove sa_id to sa_index mapping on old SA */
666  if (ipsec_get_sa_index_by_sa_id (old_sa->id) == old_sa_index)
667  hash_unset (im->sa_index_by_sa_id, old_sa->id);
668 
669  if (ipsec_add_del_sa_sess_cb (im, old_sa_index, 0))
670  {
671  clib_warning ("IPsec backend add/del callback returned error");
672  return VNET_API_ERROR_SYSCALL_ERROR_1;
673  }
674  ipsec_sa_del (old_sa->id);
675 
676  return 0;
677 }
678 
679 clib_error_t *
681 {
682  ipsec_main_t *im = &ipsec_main;
683 
684  /* initialize the ipsec-if ip4 hash */
686  hash_create (0, sizeof (ipsec4_tunnel_key_t));
687  /* initialize the ipsec-if ip6 hash */
689  sizeof
690  (ipsec6_tunnel_key_t),
691  sizeof (uword));
692  im->ipsec_if_real_dev_by_show_dev = hash_create (0, sizeof (uword));
693 
694  udp_register_dst_port (vm, UDP_DST_PORT_ipsec, ipsec4_if_input_node.index,
695  1);
696  return 0;
697 }
698 
700 
701 
702 /*
703  * fd.io coding-style-patch-verification: ON
704  *
705  * Local Variables:
706  * eval: (c-set-style "gnu")
707  * End:
708  */
u32 sw_if_index
Definition: ipsec_gre.api:37
vmrglw vmrglh hi
static u32 ipsec_tun_mk_output_sa_id(u32 ti)
Definition: ipsec_if.c:228
#define hash_set(h, key, value)
Definition: hash.h:255
u32 flags
Definition: vhost_user.h:115
ipsec_tunnel_if_t * tunnel_interfaces
Definition: ipsec.h:100
ip46_address_t tunnel_src_addr
Definition: ipsec_sa.h:156
u32 ipsec_sa_del(u32 id)
Definition: ipsec_sa.c:254
#define hash_unset(h, key)
Definition: hash.h:261
u8 vnet_get_feature_arc_index(const char *s)
Definition: feature.c:168
a
Definition: bitmap.h:538
void ip6_register_protocol(u32 protocol, u32 node_index)
Definition: ip6_forward.c:1474
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
uword * ipsec4_if_pool_index_by_key
Definition: ipsec.h:112
ip46_address_t local_ip
Definition: ipsec_if.h:47
void adj_midchain_delegate_stack(adj_index_t ai, u32 fib_index, const fib_prefix_t *pfx)
create/attach a midchain delegate and stack it on the prefix passed
vnet_link_t adj_get_link_type(adj_index_t ai)
Return the link type of the adjacency.
Definition: adj.c:468
#define NULL
Definition: clib.h:58
IP unicast adjacency.
Definition: adj.h:221
int ipsec_set_interface_sa(vnet_main_t *vnm, u32 hw_if_index, u32 sa_id, u8 is_outbound)
Definition: ipsec_if.c:563
ipsec_key_t crypto_key
Definition: ipsec_sa.h:151
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
static void ipsec_if_update_adj(vnet_main_t *vnm, u32 sw_if_index, adj_index_t ai)
Definition: ipsec_if.c:176
int ipsec_add_del_tunnel_if(ipsec_add_del_tunnel_args_t *args)
Definition: ipsec_if.c:214
static adj_walk_rc_t ipsec_if_adj_walk_cb(adj_index_t ai, void *ctx)
Call back when restacking all adjacencies on a GRE interface.
Definition: ipsec_if.c:90
VNET_DEVICE_CLASS(ipsec_device_class)
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
u8 data[128]
Definition: ipsec.api:248
void ip4_register_protocol(u32 protocol, u32 node_index)
Definition: ip4_forward.c:1702
void ipsec_mk_key(ipsec_key_t *key, const u8 *data, u8 len)
Definition: ipsec_sa.c:54
unsigned char u8
Definition: types.h:56
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
clib_error_t * ipsec_tunnel_if_init(vlib_main_t *vm)
Definition: ipsec_if.c:680
vl_api_key_t crypto_key
Definition: ipsec.api:275
static ip_adjacency_t * adj_get(adj_index_t adj_index)
Get a pointer to an adjacency object from its index.
Definition: adj.h:433
uword * ipsec6_if_pool_index_by_key
Definition: ipsec.h:113
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:163
ipsec_main_t ipsec_main
Definition: ipsec.c:28
enum adj_walk_rc_t_ adj_walk_rc_t
return codes from a adjacency walker callback function
int vnet_feature_enable_disable_with_index(u8 arc_index, u32 feature_index, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:222
vnet_hw_interface_flags_t flags
Definition: interface.h:494
uword * ipsec_if_by_sw_if_index
Definition: ipsec.h:115
static void ipsec_if_tunnel_stack(adj_index_t ai)
Definition: ipsec_if.c:45
Aggregrate type for a prefix.
Definition: fib_types.h:203
int ipsec_set_interface_key(vnet_main_t *vnm, u32 hw_if_index, ipsec_if_set_key_type_t type, u8 alg, u8 *key)
Definition: ipsec_if.c:517
unsigned int u32
Definition: types.h:88
u32 esp6_encrypt_tun_feature_index
Definition: ipsec.h:139
u32 vnet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u32 hw_class_index, u32 hw_instance)
Definition: interface.c:740
static clib_error_t * ipsec_admin_up_down_function(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: ipsec_if.c:112
int ipsec_add_del_ipsec_gre_tunnel(vnet_main_t *vnm, const ipsec_gre_tunnel_add_del_args_t *args)
Definition: ipsec_if.c:437
#define hash_create_mem(elts, key_bytes, value_bytes)
Definition: hash.h:661
#define hash_get(h, key)
Definition: hash.h:249
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:514
u32 sa_id
Definition: ipsec.api:94
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:226
long ctx[MAX_CONNS]
Definition: main.c:144
clib_error_t * ipsec_check_support_cb(ipsec_main_t *im, ipsec_sa_t *sa)
Definition: ipsec.c:67
ip46_address_t remote_ip
Definition: ipsec_if.h:47
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:286
u8 ipsec_is_sa_used(u32 sa_index)
Definition: ipsec_sa.c:294
static u8 * ipsec_if_build_rewrite(vnet_main_t *vnm, u32 sw_if_index, vnet_link_t link_type, const void *dst_address)
Definition: ipsec_if.c:168
#define pool_get_aligned_zero(P, E, A)
Allocate an object E from a pool P with alignment A and zero it.
Definition: pool.h:233
static ipsec_sa_t * ipsec_sa_get(u32 sa_index)
Definition: ipsec.h:235
ip46_address_t tunnel_dst_addr
Definition: ipsec_sa.h:157
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
Definition: pool.h:230
u32 ipsec_get_sa_index_by_sa_id(u32 sa_id)
Definition: ipsec_sa.c:362
ipsec_crypto_alg_t crypto_alg
Definition: ipsec_if.h:50
clib_error_t * ipsec_add_del_sa_sess_cb(ipsec_main_t *im, u32 sa_index, u8 is_add)
Definition: ipsec.c:45
void ipsec_sa_set_integ_alg(ipsec_sa_t *sa, ipsec_integ_alg_t integ_alg)
Definition: ipsec_sa.c:113
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:212
vlib_main_t * vm
Definition: buffer.c:312
void vl_api_rpc_call_main_thread(void *fp, u8 *data, u32 data_length)
Definition: vlib_api.c:623
#define clib_warning(format, args...)
Definition: error.h:59
void adj_nbr_midchain_update_rewrite(adj_index_t adj_index, adj_midchain_fixup_t fixup, const void *fixup_data, adj_flags_t flags, u8 *rewrite)
adj_nbr_midchain_update_rewrite
Definition: adj_midchain.c:500
enum ipsec_sad_flags_t_ ipsec_sa_flags_t
uword * sa_index_by_sa_id
Definition: ipsec.h:111
u8 is_outbound
Definition: ipsec.api:92
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
uword * ipsec_if_real_dev_by_show_dev
Definition: ipsec.h:114
void adj_nbr_walk(u32 sw_if_index, fib_protocol_t adj_nh_proto, adj_walk_cb_t cb, void *ctx)
Walk the neighbour Adjacencies on a given interface.
Definition: adj_nbr.c:574
static void ipsec_if_tunnel_restack(ipsec_tunnel_if_t *it)
Definition: ipsec_if.c:98
u8 * default_build_rewrite(vnet_main_t *vnm, u32 sw_if_index, vnet_link_t link_type, const void *dst_address)
Return a complete, zero-length (aka dummy) rewrite.
Definition: interface.c:1557
void adj_midchain_delegate_unstack(adj_index_t ai)
unstack a midchain delegate (this stacks it on a drop)
#define hash_create(elts, value_bytes)
Definition: hash.h:696
void ipsec_sa_set_crypto_alg(ipsec_sa_t *sa, ipsec_crypto_alg_t crypto_alg)
Definition: ipsec_sa.c:95
#define ASSERT(truth)
static int ipsec_add_del_tunnel_if_rpc_callback(ipsec_add_del_tunnel_args_t *a)
Definition: ipsec_if.c:205
vnet_hw_interface_flags_t flags
Definition: ipsec_if.h:37
ipsec_integ_alg_t integ_alg
Definition: ipsec_if.h:55
enum vnet_link_t_ vnet_link_t
Link Type: A description of the protocol of packets on the link.
ipsec_sa_t * sad
Definition: ipsec.h:95
int ipsec_add_del_tunnel_if_internal(vnet_main_t *vnm, ipsec_add_del_tunnel_args_t *args, u32 *sw_if_index)
Definition: ipsec_if.c:256
vlib_node_registration_t ipsec4_if_input_node
(constructor) VLIB_REGISTER_NODE (ipsec4_if_input_node)
Definition: ipsec_if_in.c:618
static void ipsec_tunnel_feature_set(ipsec_main_t *im, ipsec_tunnel_if_t *t, u8 enable)
Definition: ipsec_if.c:234
void vnet_delete_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:951
int ipsec_sa_add(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:123
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
VNET_HW_INTERFACE_CLASS(ipsec_hw_class)
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_interface_flags_t flags)
Definition: interface.c:504
u64 uword
Definition: types.h:112
static void hash_set_mem_alloc(uword **h, void *key, uword v)
Definition: hash.h:279
typedef key
Definition: ipsec.api:244
a point 2 point interface
Definition: interface.h:357
vlib_node_registration_t ipsec6_if_input_node
(constructor) VLIB_REGISTER_NODE (ipsec6_if_input_node)
Definition: ipsec_if_in.c:637
void vnet_sw_interface_set_mtu(vnet_main_t *vnm, u32 sw_if_index, u32 mtu)
Definition: interface.c:642
#define FOR_EACH_FIB_IP_PROTOCOL(_item)
Definition: fib_types.h:70
#define hash_get_mem(h, key)
Definition: hash.h:269
static void hash_unset_mem_free(uword **h, void *key)
Definition: hash.h:295
static u8 * format_ipsec_name(u8 *s, va_list *args)
Definition: ipsec_if.c:31
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, vnet_sw_interface_flags_t flags)
Definition: interface.c:513
u32 esp4_encrypt_tun_feature_index
Definition: ipsec.h:138
static u32 ipsec_tun_mk_input_sa_id(u32 ti)
Definition: ipsec_if.c:222
ipsec_if_set_key_type_t
Definition: ipsec_if.h:20
void udp_register_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u32 node_index, u8 is_ip4)
Definition: udp_local.c:484
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:486
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
ipsec_key_t integ_key
Definition: ipsec_sa.h:154
static uword vnet_hw_interface_is_link_up(vnet_main_t *vnm, u32 hw_if_index)
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128