blob: 1572e5501e20746166e8fc7a832f8962b8aed638 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
Sergio Gonzalez Monroya10f62b2016-11-25 13:36:12 +000015#ifndef __IPSEC_H__
16#define __IPSEC_H__
17
Sergio Gonzalez Monroydb93cd92017-08-26 15:22:05 +010018#include <vnet/ip/ip.h>
19#include <vnet/feature/feature.h>
20
Matus Fabian694265d2016-08-10 01:55:36 -070021#define IPSEC_FLAG_IPSEC_GRE_TUNNEL (1 << 0)
22
Sergio Gonzalez Monroyd04b60b2017-01-20 15:35:23 +000023
24#define foreach_ipsec_output_next \
25_(DROP, "error-drop") \
26_(ESP_ENCRYPT, "esp-encrypt")
27
28#define _(v, s) IPSEC_OUTPUT_NEXT_##v,
29typedef enum
30{
31 foreach_ipsec_output_next
32#undef _
33 IPSEC_OUTPUT_N_NEXT,
34} ipsec_output_next_t;
35
36
37#define foreach_ipsec_input_next \
38_(DROP, "error-drop") \
39_(ESP_DECRYPT, "esp-decrypt")
40
41#define _(v, s) IPSEC_INPUT_NEXT_##v,
42typedef enum
43{
44 foreach_ipsec_input_next
45#undef _
46 IPSEC_INPUT_N_NEXT,
47} ipsec_input_next_t;
48
49
Ed Warnickecb9cada2015-12-08 15:45:58 -070050#define foreach_ipsec_policy_action \
51 _(0, BYPASS, "bypass") \
52 _(1, DISCARD, "discard") \
53 _(2, RESOLVE, "resolve") \
54 _(3, PROTECT, "protect")
55
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070056typedef enum
57{
Ed Warnickecb9cada2015-12-08 15:45:58 -070058#define _(v,f,s) IPSEC_POLICY_ACTION_##f = v,
59 foreach_ipsec_policy_action
60#undef _
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070061 IPSEC_POLICY_N_ACTION,
Ed Warnickecb9cada2015-12-08 15:45:58 -070062} ipsec_policy_action_t;
63
Radu Nicolau6929ea92016-11-29 11:00:30 +000064#define foreach_ipsec_crypto_alg \
65 _(0, NONE, "none") \
66 _(1, AES_CBC_128, "aes-cbc-128") \
67 _(2, AES_CBC_192, "aes-cbc-192") \
68 _(3, AES_CBC_256, "aes-cbc-256") \
Sergio Gonzalez Monroydb93cd92017-08-26 15:22:05 +010069 _(4, AES_CTR_128, "aes-ctr-128") \
70 _(5, AES_CTR_192, "aes-ctr-192") \
71 _(6, AES_CTR_256, "aes-ctr-256") \
72 _(7, AES_GCM_128, "aes-gcm-128") \
73 _(8, AES_GCM_192, "aes-gcm-192") \
74 _(9, AES_GCM_256, "aes-gcm-256")
Ed Warnickecb9cada2015-12-08 15:45:58 -070075
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070076typedef enum
77{
Ed Warnickecb9cada2015-12-08 15:45:58 -070078#define _(v,f,s) IPSEC_CRYPTO_ALG_##f = v,
79 foreach_ipsec_crypto_alg
80#undef _
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070081 IPSEC_CRYPTO_N_ALG,
Ed Warnickecb9cada2015-12-08 15:45:58 -070082} ipsec_crypto_alg_t;
83
Radu Nicolau6929ea92016-11-29 11:00:30 +000084#define foreach_ipsec_integ_alg \
85 _(0, NONE, "none") \
86 _(1, MD5_96, "md5-96") /* RFC2403 */ \
87 _(2, SHA1_96, "sha1-96") /* RFC2404 */ \
88 _(3, SHA_256_96, "sha-256-96") /* draft-ietf-ipsec-ciph-sha-256-00 */ \
89 _(4, SHA_256_128, "sha-256-128") /* RFC4868 */ \
90 _(5, SHA_384_192, "sha-384-192") /* RFC4868 */ \
Sergio Gonzalez Monroydb93cd92017-08-26 15:22:05 +010091 _(6, SHA_512_256, "sha-512-256") /* RFC4868 */
Ed Warnickecb9cada2015-12-08 15:45:58 -070092
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070093typedef enum
94{
Ed Warnickecb9cada2015-12-08 15:45:58 -070095#define _(v,f,s) IPSEC_INTEG_ALG_##f = v,
96 foreach_ipsec_integ_alg
97#undef _
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070098 IPSEC_INTEG_N_ALG,
Ed Warnickecb9cada2015-12-08 15:45:58 -070099} ipsec_integ_alg_t;
100
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700101typedef enum
102{
103 IPSEC_PROTOCOL_AH = 0,
104 IPSEC_PROTOCOL_ESP = 1
Ed Warnickecb9cada2015-12-08 15:45:58 -0700105} ipsec_protocol_t;
106
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700107typedef struct
108{
109 u32 id;
110 u32 spi;
111 ipsec_protocol_t protocol;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700112
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700113 ipsec_crypto_alg_t crypto_alg;
114 u8 crypto_key_len;
115 u8 crypto_key[128];
Ed Warnickecb9cada2015-12-08 15:45:58 -0700116
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700117 ipsec_integ_alg_t integ_alg;
118 u8 integ_key_len;
119 u8 integ_key[128];
Ed Warnickecb9cada2015-12-08 15:45:58 -0700120
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700121 u8 use_esn;
122 u8 use_anti_replay;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700123
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700124 u8 is_tunnel;
125 u8 is_tunnel_ip6;
126 ip46_address_t tunnel_src_addr;
127 ip46_address_t tunnel_dst_addr;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700128
Radu Nicolau6929ea92016-11-29 11:00:30 +0000129 u32 salt;
130
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700131 /* runtime */
132 u32 seq;
133 u32 seq_hi;
134 u32 last_seq;
135 u32 last_seq_hi;
136 u64 replay_window;
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000137
138 /*lifetime data */
139 u64 total_data_size;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700140} ipsec_sa_t;
141
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700142typedef struct
143{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700144 ip46_address_t start, stop;
145} ip46_address_range_t;
146
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700147typedef struct
148{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700149 u16 start, stop;
150} port_range_t;
151
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700152typedef struct
153{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700154 u8 is_add;
155 u8 esn;
156 u8 anti_replay;
157 ip4_address_t local_ip, remote_ip;
158 u32 local_spi;
159 u32 remote_spi;
Matthew Smith2838a232016-06-21 16:05:09 -0500160 ipsec_crypto_alg_t crypto_alg;
161 u8 local_crypto_key_len;
162 u8 local_crypto_key[128];
163 u8 remote_crypto_key_len;
164 u8 remote_crypto_key[128];
165 ipsec_integ_alg_t integ_alg;
166 u8 local_integ_key_len;
167 u8 local_integ_key[128];
168 u8 remote_integ_key_len;
169 u8 remote_integ_key[128];
Ed Warnickecb9cada2015-12-08 15:45:58 -0700170} ipsec_add_del_tunnel_args_t;
171
Matus Fabian694265d2016-08-10 01:55:36 -0700172typedef struct
173{
174 u8 is_add;
175 u32 local_sa_id;
176 u32 remote_sa_id;
177 ip4_address_t local_ip;
178 ip4_address_t remote_ip;
179} ipsec_add_del_ipsec_gre_tunnel_args_t;
180
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700181typedef enum
182{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700183 IPSEC_IF_SET_KEY_TYPE_NONE,
184 IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO,
185 IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO,
186 IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG,
187 IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG,
188} ipsec_if_set_key_type_t;
189
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700190typedef struct
191{
192 u32 id;
193 i32 priority;
194 u8 is_outbound;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700195
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700196 // Selector
197 u8 is_ipv6;
198 ip46_address_range_t laddr;
199 ip46_address_range_t raddr;
200 u8 protocol;
201 port_range_t lport;
202 port_range_t rport;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700203
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700204 // Policy
205 u8 policy;
206 u32 sa_id;
207 u32 sa_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700208
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700209 // Counter
210 vlib_counter_t counter;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700211} ipsec_policy_t;
212
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700213typedef struct
214{
215 u32 id;
216 /* pool of policies */
217 ipsec_policy_t *policies;
218 /* vectors of policy indices */
219 u32 *ipv4_outbound_policies;
220 u32 *ipv6_outbound_policies;
221 u32 *ipv4_inbound_protect_policy_indices;
222 u32 *ipv4_inbound_policy_discard_and_bypass_indices;
223 u32 *ipv6_inbound_protect_policy_indices;
224 u32 *ipv6_inbound_policy_discard_and_bypass_indices;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700225} ipsec_spd_t;
226
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700227typedef struct
228{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700229 u32 spd_index;
230} ip4_ipsec_config_t;
231
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700232typedef struct
233{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700234 u32 spd_index;
235} ip6_ipsec_config_t;
236
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700237typedef struct
238{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700239 u32 input_sa_index;
240 u32 output_sa_index;
241 u32 hw_if_index;
242} ipsec_tunnel_if_t;
243
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700244typedef struct
245{
Sergio Gonzalez Monroydb93cd92017-08-26 15:22:05 +0100246 clib_error_t *(*add_del_sa_sess_cb) (u32 sa_index, u8 is_add);
Sergio Gonzalez Monroyd04b60b2017-01-20 15:35:23 +0000247 clib_error_t *(*check_support_cb) (ipsec_sa_t * sa);
248} ipsec_main_callbacks_t;
249
250typedef struct
251{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700252 /* pool of tunnel instances */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700253 ipsec_spd_t *spds;
254 ipsec_sa_t *sad;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700255
256 /* pool of tunnel interfaces */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700257 ipsec_tunnel_if_t *tunnel_interfaces;
258 u32 *free_tunnel_if_indices;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700259
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700260 u32 **empty_buffers;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700261
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700262 uword *tunnel_index_by_key;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700263
264 /* convenience */
265 vlib_main_t *vlib_main;
266 vnet_main_t *vnet_main;
267
268 /* next node indices */
269 u32 feature_next_node_index[32];
270
271 /* hashes */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700272 uword *spd_index_by_spd_id;
273 uword *spd_index_by_sw_if_index;
274 uword *sa_index_by_sa_id;
275 uword *ipsec_if_pool_index_by_key;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700276
Sergio Gonzalez Monroyd04b60b2017-01-20 15:35:23 +0000277 /* node indeces */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700278 u32 error_drop_node_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700279 u32 esp_encrypt_node_index;
Sergio Gonzalez Monroyd04b60b2017-01-20 15:35:23 +0000280 u32 esp_decrypt_node_index;
281 /* next node indeces */
282 u32 esp_encrypt_next_index;
283 u32 esp_decrypt_next_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700284
Sergio Gonzalez Monroyd04b60b2017-01-20 15:35:23 +0000285 /* callbacks */
286 ipsec_main_callbacks_t cb;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700287} ipsec_main_t;
288
Dave Wallace71612d62017-10-24 01:32:41 -0400289extern ipsec_main_t ipsec_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700290
Jean-Mickael Guerin8941ec22016-03-04 14:14:21 +0100291extern vlib_node_registration_t esp_encrypt_node;
292extern vlib_node_registration_t esp_decrypt_node;
293extern vlib_node_registration_t ipsec_if_output_node;
294extern vlib_node_registration_t ipsec_if_input_node;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700295
296
297/*
298 * functions
299 */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700300int ipsec_set_interface_spd (vlib_main_t * vm, u32 sw_if_index, u32 spd_id,
301 int is_add);
302int ipsec_add_del_spd (vlib_main_t * vm, u32 spd_id, int is_add);
303int ipsec_add_del_policy (vlib_main_t * vm, ipsec_policy_t * policy,
304 int is_add);
305int ipsec_add_del_sa (vlib_main_t * vm, ipsec_sa_t * new_sa, int is_add);
306int ipsec_set_sa_key (vlib_main_t * vm, ipsec_sa_t * sa_update);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700307
Matus Fabian694265d2016-08-10 01:55:36 -0700308u32 ipsec_get_sa_index_by_sa_id (u32 sa_id);
Matthew Smithca514fd2017-10-12 12:06:59 -0500309u8 ipsec_is_sa_used (u32 sa_index);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700310u8 *format_ipsec_if_output_trace (u8 * s, va_list * args);
311u8 *format_ipsec_policy_action (u8 * s, va_list * args);
312u8 *format_ipsec_crypto_alg (u8 * s, va_list * args);
313u8 *format_ipsec_integ_alg (u8 * s, va_list * args);
314u8 *format_ipsec_replay_window (u8 * s, va_list * args);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700315uword unformat_ipsec_policy_action (unformat_input_t * input, va_list * args);
316uword unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args);
317uword unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args);
318
Matthew Smithe04d09d2017-05-14 21:47:18 -0500319int ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
320 ipsec_add_del_tunnel_args_t * args,
321 u32 * sw_if_index);
Matthew Smith2838a232016-06-21 16:05:09 -0500322int ipsec_add_del_tunnel_if (ipsec_add_del_tunnel_args_t * args);
Matus Fabian694265d2016-08-10 01:55:36 -0700323int ipsec_add_del_ipsec_gre_tunnel (vnet_main_t * vnm,
324 ipsec_add_del_ipsec_gre_tunnel_args_t *
325 args);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700326int ipsec_set_interface_key (vnet_main_t * vnm, u32 hw_if_index,
327 ipsec_if_set_key_type_t type, u8 alg, u8 * key);
Matthew Smithca514fd2017-10-12 12:06:59 -0500328int ipsec_set_interface_sa (vnet_main_t * vnm, u32 hw_if_index, u32 sa_id,
329 u8 is_outbound);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700330
331
332/*
333 * inline functions
334 */
335
336always_inline void
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700337ipsec_alloc_empty_buffers (vlib_main_t * vm, ipsec_main_t * im)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700338{
Damjan Marion586afd72017-04-05 19:18:20 +0200339 u32 thread_index = vlib_get_thread_index ();
340 uword l = vec_len (im->empty_buffers[thread_index]);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700341 uword n_alloc = 0;
342
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700343 if (PREDICT_FALSE (l < VLIB_FRAME_SIZE))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700344 {
Damjan Marion586afd72017-04-05 19:18:20 +0200345 if (!im->empty_buffers[thread_index])
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700346 {
Damjan Marion586afd72017-04-05 19:18:20 +0200347 vec_alloc (im->empty_buffers[thread_index], 2 * VLIB_FRAME_SIZE);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700348 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700349
Damjan Marion586afd72017-04-05 19:18:20 +0200350 n_alloc = vlib_buffer_alloc (vm, im->empty_buffers[thread_index] + l,
Damjan Marion67655492016-11-15 12:50:28 +0100351 2 * VLIB_FRAME_SIZE - l);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700352
Damjan Marion586afd72017-04-05 19:18:20 +0200353 _vec_len (im->empty_buffers[thread_index]) = l + n_alloc;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700354 }
355}
356
Matus Fabian08a6f012016-11-15 06:08:51 -0800357static_always_inline u32
358get_next_output_feature_node_index (vlib_buffer_t * b,
359 vlib_node_runtime_t * nr)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700360{
Matus Fabian08a6f012016-11-15 06:08:51 -0800361 u32 next;
362 u32 sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_TX];
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700363 vlib_main_t *vm = vlib_get_main ();
Matus Fabian08a6f012016-11-15 06:08:51 -0800364 vlib_node_t *node = vlib_get_node (vm, nr->node_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700365
Matus Fabian08a6f012016-11-15 06:08:51 -0800366 vnet_feature_next (sw_if_index, &next, b);
367 return node->next_nodes[next];
Ed Warnickecb9cada2015-12-08 15:45:58 -0700368}
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700369
Sergio Gonzalez Monroya10f62b2016-11-25 13:36:12 +0000370#endif /* __IPSEC_H__ */
371
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700372/*
373 * fd.io coding-style-patch-verification: ON
374 *
375 * Local Variables:
376 * eval: (c-set-style "gnu")
377 * End:
378 */