blob: f14361936367e832edb1fbf5ea5f08b85fa89945 [file] [log] [blame]
Filip Tehlar0ad06082021-07-25 14:38:45 +00001/* SPDX-License-Identifier: Apache-2.0
2 * Copyright(c) 2021 Cisco Systems, Inc.
3 */
4
5#include <vat/vat.h>
6#include <vlibapi/api.h>
7#include <vlibmemory/api.h>
8#include <vppinfra/error.h>
9#include <vpp/api/types.h>
10
11#include <vnet/ipsec/ipsec.h>
12#include <vnet/ip/ip_types_api.h>
13
14#define __plugin_msg_base ipsec_test_main.msg_id_base
15#include <vlibapi/vat_helper_macros.h>
16
17#include <vlibmemory/vlib.api_enum.h>
18#include <vlibmemory/vlib.api_types.h>
19
20/* Declare message IDs */
21#include <vnet/format_fns.h>
22#include <vnet/ipsec/ipsec.api_enum.h>
23#include <vnet/ipsec/ipsec.api_types.h>
24
25#define vl_endianfun /* define message structures */
26#include <vnet/ipsec/ipsec.api.h>
27#undef vl_endianfun
28
Klement Sekera9b7e8ac2021-11-22 21:26:20 +010029#define vl_calcsizefun
30#include <vnet/ipsec/ipsec.api.h>
31#undef vl_calcsizefun
32
Filip Tehlar0ad06082021-07-25 14:38:45 +000033typedef struct
34{
35 /* API message ID base */
36 u16 msg_id_base;
37 u32 ping_id;
38 vat_main_t *vat_main;
39} ipsec_test_main_t;
40
41static ipsec_test_main_t ipsec_test_main;
42
43static void
44vl_api_ipsec_spds_details_t_handler (vl_api_ipsec_spds_details_t *mp)
45{
46}
47
48static void
49vl_api_ipsec_itf_details_t_handler (vl_api_ipsec_itf_details_t *mp)
50{
51}
52
53static int
54api_ipsec_itf_delete (vat_main_t *vat)
55{
56 return -1;
57}
58
59static int
60api_ipsec_itf_create (vat_main_t *vat)
61{
62 return -1;
63}
64
65static void
66vl_api_ipsec_itf_create_reply_t_handler (vl_api_ipsec_itf_create_reply_t *vat)
67{
68}
69
70static int
71api_ipsec_spd_entry_add_del (vat_main_t *vam)
72{
73 unformat_input_t *i = vam->input;
74 vl_api_ipsec_spd_entry_add_del_t *mp;
75 u8 is_add = 1, is_outbound = 0;
Piotr Bronowski815c6a42022-06-09 09:09:28 +000076 u32 spd_id = 0, sa_id = 0, protocol = IPSEC_POLICY_PROTOCOL_ANY, policy = 0;
77 i32 priority = 0;
78 u32 rport_start = 0, rport_stop = (u32) ~0;
79 u32 lport_start = 0, lport_stop = (u32) ~0;
80 vl_api_address_t laddr_start = {}, laddr_stop = {}, raddr_start = {},
81 raddr_stop = {};
82 int ret;
83
84 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
85 {
86 if (unformat (i, "del"))
87 is_add = 0;
88 if (unformat (i, "outbound"))
89 is_outbound = 1;
90 if (unformat (i, "inbound"))
91 is_outbound = 0;
92 else if (unformat (i, "spd_id %d", &spd_id))
93 ;
94 else if (unformat (i, "sa_id %d", &sa_id))
95 ;
96 else if (unformat (i, "priority %d", &priority))
97 ;
98 else if (unformat (i, "protocol %d", &protocol))
99 ;
100 else if (unformat (i, "lport_start %d", &lport_start))
101 ;
102 else if (unformat (i, "lport_stop %d", &lport_stop))
103 ;
104 else if (unformat (i, "rport_start %d", &rport_start))
105 ;
106 else if (unformat (i, "rport_stop %d", &rport_stop))
107 ;
108 else if (unformat (i, "laddr_start %U", unformat_vl_api_address,
109 &laddr_start))
110 ;
111 else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
112 &laddr_stop))
113 ;
114 else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
115 &raddr_start))
116 ;
117 else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
118 &raddr_stop))
119 ;
120 else if (unformat (i, "action %U", unformat_ipsec_policy_action,
121 &policy))
122 {
123 if (policy == IPSEC_POLICY_ACTION_RESOLVE)
124 {
125 clib_warning ("unsupported action: 'resolve'");
126 return -99;
127 }
128 }
129 else
130 {
131 clib_warning ("parse error '%U'", format_unformat_error, i);
132 return -99;
133 }
134 }
135
136 M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
137
138 mp->is_add = is_add;
139
140 mp->entry.spd_id = ntohl (spd_id);
141 mp->entry.priority = ntohl (priority);
142 mp->entry.is_outbound = is_outbound;
143
144 clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
145 sizeof (vl_api_address_t));
146 clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
147 sizeof (vl_api_address_t));
148 clib_memcpy (&mp->entry.local_address_start, &laddr_start,
149 sizeof (vl_api_address_t));
150 clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
151 sizeof (vl_api_address_t));
152
153 mp->entry.protocol = protocol ? (u8) protocol : IPSEC_POLICY_PROTOCOL_ANY;
154 mp->entry.local_port_start = ntohs ((u16) lport_start);
155 mp->entry.local_port_stop = ntohs ((u16) lport_stop);
156 mp->entry.remote_port_start = ntohs ((u16) rport_start);
157 mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
158 mp->entry.policy = (u8) policy;
159 mp->entry.sa_id = ntohl (sa_id);
160
161 S (mp);
162 W (ret);
163 return ret;
164}
165
166static int
167api_ipsec_spd_entry_add_del_v2 (vat_main_t *vam)
168{
169 unformat_input_t *i = vam->input;
170 vl_api_ipsec_spd_entry_add_del_t *mp;
171 u8 is_add = 1, is_outbound = 0;
172 u32 spd_id = 0, sa_id = 0, protocol = IPSEC_POLICY_PROTOCOL_ANY, policy = 0;
Filip Tehlar0ad06082021-07-25 14:38:45 +0000173 i32 priority = 0;
174 u32 rport_start = 0, rport_stop = (u32) ~0;
175 u32 lport_start = 0, lport_stop = (u32) ~0;
176 vl_api_address_t laddr_start = {}, laddr_stop = {}, raddr_start = {},
177 raddr_stop = {};
178 int ret;
179
180 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
181 {
182 if (unformat (i, "del"))
183 is_add = 0;
184 if (unformat (i, "outbound"))
185 is_outbound = 1;
186 if (unformat (i, "inbound"))
187 is_outbound = 0;
188 else if (unformat (i, "spd_id %d", &spd_id))
189 ;
190 else if (unformat (i, "sa_id %d", &sa_id))
191 ;
192 else if (unformat (i, "priority %d", &priority))
193 ;
194 else if (unformat (i, "protocol %d", &protocol))
195 ;
196 else if (unformat (i, "lport_start %d", &lport_start))
197 ;
198 else if (unformat (i, "lport_stop %d", &lport_stop))
199 ;
200 else if (unformat (i, "rport_start %d", &rport_start))
201 ;
202 else if (unformat (i, "rport_stop %d", &rport_stop))
203 ;
204 else if (unformat (i, "laddr_start %U", unformat_vl_api_address,
205 &laddr_start))
206 ;
207 else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
208 &laddr_stop))
209 ;
210 else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
211 &raddr_start))
212 ;
213 else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
214 &raddr_stop))
215 ;
216 else if (unformat (i, "action %U", unformat_ipsec_policy_action,
217 &policy))
218 {
219 if (policy == IPSEC_POLICY_ACTION_RESOLVE)
220 {
221 clib_warning ("unsupported action: 'resolve'");
222 return -99;
223 }
224 }
225 else
226 {
227 clib_warning ("parse error '%U'", format_unformat_error, i);
228 return -99;
229 }
230 }
231
232 M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
233
234 mp->is_add = is_add;
235
236 mp->entry.spd_id = ntohl (spd_id);
237 mp->entry.priority = ntohl (priority);
238 mp->entry.is_outbound = is_outbound;
239
240 clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
241 sizeof (vl_api_address_t));
242 clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
243 sizeof (vl_api_address_t));
244 clib_memcpy (&mp->entry.local_address_start, &laddr_start,
245 sizeof (vl_api_address_t));
246 clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
247 sizeof (vl_api_address_t));
248
249 mp->entry.protocol = (u8) protocol;
250 mp->entry.local_port_start = ntohs ((u16) lport_start);
251 mp->entry.local_port_stop = ntohs ((u16) lport_stop);
252 mp->entry.remote_port_start = ntohs ((u16) rport_start);
253 mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
254 mp->entry.policy = (u8) policy;
255 mp->entry.sa_id = ntohl (sa_id);
256
257 S (mp);
258 W (ret);
259 return ret;
260}
261
262static void
263vl_api_ipsec_spd_details_t_handler (vl_api_ipsec_spd_details_t *mp)
264{
265}
266
267static void
268vl_api_ipsec_sad_entry_add_del_reply_t_handler (
269 vl_api_ipsec_sad_entry_add_del_reply_t *mp)
270{
271}
272
273static void
274vl_api_ipsec_sad_entry_add_del_v3_reply_t_handler (
275 vl_api_ipsec_sad_entry_add_del_v3_reply_t *mp)
276{
277}
278
279static void
280vl_api_ipsec_sad_entry_add_reply_t_handler (
281 vl_api_ipsec_sad_entry_add_reply_t *mp)
282{
283}
284
285static int
286api_ipsec_sad_entry_del (vat_main_t *vat)
287{
288 return -1;
289}
290
291static void
292vl_api_ipsec_sad_entry_add_del_v2_reply_t_handler (
293 vl_api_ipsec_sad_entry_add_del_v2_reply_t *mp)
294{
295}
296
297static void
298vl_api_ipsec_spd_interface_details_t_handler (
299 vl_api_ipsec_spd_interface_details_t *vat)
300{
301}
302
303static int
304api_ipsec_sad_entry_add_del_v3 (vat_main_t *vat)
305{
306 return -1;
307}
308
309static int
310api_ipsec_tunnel_protect_update (vat_main_t *vat)
311{
312 return -1;
313}
314
315static void
316vl_api_ipsec_backend_details_t_handler (vl_api_ipsec_backend_details_t *mp)
317{
318}
319
320static int
321api_ipsec_sa_v3_dump (vat_main_t *vat)
322{
323 return -1;
324}
325
326static int
327api_ipsec_tunnel_protect_dump (vat_main_t *vat)
328{
329 return -1;
330}
331
332static int
333api_ipsec_tunnel_protect_del (vat_main_t *vat)
334{
335 return -1;
336}
337
338static void
339vl_api_ipsec_tunnel_protect_details_t_handler (
340 vl_api_ipsec_tunnel_protect_details_t *mp)
341{
342}
343
344static int
345api_ipsec_sad_entry_add (vat_main_t *vat)
346{
347 return -1;
348}
349
350static void
351vl_api_ipsec_spd_entry_add_del_reply_t_handler (
352 vl_api_ipsec_spd_entry_add_del_reply_t *mp)
353{
354}
355
Piotr Bronowski815c6a42022-06-09 09:09:28 +0000356static void
357vl_api_ipsec_spd_entry_add_del_v2_reply_t_handler (
358 vl_api_ipsec_spd_entry_add_del_v2_reply_t *mp)
359{
360}
361
Filip Tehlar0ad06082021-07-25 14:38:45 +0000362static int
363api_ipsec_spds_dump (vat_main_t *vam)
364{
365 return -1;
366}
367
368static int
369api_ipsec_itf_dump (vat_main_t *vam)
370{
371 return -1;
372}
373
374static void
375vl_api_ipsec_sa_v3_details_t_handler (vl_api_ipsec_sa_v3_details_t *mp)
376{
377}
378
379static int
380api_ipsec_spd_interface_dump (vat_main_t *vat)
381{
382 return -1;
383}
384
385static void
386vl_api_ipsec_sa_v2_details_t_handler (vl_api_ipsec_sa_v2_details_t *mp)
387{
388}
389
390static int
391api_ipsec_sa_v2_dump (vat_main_t *mp)
392{
393 return -1;
394}
395
396static int
397api_ipsec_sa_dump (vat_main_t *vam)
398{
399 unformat_input_t *i = vam->input;
400 vl_api_ipsec_sa_dump_t *mp;
401 vl_api_control_ping_t *mp_ping;
402 u32 sa_id = ~0;
403 int ret;
404
405 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
406 {
407 if (unformat (i, "sa_id %d", &sa_id))
408 ;
409 else
410 {
411 clib_warning ("parse error '%U'", format_unformat_error, i);
412 return -99;
413 }
414 }
415
416 M (IPSEC_SA_DUMP, mp);
417
418 mp->sa_id = ntohl (sa_id);
419
420 S (mp);
421
422 /* Use a control ping for synchronization */
423 PING (&ipsec_test_main, mp_ping);
424 S (mp_ping);
425
426 W (ret);
427 return ret;
428}
429
430static void
431vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t *mp)
432{
433 vat_main_t *vam = &vat_main;
434
435 print (vam->ofp,
436 "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
437 "crypto_key %U integ_alg %u integ_key %U flags %x "
438 "tunnel_src_addr %U tunnel_dst_addr %U "
439 "salt %u seq_outbound %lu last_seq_inbound %lu "
440 "replay_window %lu stat_index %u\n",
441 ntohl (mp->entry.sad_id), ntohl (mp->sw_if_index),
442 ntohl (mp->entry.spi), ntohl (mp->entry.protocol),
443 ntohl (mp->entry.crypto_algorithm), format_hex_bytes,
444 mp->entry.crypto_key.data, mp->entry.crypto_key.length,
445 ntohl (mp->entry.integrity_algorithm), format_hex_bytes,
446 mp->entry.integrity_key.data, mp->entry.integrity_key.length,
447 ntohl (mp->entry.flags), format_vl_api_address, &mp->entry.tunnel_src,
448 format_vl_api_address, &mp->entry.tunnel_dst, ntohl (mp->salt),
449 clib_net_to_host_u64 (mp->seq_outbound),
450 clib_net_to_host_u64 (mp->last_seq_inbound),
451 clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
452}
453
454static int
455api_ipsec_spd_dump (vat_main_t *vam)
456{
457 return -1;
458}
459
460uword
461unformat_ipsec_api_crypto_alg (unformat_input_t *input, va_list *args)
462{
463 u32 *r = va_arg (*args, u32 *);
464
465 if (0)
466 ;
467#define _(v, f, s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
468 foreach_ipsec_crypto_alg
469#undef _
470 else return 0;
471 return 1;
472}
473
474uword
475unformat_ipsec_api_integ_alg (unformat_input_t *input, va_list *args)
476{
477 u32 *r = va_arg (*args, u32 *);
478
479 if (0)
480 ;
481#define _(v, f, s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
482 foreach_ipsec_integ_alg
483#undef _
484 else return 0;
485 return 1;
486}
487
488static int
489api_ipsec_sad_entry_add_del (vat_main_t *vam)
490{
491 unformat_input_t *i = vam->input;
492 vl_api_ipsec_sad_entry_add_del_t *mp;
493 u32 sad_id = 0, spi = 0;
494 u8 *ck = 0, *ik = 0;
495 u8 is_add = 1;
496
497 vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
498 vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
499 vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
500 vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
501 vl_api_address_t tun_src, tun_dst;
502 int ret;
503
504 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
505 {
506 if (unformat (i, "del"))
507 is_add = 0;
508 else if (unformat (i, "sad_id %d", &sad_id))
509 ;
510 else if (unformat (i, "spi %d", &spi))
511 ;
512 else if (unformat (i, "esp"))
513 protocol = IPSEC_API_PROTO_ESP;
514 else if (unformat (i, "tunnel_src %U", unformat_vl_api_address,
515 &tun_src))
516 {
517 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
518 if (ADDRESS_IP6 == tun_src.af)
519 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
520 }
521 else if (unformat (i, "tunnel_dst %U", unformat_vl_api_address,
522 &tun_dst))
523 {
524 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
525 if (ADDRESS_IP6 == tun_src.af)
526 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
527 }
528 else if (unformat (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg,
529 &crypto_alg))
530 ;
531 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
532 ;
533 else if (unformat (i, "integ_alg %U", unformat_ipsec_api_integ_alg,
534 &integ_alg))
535 ;
536 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
537 ;
538 else
539 {
540 clib_warning ("parse error '%U'", format_unformat_error, i);
541 return -99;
542 }
543 }
544
545 M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
546
547 mp->is_add = is_add;
548 mp->entry.sad_id = ntohl (sad_id);
549 mp->entry.protocol = protocol;
550 mp->entry.spi = ntohl (spi);
551 mp->entry.flags = flags;
552
553 mp->entry.crypto_algorithm = crypto_alg;
554 mp->entry.integrity_algorithm = integ_alg;
555 mp->entry.crypto_key.length = vec_len (ck);
556 mp->entry.integrity_key.length = vec_len (ik);
557
558 if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
559 mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
560
561 if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
562 mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
563
564 if (ck)
565 clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
566 if (ik)
567 clib_memcpy (mp->entry.integrity_key.data, ik,
568 mp->entry.integrity_key.length);
569
570 if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
571 {
572 clib_memcpy (&mp->entry.tunnel_src, &tun_src,
573 sizeof (mp->entry.tunnel_src));
574 clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
575 sizeof (mp->entry.tunnel_dst));
576 }
577
578 S (mp);
579 W (ret);
580 return ret;
581}
582
583static int
584api_ipsec_sad_entry_add_del_v2 (vat_main_t *vam)
585{
586 return -1;
587}
588
589static int
590api_ipsec_interface_add_del_spd (vat_main_t *vam)
591{
592 vnet_main_t *vnm = vnet_get_main ();
593 unformat_input_t *i = vam->input;
594 vl_api_ipsec_interface_add_del_spd_t *mp;
595 u32 sw_if_index;
596 u8 sw_if_index_set = 0;
597 u32 spd_id = (u32) ~0;
598 u8 is_add = 1;
599 int ret;
600
601 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
602 {
603 if (unformat (i, "del"))
604 is_add = 0;
605 else if (unformat (i, "spd_id %d", &spd_id))
606 ;
607 else if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
608 &sw_if_index))
609 sw_if_index_set = 1;
610 else if (unformat (i, "sw_if_index %d", &sw_if_index))
611 sw_if_index_set = 1;
612 else
613 {
614 clib_warning ("parse error '%U'", format_unformat_error, i);
615 return -99;
616 }
617 }
618
619 if (spd_id == (u32) ~0)
620 {
621 errmsg ("spd_id must be set");
622 return -99;
623 }
624
625 if (sw_if_index_set == 0)
626 {
627 errmsg ("missing interface name or sw_if_index");
628 return -99;
629 }
630
631 M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
632
633 mp->spd_id = ntohl (spd_id);
634 mp->sw_if_index = ntohl (sw_if_index);
635 mp->is_add = is_add;
636
637 S (mp);
638 W (ret);
639 return ret;
640}
641
642static int
643api_ipsec_backend_dump (vat_main_t *vam)
644{
645 return -1;
646}
647
648static int
649api_ipsec_select_backend (vat_main_t *vam)
650{
651 return -1;
652}
653
654static int
655api_ipsec_set_async_mode (vat_main_t *vam)
656{
657 return -1;
658}
659
660static int
661api_ipsec_spd_add_del (vat_main_t *vam)
662{
663 unformat_input_t *i = vam->input;
664 vl_api_ipsec_spd_add_del_t *mp;
665 u32 spd_id = ~0;
666 u8 is_add = 1;
667 int ret;
668
669 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
670 {
671 if (unformat (i, "spd_id %d", &spd_id))
672 ;
673 else if (unformat (i, "del"))
674 is_add = 0;
675 else
676 {
677 clib_warning ("parse error '%U'", format_unformat_error, i);
678 return -99;
679 }
680 }
681 if (spd_id == ~0)
682 {
683 errmsg ("spd_id must be set");
684 return -99;
685 }
686
687 M (IPSEC_SPD_ADD_DEL, mp);
688
689 mp->spd_id = ntohl (spd_id);
690 mp->is_add = is_add;
691
692 S (mp);
693 W (ret);
694 return ret;
695}
696
697#include <vnet/ipsec/ipsec.api_test.c>
698
699/*
700 * Local Variables:
701 * eval: (c-set-style "gnu")
702 * End:
703 */