blob: 86d09f18a5c39405551b57098dc46269e59bdcc2 [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
Maxime Peim0e2f1882022-12-22 11:26:57 +0000285static void
286vl_api_ipsec_sad_entry_add_v2_reply_t_handler (
287 vl_api_ipsec_sad_entry_add_reply_t *mp)
288{
289}
290
Filip Tehlar0ad06082021-07-25 14:38:45 +0000291static int
292api_ipsec_sad_entry_del (vat_main_t *vat)
293{
294 return -1;
295}
296
Maxime Peim1271e3a2023-03-20 14:13:56 +0000297static int
298api_ipsec_sad_bind (vat_main_t *vat)
299{
300 return -1;
301}
302
303static int
304api_ipsec_sad_unbind (vat_main_t *vat)
305{
306 return -1;
307}
308
Filip Tehlar0ad06082021-07-25 14:38:45 +0000309static void
310vl_api_ipsec_sad_entry_add_del_v2_reply_t_handler (
311 vl_api_ipsec_sad_entry_add_del_v2_reply_t *mp)
312{
313}
314
315static void
316vl_api_ipsec_spd_interface_details_t_handler (
317 vl_api_ipsec_spd_interface_details_t *vat)
318{
319}
320
321static int
322api_ipsec_sad_entry_add_del_v3 (vat_main_t *vat)
323{
324 return -1;
325}
326
327static int
Arthur de Kerhor4117b242022-08-31 19:13:03 +0200328api_ipsec_sad_entry_update (vat_main_t *vat)
329{
330 return -1;
331}
332
333static int
Filip Tehlar0ad06082021-07-25 14:38:45 +0000334api_ipsec_tunnel_protect_update (vat_main_t *vat)
335{
336 return -1;
337}
338
339static void
340vl_api_ipsec_backend_details_t_handler (vl_api_ipsec_backend_details_t *mp)
341{
342}
343
344static int
345api_ipsec_sa_v3_dump (vat_main_t *vat)
346{
347 return -1;
348}
349
350static int
Maxime Peim0e2f1882022-12-22 11:26:57 +0000351api_ipsec_sa_v4_dump (vat_main_t *vat)
352{
353 return -1;
354}
355
356static int
357api_ipsec_sa_v5_dump (vat_main_t *vat)
358{
359 return -1;
360}
361
362static int
Filip Tehlar0ad06082021-07-25 14:38:45 +0000363api_ipsec_tunnel_protect_dump (vat_main_t *vat)
364{
365 return -1;
366}
367
368static int
369api_ipsec_tunnel_protect_del (vat_main_t *vat)
370{
371 return -1;
372}
373
374static void
375vl_api_ipsec_tunnel_protect_details_t_handler (
376 vl_api_ipsec_tunnel_protect_details_t *mp)
377{
378}
379
380static int
381api_ipsec_sad_entry_add (vat_main_t *vat)
382{
383 return -1;
384}
385
Maxime Peim0e2f1882022-12-22 11:26:57 +0000386static int
387api_ipsec_sad_entry_add_v2 (vat_main_t *vat)
388{
389 return -1;
390}
391
Filip Tehlar0ad06082021-07-25 14:38:45 +0000392static void
393vl_api_ipsec_spd_entry_add_del_reply_t_handler (
394 vl_api_ipsec_spd_entry_add_del_reply_t *mp)
395{
396}
397
Piotr Bronowski815c6a42022-06-09 09:09:28 +0000398static void
399vl_api_ipsec_spd_entry_add_del_v2_reply_t_handler (
400 vl_api_ipsec_spd_entry_add_del_v2_reply_t *mp)
401{
402}
403
Filip Tehlar0ad06082021-07-25 14:38:45 +0000404static int
405api_ipsec_spds_dump (vat_main_t *vam)
406{
407 return -1;
408}
409
410static int
411api_ipsec_itf_dump (vat_main_t *vam)
412{
413 return -1;
414}
415
416static void
417vl_api_ipsec_sa_v3_details_t_handler (vl_api_ipsec_sa_v3_details_t *mp)
418{
419}
420
Maxime Peim0e2f1882022-12-22 11:26:57 +0000421static void
422vl_api_ipsec_sa_v4_details_t_handler (vl_api_ipsec_sa_v4_details_t *mp)
423{
424}
425
426static void
427vl_api_ipsec_sa_v5_details_t_handler (vl_api_ipsec_sa_v5_details_t *mp)
428{
429}
430
Filip Tehlar0ad06082021-07-25 14:38:45 +0000431static int
432api_ipsec_spd_interface_dump (vat_main_t *vat)
433{
434 return -1;
435}
436
437static void
438vl_api_ipsec_sa_v2_details_t_handler (vl_api_ipsec_sa_v2_details_t *mp)
439{
440}
441
442static int
443api_ipsec_sa_v2_dump (vat_main_t *mp)
444{
445 return -1;
446}
447
448static int
449api_ipsec_sa_dump (vat_main_t *vam)
450{
451 unformat_input_t *i = vam->input;
452 vl_api_ipsec_sa_dump_t *mp;
453 vl_api_control_ping_t *mp_ping;
454 u32 sa_id = ~0;
455 int ret;
456
457 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
458 {
459 if (unformat (i, "sa_id %d", &sa_id))
460 ;
461 else
462 {
463 clib_warning ("parse error '%U'", format_unformat_error, i);
464 return -99;
465 }
466 }
467
468 M (IPSEC_SA_DUMP, mp);
469
470 mp->sa_id = ntohl (sa_id);
471
472 S (mp);
473
474 /* Use a control ping for synchronization */
475 PING (&ipsec_test_main, mp_ping);
476 S (mp_ping);
477
478 W (ret);
479 return ret;
480}
481
482static void
Filip Tehlar0ad06082021-07-25 14:38:45 +0000483vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t *mp)
484{
485 vat_main_t *vam = &vat_main;
486
487 print (vam->ofp,
488 "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
489 "crypto_key %U integ_alg %u integ_key %U flags %x "
490 "tunnel_src_addr %U tunnel_dst_addr %U "
491 "salt %u seq_outbound %lu last_seq_inbound %lu "
492 "replay_window %lu stat_index %u\n",
493 ntohl (mp->entry.sad_id), ntohl (mp->sw_if_index),
494 ntohl (mp->entry.spi), ntohl (mp->entry.protocol),
495 ntohl (mp->entry.crypto_algorithm), format_hex_bytes,
496 mp->entry.crypto_key.data, mp->entry.crypto_key.length,
497 ntohl (mp->entry.integrity_algorithm), format_hex_bytes,
498 mp->entry.integrity_key.data, mp->entry.integrity_key.length,
499 ntohl (mp->entry.flags), format_vl_api_address, &mp->entry.tunnel_src,
500 format_vl_api_address, &mp->entry.tunnel_dst, ntohl (mp->salt),
501 clib_net_to_host_u64 (mp->seq_outbound),
502 clib_net_to_host_u64 (mp->last_seq_inbound),
503 clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
504}
505
506static int
507api_ipsec_spd_dump (vat_main_t *vam)
508{
509 return -1;
510}
511
512uword
513unformat_ipsec_api_crypto_alg (unformat_input_t *input, va_list *args)
514{
515 u32 *r = va_arg (*args, u32 *);
516
517 if (0)
518 ;
519#define _(v, f, s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
520 foreach_ipsec_crypto_alg
521#undef _
522 else return 0;
523 return 1;
524}
525
526uword
527unformat_ipsec_api_integ_alg (unformat_input_t *input, va_list *args)
528{
529 u32 *r = va_arg (*args, u32 *);
530
531 if (0)
532 ;
533#define _(v, f, s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
534 foreach_ipsec_integ_alg
535#undef _
536 else return 0;
537 return 1;
538}
539
540static int
541api_ipsec_sad_entry_add_del (vat_main_t *vam)
542{
543 unformat_input_t *i = vam->input;
544 vl_api_ipsec_sad_entry_add_del_t *mp;
545 u32 sad_id = 0, spi = 0;
546 u8 *ck = 0, *ik = 0;
547 u8 is_add = 1;
548
549 vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
550 vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
551 vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
552 vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
553 vl_api_address_t tun_src, tun_dst;
554 int ret;
555
556 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
557 {
558 if (unformat (i, "del"))
559 is_add = 0;
560 else if (unformat (i, "sad_id %d", &sad_id))
561 ;
562 else if (unformat (i, "spi %d", &spi))
563 ;
564 else if (unformat (i, "esp"))
565 protocol = IPSEC_API_PROTO_ESP;
566 else if (unformat (i, "tunnel_src %U", unformat_vl_api_address,
567 &tun_src))
568 {
569 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
570 if (ADDRESS_IP6 == tun_src.af)
571 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
572 }
573 else if (unformat (i, "tunnel_dst %U", unformat_vl_api_address,
574 &tun_dst))
575 {
576 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
577 if (ADDRESS_IP6 == tun_src.af)
578 flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
579 }
580 else if (unformat (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg,
581 &crypto_alg))
582 ;
583 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
584 ;
585 else if (unformat (i, "integ_alg %U", unformat_ipsec_api_integ_alg,
586 &integ_alg))
587 ;
588 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
589 ;
590 else
591 {
592 clib_warning ("parse error '%U'", format_unformat_error, i);
593 return -99;
594 }
595 }
596
597 M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
598
599 mp->is_add = is_add;
600 mp->entry.sad_id = ntohl (sad_id);
601 mp->entry.protocol = protocol;
602 mp->entry.spi = ntohl (spi);
603 mp->entry.flags = flags;
604
605 mp->entry.crypto_algorithm = crypto_alg;
606 mp->entry.integrity_algorithm = integ_alg;
607 mp->entry.crypto_key.length = vec_len (ck);
608 mp->entry.integrity_key.length = vec_len (ik);
609
610 if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
611 mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
612
613 if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
614 mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
615
616 if (ck)
617 clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
618 if (ik)
619 clib_memcpy (mp->entry.integrity_key.data, ik,
620 mp->entry.integrity_key.length);
621
622 if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
623 {
624 clib_memcpy (&mp->entry.tunnel_src, &tun_src,
625 sizeof (mp->entry.tunnel_src));
626 clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
627 sizeof (mp->entry.tunnel_dst));
628 }
629
630 S (mp);
631 W (ret);
632 return ret;
633}
634
635static int
636api_ipsec_sad_entry_add_del_v2 (vat_main_t *vam)
637{
638 return -1;
639}
640
641static int
642api_ipsec_interface_add_del_spd (vat_main_t *vam)
643{
644 vnet_main_t *vnm = vnet_get_main ();
645 unformat_input_t *i = vam->input;
646 vl_api_ipsec_interface_add_del_spd_t *mp;
647 u32 sw_if_index;
648 u8 sw_if_index_set = 0;
649 u32 spd_id = (u32) ~0;
650 u8 is_add = 1;
651 int ret;
652
653 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
654 {
655 if (unformat (i, "del"))
656 is_add = 0;
657 else if (unformat (i, "spd_id %d", &spd_id))
658 ;
659 else if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
660 &sw_if_index))
661 sw_if_index_set = 1;
662 else if (unformat (i, "sw_if_index %d", &sw_if_index))
663 sw_if_index_set = 1;
664 else
665 {
666 clib_warning ("parse error '%U'", format_unformat_error, i);
667 return -99;
668 }
669 }
670
671 if (spd_id == (u32) ~0)
672 {
673 errmsg ("spd_id must be set");
674 return -99;
675 }
676
677 if (sw_if_index_set == 0)
678 {
679 errmsg ("missing interface name or sw_if_index");
680 return -99;
681 }
682
683 M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
684
685 mp->spd_id = ntohl (spd_id);
686 mp->sw_if_index = ntohl (sw_if_index);
687 mp->is_add = is_add;
688
689 S (mp);
690 W (ret);
691 return ret;
692}
693
694static int
695api_ipsec_backend_dump (vat_main_t *vam)
696{
697 return -1;
698}
699
700static int
701api_ipsec_select_backend (vat_main_t *vam)
702{
703 return -1;
704}
705
706static int
707api_ipsec_set_async_mode (vat_main_t *vam)
708{
709 return -1;
710}
711
712static int
713api_ipsec_spd_add_del (vat_main_t *vam)
714{
715 unformat_input_t *i = vam->input;
716 vl_api_ipsec_spd_add_del_t *mp;
717 u32 spd_id = ~0;
718 u8 is_add = 1;
719 int ret;
720
721 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
722 {
723 if (unformat (i, "spd_id %d", &spd_id))
724 ;
725 else if (unformat (i, "del"))
726 is_add = 0;
727 else
728 {
729 clib_warning ("parse error '%U'", format_unformat_error, i);
730 return -99;
731 }
732 }
733 if (spd_id == ~0)
734 {
735 errmsg ("spd_id must be set");
736 return -99;
737 }
738
739 M (IPSEC_SPD_ADD_DEL, mp);
740
741 mp->spd_id = ntohl (spd_id);
742 mp->is_add = is_add;
743
744 S (mp);
745 W (ret);
746 return ret;
747}
748
749#include <vnet/ipsec/ipsec.api_test.c>
750
751/*
752 * Local Variables:
753 * eval: (c-set-style "gnu")
754 * End:
755 */