udp: fix csum computation when offload disabled
[vpp.git] / src / vnet / ipsec / ipsec_test.c
1 /* 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
29 #define vl_calcsizefun
30 #include <vnet/ipsec/ipsec.api.h>
31 #undef vl_calcsizefun
32
33 typedef 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
41 static ipsec_test_main_t ipsec_test_main;
42
43 static void
44 vl_api_ipsec_spds_details_t_handler (vl_api_ipsec_spds_details_t *mp)
45 {
46 }
47
48 static void
49 vl_api_ipsec_itf_details_t_handler (vl_api_ipsec_itf_details_t *mp)
50 {
51 }
52
53 static int
54 api_ipsec_itf_delete (vat_main_t *vat)
55 {
56   return -1;
57 }
58
59 static int
60 api_ipsec_itf_create (vat_main_t *vat)
61 {
62   return -1;
63 }
64
65 static void
66 vl_api_ipsec_itf_create_reply_t_handler (vl_api_ipsec_itf_create_reply_t *vat)
67 {
68 }
69
70 static int
71 api_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;
76   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
166 static int
167 api_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;
173   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
262 static void
263 vl_api_ipsec_spd_details_t_handler (vl_api_ipsec_spd_details_t *mp)
264 {
265 }
266
267 static void
268 vl_api_ipsec_sad_entry_add_del_reply_t_handler (
269   vl_api_ipsec_sad_entry_add_del_reply_t *mp)
270 {
271 }
272
273 static void
274 vl_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
279 static void
280 vl_api_ipsec_sad_entry_add_reply_t_handler (
281   vl_api_ipsec_sad_entry_add_reply_t *mp)
282 {
283 }
284
285 static void
286 vl_api_ipsec_sad_entry_add_v2_reply_t_handler (
287   vl_api_ipsec_sad_entry_add_reply_t *mp)
288 {
289 }
290
291 static int
292 api_ipsec_sad_entry_del (vat_main_t *vat)
293 {
294   return -1;
295 }
296
297 static int
298 api_ipsec_sad_bind (vat_main_t *vat)
299 {
300   return -1;
301 }
302
303 static int
304 api_ipsec_sad_unbind (vat_main_t *vat)
305 {
306   return -1;
307 }
308
309 static void
310 vl_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
315 static void
316 vl_api_ipsec_spd_interface_details_t_handler (
317   vl_api_ipsec_spd_interface_details_t *vat)
318 {
319 }
320
321 static int
322 api_ipsec_sad_entry_add_del_v3 (vat_main_t *vat)
323 {
324   return -1;
325 }
326
327 static int
328 api_ipsec_sad_entry_update (vat_main_t *vat)
329 {
330   return -1;
331 }
332
333 static int
334 api_ipsec_tunnel_protect_update (vat_main_t *vat)
335 {
336   return -1;
337 }
338
339 static void
340 vl_api_ipsec_backend_details_t_handler (vl_api_ipsec_backend_details_t *mp)
341 {
342 }
343
344 static int
345 api_ipsec_sa_v3_dump (vat_main_t *vat)
346 {
347   return -1;
348 }
349
350 static int
351 api_ipsec_sa_v4_dump (vat_main_t *vat)
352 {
353   return -1;
354 }
355
356 static int
357 api_ipsec_sa_v5_dump (vat_main_t *vat)
358 {
359   return -1;
360 }
361
362 static int
363 api_ipsec_tunnel_protect_dump (vat_main_t *vat)
364 {
365   return -1;
366 }
367
368 static int
369 api_ipsec_tunnel_protect_del (vat_main_t *vat)
370 {
371   return -1;
372 }
373
374 static void
375 vl_api_ipsec_tunnel_protect_details_t_handler (
376   vl_api_ipsec_tunnel_protect_details_t *mp)
377 {
378 }
379
380 static int
381 api_ipsec_sad_entry_add (vat_main_t *vat)
382 {
383   return -1;
384 }
385
386 static int
387 api_ipsec_sad_entry_add_v2 (vat_main_t *vat)
388 {
389   return -1;
390 }
391
392 static void
393 vl_api_ipsec_spd_entry_add_del_reply_t_handler (
394   vl_api_ipsec_spd_entry_add_del_reply_t *mp)
395 {
396 }
397
398 static void
399 vl_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
404 static int
405 api_ipsec_spds_dump (vat_main_t *vam)
406 {
407   return -1;
408 }
409
410 static int
411 api_ipsec_itf_dump (vat_main_t *vam)
412 {
413   return -1;
414 }
415
416 static void
417 vl_api_ipsec_sa_v3_details_t_handler (vl_api_ipsec_sa_v3_details_t *mp)
418 {
419 }
420
421 static void
422 vl_api_ipsec_sa_v4_details_t_handler (vl_api_ipsec_sa_v4_details_t *mp)
423 {
424 }
425
426 static void
427 vl_api_ipsec_sa_v5_details_t_handler (vl_api_ipsec_sa_v5_details_t *mp)
428 {
429 }
430
431 static int
432 api_ipsec_spd_interface_dump (vat_main_t *vat)
433 {
434   return -1;
435 }
436
437 static void
438 vl_api_ipsec_sa_v2_details_t_handler (vl_api_ipsec_sa_v2_details_t *mp)
439 {
440 }
441
442 static int
443 api_ipsec_sa_v2_dump (vat_main_t *mp)
444 {
445   return -1;
446 }
447
448 static int
449 api_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
482 static void
483 vl_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
506 static int
507 api_ipsec_spd_dump (vat_main_t *vam)
508 {
509   return -1;
510 }
511
512 uword
513 unformat_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
526 uword
527 unformat_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
540 static int
541 api_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
635 static int
636 api_ipsec_sad_entry_add_del_v2 (vat_main_t *vam)
637 {
638   return -1;
639 }
640
641 static int
642 api_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
694 static int
695 api_ipsec_backend_dump (vat_main_t *vam)
696 {
697   return -1;
698 }
699
700 static int
701 api_ipsec_select_backend (vat_main_t *vam)
702 {
703   return -1;
704 }
705
706 static int
707 api_ipsec_set_async_mode (vat_main_t *vam)
708 {
709   return -1;
710 }
711
712 static int
713 api_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  */