8e728cea32534e91f0d269a5fb1ad923f5414bdf
[vpp.git] / plugins / ioam-plugin / ioam / lib-pot / pot_test.c
1 /*
2  * Copyright (c) 2016 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  */
15 /*
16  *------------------------------------------------------------------
17  * pot_test.c - test harness for pot plugin
18  *------------------------------------------------------------------
19  */
20
21 #include <vat/vat.h>
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vlibsocket/api.h>
25 #include <vppinfra/error.h>
26
27 /* Declare message IDs */
28 #include <ioam/lib-pot/pot_msg_enum.h>
29
30 /* define message structures */
31 #define vl_typedefs
32 #include <ioam/lib-pot/pot_all_api_h.h>
33 #undef vl_typedefs
34
35 /* declare message handlers for each api */
36
37 #define vl_endianfun             /* define message structures */
38 #include <ioam/lib-pot/pot_all_api_h.h>
39 #undef vl_endianfun
40
41 /* instantiate all the print functions we know about */
42 #define vl_print(handle, ...)
43 #define vl_printfun
44 #include <ioam/lib-pot/pot_all_api_h.h>
45 #undef vl_printfun
46
47 /* Get the API version number. */
48 #define vl_api_version(n,v) static u32 api_version=(v);
49 #include <ioam/lib-pot/pot_all_api_h.h>
50 #undef vl_api_version
51
52
53 typedef struct {
54     /* API message ID base */
55     u16 msg_id_base;
56     vat_main_t *vat_main;
57 } pot_test_main_t;
58
59 pot_test_main_t pot_test_main;
60
61 #define foreach_standard_reply_retval_handler     \
62 _(pot_profile_add_reply)                          \
63 _(pot_profile_activate_reply)                     \
64 _(pot_profile_del_reply)
65
66 #define _(n)                                            \
67     static void vl_api_##n##_t_handler                  \
68     (vl_api_##n##_t * mp)                               \
69     {                                                   \
70         vat_main_t * vam = pot_test_main.vat_main;   \
71         i32 retval = ntohl(mp->retval);                 \
72         if (vam->async_mode) {                          \
73             vam->async_errors += (retval < 0);          \
74         } else {                                        \
75             vam->retval = retval;                       \
76             vam->result_ready = 1;                      \
77         }                                               \
78     }
79 foreach_standard_reply_retval_handler;
80 #undef _
81
82 /* 
83  * Table of message reply handlers, must include boilerplate handlers
84  * we just generated
85  */
86 #define foreach_vpe_api_reply_msg                                       \
87 _(POT_PROFILE_ADD_REPLY, pot_profile_add_reply)                         \
88 _(POT_PROFILE_ACTIVATE_REPLY, pot_profile_activate_reply)               \
89 _(POT_PROFILE_DEL_REPLY, pot_profile_del_reply)                         \
90
91
92 /* M: construct, but don't yet send a message */
93
94 #define M(T,t)                                                  \
95 do {                                                            \
96     vam->result_ready = 0;                                      \
97     mp = vl_msg_api_alloc(sizeof(*mp));                         \
98     memset (mp, 0, sizeof (*mp));                               \
99     mp->_vl_msg_id = ntohs (VL_API_##T + sm->msg_id_base);      \
100     mp->client_index = vam->my_client_index;                    \
101 } while(0);
102
103 #define M2(T,t,n)                                               \
104 do {                                                            \
105     vam->result_ready = 0;                                      \
106     mp = vl_msg_api_alloc(sizeof(*mp)+(n));                     \
107     memset (mp, 0, sizeof (*mp));                               \
108     mp->_vl_msg_id = ntohs (VL_API_##T + sm->msg_id_base);      \
109     mp->client_index = vam->my_client_index;                    \
110 } while(0);
111
112 /* S: send a message */
113 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
114
115 /* W: wait for results, with timeout */
116 #define W                                       \
117 do {                                            \
118     timeout = vat_time_now (vam) + 1.0;         \
119                                                 \
120     while (vat_time_now (vam) < timeout) {      \
121         if (vam->result_ready == 1) {           \
122             return (vam->retval);               \
123         }                                       \
124     }                                           \
125     return -99;                                 \
126 } while(0);
127
128
129 static int api_pot_profile_add (vat_main_t *vam)
130 {
131 #define MAX_BITS 64
132     pot_test_main_t * sm = &pot_test_main;
133     unformat_input_t *input = vam->input;
134     vl_api_pot_profile_add_t *mp;
135     u8 *name = NULL;
136     u64 prime = 0;
137     u64 secret_share = 0;
138     u64 secret_key = 0;
139     u32  bits = MAX_BITS;
140     u64 lpc = 0, poly2 = 0;
141     f64 timeout;
142     u8 id = 0;
143     int rv = 0;
144
145     while (unformat_check_input(input) != UNFORMAT_END_OF_INPUT)
146       {
147         if (unformat(input, "name %s", &name))
148           ;
149         else if(unformat(input, "id %d", &id))
150           ;
151         else if (unformat(input, "validator-key 0x%Lx", &secret_key))
152           ;
153         else if (unformat(input, "prime-number 0x%Lx", &prime))
154           ;
155         else if (unformat(input, "secret-share 0x%Lx", &secret_share))
156           ;
157         else if (unformat(input, "polynomial-public 0x%Lx", &poly2))
158           ;
159         else if (unformat(input, "lpc 0x%Lx", &lpc))
160           ;
161         else if (unformat(input, "bits-in-random %u", &bits))
162           {
163             if (bits > MAX_BITS)
164               bits = MAX_BITS;
165           }
166         else
167         break;
168       }
169
170     if (!name)
171       {
172         errmsg ("name required\n");
173         rv = -99;
174         goto OUT;
175       }
176     
177     M2(POT_PROFILE_ADD, pot_profile_add, vec_len(name));
178
179     mp->list_name_len = vec_len(name);
180     clib_memcpy(mp->list_name, name, mp->list_name_len);
181     mp->secret_share = clib_host_to_net_u64(secret_share);
182     mp->polynomial_public = clib_host_to_net_u64(poly2);
183     mp->lpc = clib_host_to_net_u64(lpc);
184     mp->prime = clib_host_to_net_u64(prime);
185     if (secret_key != 0)
186       {
187         mp->secret_key = clib_host_to_net_u64(secret_key);
188         mp->validator = 1;
189       }
190     else
191       {
192         mp->validator = 0;
193       }
194     mp->id = id;
195     mp->max_bits = bits;
196       
197     S; W;
198   
199 OUT:
200     vec_free(name);
201     return(rv);
202 }
203
204 static int api_pot_profile_activate (vat_main_t *vam)
205 {
206 #define MAX_BITS 64
207     pot_test_main_t * sm = &pot_test_main;  
208     unformat_input_t *input = vam->input;
209     vl_api_pot_profile_activate_t *mp;
210     u8 *name = NULL;
211     u8 id = 0;
212     int rv = 0;
213     f64 timeout;
214     
215     while (unformat_check_input(input) != UNFORMAT_END_OF_INPUT)
216       {
217         if (unformat(input, "name %s", &name))
218           ;
219         else if(unformat(input, "id %d", &id))
220           ;
221         else
222         break;
223       }
224
225     if (!name)
226       {
227         errmsg ("name required\n");
228         rv = -99;
229         goto OUT;
230       }
231     
232     M2(POT_PROFILE_ACTIVATE, pot_profile_activate, vec_len(name));
233
234     mp->list_name_len = vec_len(name);
235     clib_memcpy(mp->list_name, name, mp->list_name_len);
236     mp->id = id;
237       
238     S; W;
239   
240 OUT:
241     vec_free(name);
242     return(rv);
243 }
244
245
246 static int api_pot_profile_del (vat_main_t *vam)
247 {
248     pot_test_main_t * sm = &pot_test_main;
249     vl_api_pot_profile_del_t *mp;
250     f64 timeout;
251    
252     M(POT_PROFILE_DEL, pot_profile_del);
253     mp->list_name_len = 0;
254     S; W;
255     return 0;
256 }
257
258 /* 
259  * List of messages that the api test plugin sends,
260  * and that the data plane plugin processes
261  */
262 #define foreach_vpe_api_msg \
263 _(pot_profile_add, "name <name> id [0-1] "                              \
264   "prime-number <0xu64> bits-in-random [0-64] "                         \
265   "secret-share <0xu64> lpc <0xu64> polynomial-public <0xu64> "         \
266   "[validator-key <0xu64>] [validity <0xu64>]")                         \
267 _(pot_profile_activate, "name <name> id [0-1] ")                        \
268 _(pot_profile_del, "[id <nn>]")                                         \
269
270
271 void vat_api_hookup (vat_main_t *vam)
272 {
273     pot_test_main_t * sm = &pot_test_main;
274     /* Hook up handlers for replies from the data plane plug-in */
275 #define _(N,n)                                                  \
276     vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base),     \
277                            #n,                                  \
278                            vl_api_##n##_t_handler,              \
279                            vl_noop_handler,                     \
280                            vl_api_##n##_t_endian,               \
281                            vl_api_##n##_t_print,                \
282                            sizeof(vl_api_##n##_t), 1); 
283     foreach_vpe_api_reply_msg;
284 #undef _
285
286     /* API messages we can send */
287 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
288     foreach_vpe_api_msg;
289 #undef _    
290     
291     /* Help strings */
292 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
293     foreach_vpe_api_msg;
294 #undef _
295 }
296
297 clib_error_t * vat_plugin_register (vat_main_t *vam)
298 {
299   pot_test_main_t * sm = &pot_test_main;
300   u8 * name;
301
302   sm->vat_main = vam;
303
304   name = format (0, "pot_%08x%c", api_version, 0);
305   sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
306
307   if (sm->msg_id_base != (u16) ~0)
308     vat_api_hookup (vam);
309   
310   vec_free(name);
311   
312   return 0;
313 }