Neale Ranns | dd4ccf2 | 2020-06-30 07:47:14 +0000 | [diff] [blame] | 1 | /* |
| 2 | * ipsec_itf.c: IPSec dedicated interface type |
| 3 | * |
| 4 | * Copyright (c) 2020 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 | #ifndef __IPSEC_ITF_H__ |
| 19 | #define __IPSEC_ITF_H__ |
| 20 | |
| 21 | #include <vnet/tunnel/tunnel.h> |
| 22 | #include <vnet/ipsec/ipsec_sa.h> |
| 23 | |
| 24 | /** |
| 25 | * @brief A dedicated IPSec interface type |
| 26 | * |
| 27 | * In order to support route based VPNs one needs 3 elements: an interface, |
| 28 | * for routing to resolve routes through, an SA from the peer to describe |
| 29 | * security, and encap, to describe how to reach the peer. There are two |
| 30 | * ways one could model this: |
| 31 | * |
| 32 | * interface + encap + SA = (interface + encap) + SA = |
| 33 | * ipip-interface + SA transport mode |
| 34 | * |
| 35 | * or |
| 36 | * |
| 37 | * interface + encap + SA = interface + (encap + SA) = |
| 38 | * IPSec-interface + SA tunnel mode |
| 39 | * |
| 40 | * It's a question of where you add the parenthesis, from the perspective |
| 41 | * of the external user the effect is identical. |
| 42 | * |
| 43 | * The IPsec interface serves as the encap-free interface to be used |
| 44 | * in conjunction with an encap-describing tunnel mode SA. |
| 45 | * |
| 46 | * VPP supports both models, which modelshould you pick? |
| 47 | * A route based VPN could impose 0, 1 or 2 encaps. the support matrix for |
| 48 | * these use cases is: |
| 49 | * |
| 50 | * | 0 | 1 | 2 | |
| 51 | * -------------------------- |
| 52 | * ipip | N | Y | Y | |
| 53 | * ipsec | P | Y | P | |
| 54 | * |
| 55 | * Where P = potentially. |
| 56 | * ipsec could potnetially support 0 encap (i.e. transport mode) since neither |
| 57 | * the interface nor the SA *requires* encap. However, for a route beased VPN |
| 58 | * to use transport mode is probably wrong since one shouldn't use thransport |
| 59 | * mode for transit traffic, since without encap it is not guaranteed to return. |
| 60 | * ipsec could potnetially support 2 encaps, but that would require the SA to |
| 61 | * describe both, something it does not do at this time. |
| 62 | * |
| 63 | * ipsec currently does not support: |
| 64 | * - multipoint interfaces |
| 65 | * but this is only because it is not yet implemented, rather than it cannot |
| 66 | * be done. |
| 67 | * |
| 68 | * Internally the difference is that the midchain adjacency for the IPSec |
| 69 | * interface has no associated encap (whereas for an ipip tunnel it describes |
| 70 | * the peer). Consequently, features on the output arc see packets without |
| 71 | * any encap. Since the protecting SAs are in tunnel mode, |
| 72 | * they apply the encap. The midchain adj is stacked only once the proctecting |
| 73 | * SA is known, since only then is the peer known. Otherwise the VLIB graph |
| 74 | * nodes used are the same: |
| 75 | * (routing) --> ipX-michain --> espX-encrypt --> adj-midchain-tx --> (routing) |
| 76 | * where X = 4 or 6. |
| 77 | * |
| 78 | * Some benefits to the ipsec interface: |
| 79 | * - it is slightly more efficient since the encapsulating IP header has |
| 80 | * its checksum updated only once. |
| 81 | * - even when the interface is admin up traffic cannot be sent to a peer |
| 82 | * unless the SA is available (since it's the SA that determines the |
| 83 | * encap). With ipip interfaces a client must use the admin state to |
| 84 | * prevent sending until the SA is available. |
| 85 | * |
| 86 | * The best recommendations i can make are: |
| 87 | * - pick a model that supports your use case |
| 88 | * - make sure any other features you wish to use are supported by the model |
| 89 | * - choose the model that best fits your control plane's model. |
| 90 | * |
| 91 | * |
| 92 | * gun reloaded, fire away. |
| 93 | */ |
| 94 | typedef struct ipsec_itf_t_ |
| 95 | { |
| 96 | tunnel_mode_t ii_mode; |
| 97 | int ii_user_instance; |
| 98 | u32 ii_sw_if_index; |
| 99 | } __clib_packed ipsec_itf_t; |
| 100 | |
| 101 | |
| 102 | extern int ipsec_itf_create (u32 user_instance, |
| 103 | tunnel_mode_t mode, u32 * sw_if_indexp); |
| 104 | extern int ipsec_itf_delete (u32 sw_if_index); |
Neale Ranns | 49378f2 | 2022-01-10 10:38:43 +0000 | [diff] [blame] | 105 | extern void ipsec_itf_reset_tx_nodes (u32 sw_if_index); |
Neale Ranns | dd4ccf2 | 2020-06-30 07:47:14 +0000 | [diff] [blame] | 106 | |
| 107 | extern void ipsec_itf_adj_stack (adj_index_t ai, u32 sai); |
| 108 | extern void ipsec_itf_adj_unstack (adj_index_t ai); |
| 109 | |
Neale Ranns | 6ba4e41 | 2020-10-19 09:59:41 +0000 | [diff] [blame] | 110 | extern u8 *format_ipsec_itf (u8 * s, va_list * a); |
| 111 | |
| 112 | extern ipsec_itf_t *ipsec_itf_get (index_t ii); |
Neale Ranns | 6fdcc3d | 2021-10-08 07:30:47 +0000 | [diff] [blame] | 113 | extern u32 ipsec_itf_count (void); |
Neale Ranns | 6ba4e41 | 2020-10-19 09:59:41 +0000 | [diff] [blame] | 114 | |
Neale Ranns | 89d939e | 2021-06-07 09:34:07 +0000 | [diff] [blame] | 115 | typedef walk_rc_t (*ipsec_itf_walk_cb_t) (ipsec_itf_t *itf, void *ctx); |
| 116 | extern void ipsec_itf_walk (ipsec_itf_walk_cb_t cd, void *ctx); |
| 117 | |
Neale Ranns | dd4ccf2 | 2020-06-30 07:47:14 +0000 | [diff] [blame] | 118 | /* |
| 119 | * fd.io coding-style-patch-verification: ON |
| 120 | * |
| 121 | * Local Variables: |
| 122 | * eval: (c-set-style "gnu") |
| 123 | * End: |
| 124 | */ |
| 125 | |
| 126 | #endif |