Repair vlib API socket server
[vpp.git] / src / plugins / flowprobe / flowprobe_test.c
1 /*
2  * flowprobe.c - skeleton vpp-api-test plug-in
3  *
4  * Copyright (c) <current-year> <your-organization>
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #include <vat/vat.h>
18 #include <vlibapi/api.h>
19 #include <vlibmemory/api.h>
20 #include <vppinfra/error.h>
21 #include <flowprobe/flowprobe.h>
22
23 #define __plugin_msg_base flowprobe_test_main.msg_id_base
24 #include <vlibapi/vat_helper_macros.h>
25
26 /**
27  * @file vpp_api_test plugin
28  */
29
30 uword unformat_sw_if_index (unformat_input_t * input, va_list * args);
31
32 /* Declare message IDs */
33 #include <flowprobe/flowprobe_msg_enum.h>
34
35 /* define message structures */
36 #define vl_typedefs
37 #include <flowprobe/flowprobe_all_api_h.h>
38 #undef vl_typedefs
39
40 /* declare message handlers for each api */
41
42 #define vl_endianfun            /* define message structures */
43 #include <flowprobe/flowprobe_all_api_h.h>
44 #undef vl_endianfun
45
46 /* instantiate all the print functions we know about */
47 #define vl_print(handle, ...)
48 #define vl_printfun
49 #include <flowprobe/flowprobe_all_api_h.h>
50 #undef vl_printfun
51
52 /* Get the API version number. */
53 #define vl_api_version(n,v) static u32 api_version=(v);
54 #include <flowprobe/flowprobe_all_api_h.h>
55 #undef vl_api_version
56
57 typedef struct
58 {
59     /** API message ID base */
60   u16 msg_id_base;
61     /** vat_main_t pointer */
62   vat_main_t *vat_main;
63 } flowprobe_test_main_t;
64
65 flowprobe_test_main_t flowprobe_test_main;
66
67 #define foreach_standard_reply_retval_handler   \
68 _(flowprobe_tx_interface_add_del_reply)        \
69 _(flowprobe_params_reply)
70
71 #define _(n)                                            \
72     static void vl_api_##n##_t_handler                  \
73     (vl_api_##n##_t * mp)                               \
74     {                                                   \
75         vat_main_t * vam = flowprobe_test_main.vat_main;   \
76         i32 retval = ntohl(mp->retval);                 \
77         if (vam->async_mode) {                          \
78             vam->async_errors += (retval < 0);          \
79         } else {                                        \
80             vam->retval = retval;                       \
81             vam->result_ready = 1;                      \
82         }                                               \
83     }
84 foreach_standard_reply_retval_handler;
85 #undef _
86
87 /*
88  * Table of message reply handlers, must include boilerplate handlers
89  * we just generated
90  */
91 #define foreach_vpe_api_reply_msg               \
92 _(FLOWPROBE_TX_INTERFACE_ADD_DEL_REPLY,        \
93   flowprobe_tx_interface_add_del_reply)        \
94 _(FLOWPROBE_PARAMS_REPLY, flowprobe_params_reply)
95
96 static int
97 api_flowprobe_tx_interface_add_del (vat_main_t * vam)
98 {
99   unformat_input_t *i = vam->input;
100   int enable_disable = 1;
101   u8 which = FLOW_VARIANT_IP4;
102   u32 sw_if_index = ~0;
103   vl_api_flowprobe_tx_interface_add_del_t *mp;
104   int ret;
105
106   /* Parse args required to build the message */
107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
108     {
109       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
110         ;
111       else if (unformat (i, "sw_if_index %d", &sw_if_index))
112         ;
113       else if (unformat (i, "disable"))
114         enable_disable = 0;
115       else if (unformat (i, "ip4"))
116         which = FLOW_VARIANT_IP4;
117       else if (unformat (i, "ip6"))
118         which = FLOW_VARIANT_IP6;
119       else if (unformat (i, "l2"))
120         which = FLOW_VARIANT_L2;
121       else
122         break;
123     }
124
125   if (sw_if_index == ~0)
126     {
127       errmsg ("missing interface name / explicit sw_if_index number \n");
128       return -99;
129     }
130
131   /* Construct the API message */
132   M (FLOWPROBE_TX_INTERFACE_ADD_DEL, mp);
133   mp->sw_if_index = ntohl (sw_if_index);
134   mp->is_add = enable_disable;
135   mp->which = which;
136
137   /* send it... */
138   S (mp);
139
140   /* Wait for a reply... */
141   W (ret);
142   return ret;
143 }
144
145 static int
146 api_flowprobe_params (vat_main_t * vam)
147 {
148   unformat_input_t *i = vam->input;
149   u8 record_l2 = 0, record_l3 = 0, record_l4 = 0;
150   u32 active_timer = ~0;
151   u32 passive_timer = ~0;
152   vl_api_flowprobe_params_t *mp;
153   int ret;
154
155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
156     {
157       if (unformat (i, "active %d", &active_timer))
158         ;
159       else if (unformat (i, "passive %d", &passive_timer))
160         ;
161       else if (unformat (i, "record"))
162         while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
163           {
164             if (unformat (i, "l2"))
165               record_l2 = 1;
166             else if (unformat (i, "l3"))
167               record_l3 = 1;
168             else if (unformat (i, "l4"))
169               record_l4 = 1;
170             else
171               break;
172           }
173       else
174         break;
175     }
176
177   if (passive_timer > 0 && active_timer > passive_timer)
178     {
179       errmsg ("Passive timer has to be greater than active one...\n");
180       return -99;
181     }
182
183   /* Construct the API message */
184   M (FLOWPROBE_PARAMS, mp);
185   mp->record_l2 = record_l2;
186   mp->record_l3 = record_l3;
187   mp->record_l4 = record_l4;
188   mp->active_timer = ntohl (active_timer);
189   mp->passive_timer = ntohl (passive_timer);
190
191   /* send it... */
192   S (mp);
193
194   /* Wait for a reply... */
195   W (ret);
196
197   return ret;
198 }
199
200 /*
201  * List of messages that the api test plugin sends,
202  * and that the data plane plugin processes
203  */
204 #define foreach_vpe_api_msg \
205 _(flowprobe_tx_interface_add_del, "<intfc> [disable]") \
206 _(flowprobe_params, "record <[l2] [l3] [l4]> [active <timer> passive <timer>]")
207
208 static void
209 flowprobe_vat_api_hookup (vat_main_t * vam)
210 {
211   flowprobe_test_main_t *sm = &flowprobe_test_main;
212   /* Hook up handlers for replies from the data plane plug-in */
213 #define _(N,n)                                                  \
214     vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base),     \
215                            #n,                                  \
216                            vl_api_##n##_t_handler,              \
217                            vl_noop_handler,                     \
218                            vl_api_##n##_t_endian,               \
219                            vl_api_##n##_t_print,                \
220                            sizeof(vl_api_##n##_t), 1);
221   foreach_vpe_api_reply_msg;
222 #undef _
223
224   /* API messages we can send */
225 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
226   foreach_vpe_api_msg;
227 #undef _
228
229   /* Help strings */
230 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
231   foreach_vpe_api_msg;
232 #undef _
233 }
234
235 clib_error_t *
236 vat_plugin_register (vat_main_t * vam)
237 {
238   flowprobe_test_main_t *sm = &flowprobe_test_main;
239   u8 *name;
240
241   sm->vat_main = vam;
242
243   /* Ask the vpp engine for the first assigned message-id */
244   name = format (0, "flowprobe_%08x%c", api_version, 0);
245   sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
246
247   /* Don't attempt to hook up API messages if the data plane plugin is AWOL */
248   if (sm->msg_id_base != (u16) ~ 0)
249     flowprobe_vat_api_hookup (vam);
250
251   vec_free (name);
252
253   return 0;
254 }
255
256 /*
257  * fd.io coding-style-patch-verification: ON
258  *
259  * Local Variables:
260  * eval: (c-set-style "gnu")
261  * End:
262  */