api: verify message size on receipt
[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 = 0, 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 = (u8) protocol;
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 void
167 vl_api_ipsec_spd_details_t_handler (vl_api_ipsec_spd_details_t *mp)
168 {
169 }
170
171 static void
172 vl_api_ipsec_sad_entry_add_del_reply_t_handler (
173   vl_api_ipsec_sad_entry_add_del_reply_t *mp)
174 {
175 }
176
177 static void
178 vl_api_ipsec_sad_entry_add_del_v3_reply_t_handler (
179   vl_api_ipsec_sad_entry_add_del_v3_reply_t *mp)
180 {
181 }
182
183 static void
184 vl_api_ipsec_sad_entry_add_reply_t_handler (
185   vl_api_ipsec_sad_entry_add_reply_t *mp)
186 {
187 }
188
189 static int
190 api_ipsec_sad_entry_del (vat_main_t *vat)
191 {
192   return -1;
193 }
194
195 static void
196 vl_api_ipsec_sad_entry_add_del_v2_reply_t_handler (
197   vl_api_ipsec_sad_entry_add_del_v2_reply_t *mp)
198 {
199 }
200
201 static void
202 vl_api_ipsec_spd_interface_details_t_handler (
203   vl_api_ipsec_spd_interface_details_t *vat)
204 {
205 }
206
207 static int
208 api_ipsec_sad_entry_add_del_v3 (vat_main_t *vat)
209 {
210   return -1;
211 }
212
213 static int
214 api_ipsec_tunnel_protect_update (vat_main_t *vat)
215 {
216   return -1;
217 }
218
219 static void
220 vl_api_ipsec_backend_details_t_handler (vl_api_ipsec_backend_details_t *mp)
221 {
222 }
223
224 static int
225 api_ipsec_sa_v3_dump (vat_main_t *vat)
226 {
227   return -1;
228 }
229
230 static int
231 api_ipsec_tunnel_protect_dump (vat_main_t *vat)
232 {
233   return -1;
234 }
235
236 static int
237 api_ipsec_tunnel_protect_del (vat_main_t *vat)
238 {
239   return -1;
240 }
241
242 static void
243 vl_api_ipsec_tunnel_protect_details_t_handler (
244   vl_api_ipsec_tunnel_protect_details_t *mp)
245 {
246 }
247
248 static int
249 api_ipsec_sad_entry_add (vat_main_t *vat)
250 {
251   return -1;
252 }
253
254 static void
255 vl_api_ipsec_spd_entry_add_del_reply_t_handler (
256   vl_api_ipsec_spd_entry_add_del_reply_t *mp)
257 {
258 }
259
260 static int
261 api_ipsec_spds_dump (vat_main_t *vam)
262 {
263   return -1;
264 }
265
266 static int
267 api_ipsec_itf_dump (vat_main_t *vam)
268 {
269   return -1;
270 }
271
272 static void
273 vl_api_ipsec_sa_v3_details_t_handler (vl_api_ipsec_sa_v3_details_t *mp)
274 {
275 }
276
277 static int
278 api_ipsec_spd_interface_dump (vat_main_t *vat)
279 {
280   return -1;
281 }
282
283 static void
284 vl_api_ipsec_sa_v2_details_t_handler (vl_api_ipsec_sa_v2_details_t *mp)
285 {
286 }
287
288 static int
289 api_ipsec_sa_v2_dump (vat_main_t *mp)
290 {
291   return -1;
292 }
293
294 static int
295 api_ipsec_sa_dump (vat_main_t *vam)
296 {
297   unformat_input_t *i = vam->input;
298   vl_api_ipsec_sa_dump_t *mp;
299   vl_api_control_ping_t *mp_ping;
300   u32 sa_id = ~0;
301   int ret;
302
303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
304     {
305       if (unformat (i, "sa_id %d", &sa_id))
306         ;
307       else
308         {
309           clib_warning ("parse error '%U'", format_unformat_error, i);
310           return -99;
311         }
312     }
313
314   M (IPSEC_SA_DUMP, mp);
315
316   mp->sa_id = ntohl (sa_id);
317
318   S (mp);
319
320   /* Use a control ping for synchronization */
321   PING (&ipsec_test_main, mp_ping);
322   S (mp_ping);
323
324   W (ret);
325   return ret;
326 }
327
328 static void
329 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t *mp)
330 {
331   vat_main_t *vam = &vat_main;
332
333   print (vam->ofp,
334          "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
335          "crypto_key %U integ_alg %u integ_key %U flags %x "
336          "tunnel_src_addr %U tunnel_dst_addr %U "
337          "salt %u seq_outbound %lu last_seq_inbound %lu "
338          "replay_window %lu stat_index %u\n",
339          ntohl (mp->entry.sad_id), ntohl (mp->sw_if_index),
340          ntohl (mp->entry.spi), ntohl (mp->entry.protocol),
341          ntohl (mp->entry.crypto_algorithm), format_hex_bytes,
342          mp->entry.crypto_key.data, mp->entry.crypto_key.length,
343          ntohl (mp->entry.integrity_algorithm), format_hex_bytes,
344          mp->entry.integrity_key.data, mp->entry.integrity_key.length,
345          ntohl (mp->entry.flags), format_vl_api_address, &mp->entry.tunnel_src,
346          format_vl_api_address, &mp->entry.tunnel_dst, ntohl (mp->salt),
347          clib_net_to_host_u64 (mp->seq_outbound),
348          clib_net_to_host_u64 (mp->last_seq_inbound),
349          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
350 }
351
352 static int
353 api_ipsec_spd_dump (vat_main_t *vam)
354 {
355   return -1;
356 }
357
358 uword
359 unformat_ipsec_api_crypto_alg (unformat_input_t *input, va_list *args)
360 {
361   u32 *r = va_arg (*args, u32 *);
362
363   if (0)
364     ;
365 #define _(v, f, s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
366   foreach_ipsec_crypto_alg
367 #undef _
368     else return 0;
369   return 1;
370 }
371
372 uword
373 unformat_ipsec_api_integ_alg (unformat_input_t *input, va_list *args)
374 {
375   u32 *r = va_arg (*args, u32 *);
376
377   if (0)
378     ;
379 #define _(v, f, s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
380   foreach_ipsec_integ_alg
381 #undef _
382     else return 0;
383   return 1;
384 }
385
386 static int
387 api_ipsec_sad_entry_add_del (vat_main_t *vam)
388 {
389   unformat_input_t *i = vam->input;
390   vl_api_ipsec_sad_entry_add_del_t *mp;
391   u32 sad_id = 0, spi = 0;
392   u8 *ck = 0, *ik = 0;
393   u8 is_add = 1;
394
395   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
396   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
397   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
398   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
399   vl_api_address_t tun_src, tun_dst;
400   int ret;
401
402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
403     {
404       if (unformat (i, "del"))
405         is_add = 0;
406       else if (unformat (i, "sad_id %d", &sad_id))
407         ;
408       else if (unformat (i, "spi %d", &spi))
409         ;
410       else if (unformat (i, "esp"))
411         protocol = IPSEC_API_PROTO_ESP;
412       else if (unformat (i, "tunnel_src %U", unformat_vl_api_address,
413                          &tun_src))
414         {
415           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
416           if (ADDRESS_IP6 == tun_src.af)
417             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
418         }
419       else if (unformat (i, "tunnel_dst %U", unformat_vl_api_address,
420                          &tun_dst))
421         {
422           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
423           if (ADDRESS_IP6 == tun_src.af)
424             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
425         }
426       else if (unformat (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg,
427                          &crypto_alg))
428         ;
429       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
430         ;
431       else if (unformat (i, "integ_alg %U", unformat_ipsec_api_integ_alg,
432                          &integ_alg))
433         ;
434       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
435         ;
436       else
437         {
438           clib_warning ("parse error '%U'", format_unformat_error, i);
439           return -99;
440         }
441     }
442
443   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
444
445   mp->is_add = is_add;
446   mp->entry.sad_id = ntohl (sad_id);
447   mp->entry.protocol = protocol;
448   mp->entry.spi = ntohl (spi);
449   mp->entry.flags = flags;
450
451   mp->entry.crypto_algorithm = crypto_alg;
452   mp->entry.integrity_algorithm = integ_alg;
453   mp->entry.crypto_key.length = vec_len (ck);
454   mp->entry.integrity_key.length = vec_len (ik);
455
456   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
457     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
458
459   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
460     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
461
462   if (ck)
463     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
464   if (ik)
465     clib_memcpy (mp->entry.integrity_key.data, ik,
466                  mp->entry.integrity_key.length);
467
468   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
469     {
470       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
471                    sizeof (mp->entry.tunnel_src));
472       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
473                    sizeof (mp->entry.tunnel_dst));
474     }
475
476   S (mp);
477   W (ret);
478   return ret;
479 }
480
481 static int
482 api_ipsec_sad_entry_add_del_v2 (vat_main_t *vam)
483 {
484   return -1;
485 }
486
487 static int
488 api_ipsec_interface_add_del_spd (vat_main_t *vam)
489 {
490   vnet_main_t *vnm = vnet_get_main ();
491   unformat_input_t *i = vam->input;
492   vl_api_ipsec_interface_add_del_spd_t *mp;
493   u32 sw_if_index;
494   u8 sw_if_index_set = 0;
495   u32 spd_id = (u32) ~0;
496   u8 is_add = 1;
497   int ret;
498
499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
500     {
501       if (unformat (i, "del"))
502         is_add = 0;
503       else if (unformat (i, "spd_id %d", &spd_id))
504         ;
505       else if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
506                          &sw_if_index))
507         sw_if_index_set = 1;
508       else if (unformat (i, "sw_if_index %d", &sw_if_index))
509         sw_if_index_set = 1;
510       else
511         {
512           clib_warning ("parse error '%U'", format_unformat_error, i);
513           return -99;
514         }
515     }
516
517   if (spd_id == (u32) ~0)
518     {
519       errmsg ("spd_id must be set");
520       return -99;
521     }
522
523   if (sw_if_index_set == 0)
524     {
525       errmsg ("missing interface name or sw_if_index");
526       return -99;
527     }
528
529   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
530
531   mp->spd_id = ntohl (spd_id);
532   mp->sw_if_index = ntohl (sw_if_index);
533   mp->is_add = is_add;
534
535   S (mp);
536   W (ret);
537   return ret;
538 }
539
540 static int
541 api_ipsec_backend_dump (vat_main_t *vam)
542 {
543   return -1;
544 }
545
546 static int
547 api_ipsec_select_backend (vat_main_t *vam)
548 {
549   return -1;
550 }
551
552 static int
553 api_ipsec_set_async_mode (vat_main_t *vam)
554 {
555   return -1;
556 }
557
558 static int
559 api_ipsec_spd_add_del (vat_main_t *vam)
560 {
561   unformat_input_t *i = vam->input;
562   vl_api_ipsec_spd_add_del_t *mp;
563   u32 spd_id = ~0;
564   u8 is_add = 1;
565   int ret;
566
567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
568     {
569       if (unformat (i, "spd_id %d", &spd_id))
570         ;
571       else if (unformat (i, "del"))
572         is_add = 0;
573       else
574         {
575           clib_warning ("parse error '%U'", format_unformat_error, i);
576           return -99;
577         }
578     }
579   if (spd_id == ~0)
580     {
581       errmsg ("spd_id must be set");
582       return -99;
583     }
584
585   M (IPSEC_SPD_ADD_DEL, mp);
586
587   mp->spd_id = ntohl (spd_id);
588   mp->is_add = is_add;
589
590   S (mp);
591   W (ret);
592   return ret;
593 }
594
595 #include <vnet/ipsec/ipsec.api_test.c>
596
597 /*
598  * Local Variables:
599  * eval: (c-set-style "gnu")
600  * End:
601  */