blob: 904540b679e6ffb3678b2709247457be2c99024c [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 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#include "vat.h"
16#include "plugin.h"
17
18vat_main_t vat_main;
19
Dave Barach72d72232016-08-04 10:15:08 -040020int
21connect_to_vpe (char *name)
Ed Warnickecb9cada2015-12-08 15:45:58 -070022{
Dave Barach72d72232016-08-04 10:15:08 -040023 vat_main_t *vam = &vat_main;
24 api_main_t *am = &api_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -070025
Dave Barach72d72232016-08-04 10:15:08 -040026 if (vl_client_connect_to_vlib ("/vpe-api", name, 32) < 0)
27 return -1;
Ed Warnickecb9cada2015-12-08 15:45:58 -070028
Dave Barach72d72232016-08-04 10:15:08 -040029 vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
30 vam->my_client_index = am->my_client_index;
31
32 return 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -070033}
34
Dave Barach72d72232016-08-04 10:15:08 -040035void
36vlib_cli_output (struct vlib_main_t *vm, char *fmt, ...)
Ed Warnickecb9cada2015-12-08 15:45:58 -070037{
Dave Barach72d72232016-08-04 10:15:08 -040038 clib_warning ("BUG");
Ed Warnickecb9cada2015-12-08 15:45:58 -070039}
40
Dave Barach72d72232016-08-04 10:15:08 -040041
42static u8 *
43format_api_error (u8 * s, va_list * args)
Ed Warnickecb9cada2015-12-08 15:45:58 -070044{
Dave Barach72d72232016-08-04 10:15:08 -040045 vat_main_t *vam = va_arg (*args, vat_main_t *);
46 i32 error = va_arg (*args, u32);
47 uword *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -070048
Dave Barach72d72232016-08-04 10:15:08 -040049 p = hash_get (vam->error_string_by_error_number, -error);
Ed Warnickecb9cada2015-12-08 15:45:58 -070050
Dave Barach72d72232016-08-04 10:15:08 -040051 if (p)
52 s = format (s, "%s", p[0]);
53 else
54 s = format (s, "%d", error);
55 return s;
56}
Ed Warnickecb9cada2015-12-08 15:45:58 -070057
Dave Barach72d72232016-08-04 10:15:08 -040058void
59do_one_file (vat_main_t * vam)
60{
61 int rv;
62 int (*fp) (vat_main_t * vam);
63 int arg_len;
64 unformat_input_t _input;
65 u8 *cmdp, *argsp;
66 uword *p;
67 u8 *this_cmd = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -070068
Dave Barach72d72232016-08-04 10:15:08 -040069 vam->input = &_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -070070
Dave Barach72d72232016-08-04 10:15:08 -040071 /* Used by the "quit" command handler */
72 if (setjmp (vam->jump_buf) != 0)
73 return;
Ed Warnickecb9cada2015-12-08 15:45:58 -070074
Dave Barach72d72232016-08-04 10:15:08 -040075 while (1)
76 {
77 if (vam->ifp == stdin)
78 {
79 if (vam->exec_mode == 0)
80 rv = write (1, "vat# ", 5);
81 else
82 rv = write (1, "exec# ", 6);
83 }
84
85 _vec_len (vam->inbuf) = 4096;
86
87 if (fgets ((char *) vam->inbuf, vec_len (vam->inbuf), vam->ifp) == 0)
88 break;
89
90 vam->input_line_number++;
91
92 vec_free (this_cmd);
93
94 this_cmd =
95 (u8 *) clib_macro_eval (&vam->macro_main, (char *) vam->inbuf,
96 1 /* complain */ );
97
98 if (vam->exec_mode == 0)
99 {
100 /* Split input into cmd + args */
101 cmdp = this_cmd;
102
103 while (cmdp < (this_cmd + vec_len (this_cmd)))
104 {
105 if (*cmdp == ' ' || *cmdp == '\t' || *cmdp == '\n')
106 {
107 cmdp++;
108 }
109 else
110 break;
111 }
112 argsp = cmdp;
113 while (argsp < (this_cmd + vec_len (this_cmd)))
114 {
115 if (*argsp != ' ' && *argsp != '\t' && *argsp != '\n')
116 {
117 argsp++;
118 }
119 else
120 break;
121 }
122 *argsp++ = 0;
123 while (argsp < (this_cmd + vec_len (this_cmd)))
124 {
125 if (*argsp == ' ' || *argsp == '\t' || *argsp == '\n')
126 {
127 argsp++;
128 }
129 else
130 break;
131 }
132
133
134 /* Blank input line? */
135 if (*cmdp == 0)
136 continue;
137
138 p = hash_get_mem (vam->function_by_name, cmdp);
139 if (p == 0)
140 {
141 errmsg ("'%s': function not found\n", cmdp);
142 continue;
143 }
144
145 arg_len = strlen ((char *) argsp);
146
147 unformat_init_string (vam->input, (char *) argsp, arg_len);
148 fp = (void *) p[0];
149 }
150 else
151 {
152 unformat_init_string (vam->input, (char *) this_cmd,
153 strlen ((char *) this_cmd));
154 cmdp = this_cmd;
155 fp = exec;
156 }
157
158 rv = (*fp) (vam);
159 if (rv < 0)
160 errmsg ("%s error: %U\n", cmdp, format_api_error, vam, rv);
161 unformat_free (vam->input);
162
163 if (vam->regenerate_interface_table)
164 {
165 vam->regenerate_interface_table = 0;
166 api_sw_interface_dump (vam);
167 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700168 }
169}
170
Dave Barach72d72232016-08-04 10:15:08 -0400171static void
172init_error_string_table (vat_main_t * vam)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700173{
174
Dave Barach72d72232016-08-04 10:15:08 -0400175 vam->error_string_by_error_number = hash_create (0, sizeof (uword));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700176
177#define _(n,v,s) hash_set (vam->error_string_by_error_number, -v, s);
Dave Barach72d72232016-08-04 10:15:08 -0400178 foreach_vnet_api_error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700179#undef _
180
Dave Barach72d72232016-08-04 10:15:08 -0400181 hash_set (vam->error_string_by_error_number, 99, "Misc");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700182}
183
Dave Barach72d72232016-08-04 10:15:08 -0400184static i8 *
185eval_current_file (macro_main_t * mm, i32 complain)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700186{
Dave Barach72d72232016-08-04 10:15:08 -0400187 vat_main_t *vam = &vat_main;
188 return ((i8 *) format (0, "%s%c", vam->current_file, 0));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700189}
190
Dave Barach72d72232016-08-04 10:15:08 -0400191static i8 *
192eval_current_line (macro_main_t * mm, i32 complain)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700193{
Dave Barach72d72232016-08-04 10:15:08 -0400194 vat_main_t *vam = &vat_main;
195 return ((i8 *) format (0, "%d%c", vam->input_line_number, 0));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700196}
197
198
Dave Barach72d72232016-08-04 10:15:08 -0400199int
200main (int argc, char **argv)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700201{
Dave Barach72d72232016-08-04 10:15:08 -0400202 vat_main_t *vam = &vat_main;
203 unformat_input_t _argv, *a = &_argv;
204 u8 **input_files = 0;
205 u8 *output_file = 0;
206 u8 *chroot_prefix;
207 u8 *this_input_file;
208 u8 interactive = 1;
209 u8 json_output = 0;
210 u8 *heap;
211 mheap_t *h;
212 int i;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700213
Dave Barach72d72232016-08-04 10:15:08 -0400214 clib_mem_init (0, 128 << 20);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700215
Dave Barach72d72232016-08-04 10:15:08 -0400216 heap = clib_mem_get_per_cpu_heap ();
217 h = mheap_header (heap);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700218
Dave Barach72d72232016-08-04 10:15:08 -0400219 /* make the main heap thread-safe */
220 h->flags |= MHEAP_FLAG_THREAD_SAFE;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700221
Dave Barach72d72232016-08-04 10:15:08 -0400222 clib_macro_init (&vam->macro_main);
223 clib_macro_add_builtin (&vam->macro_main, "current_file",
224 eval_current_file);
225 clib_macro_add_builtin (&vam->macro_main, "current_line",
226 eval_current_line);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700227
Dave Barach72d72232016-08-04 10:15:08 -0400228 init_error_string_table (vam);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700229
Dave Barach72d72232016-08-04 10:15:08 -0400230 unformat_init_command_line (a, argv);
231
232 while (unformat_check_input (a) != UNFORMAT_END_OF_INPUT)
233 {
234 if (unformat (a, "in %s", &this_input_file))
235 vec_add1 (input_files, this_input_file);
236 else if (unformat (a, "out %s", &output_file))
237 ;
238 else if (unformat (a, "script"))
239 interactive = 0;
240 else if (unformat (a, "json"))
241 json_output = 1;
242 else if (unformat (a, "plugin_path %s", (u8 *) & vat_plugin_path))
243 vec_add1 (vat_plugin_path, 0);
244 else if (unformat (a, "plugin_name_filter %s",
245 (u8 *) & vat_plugin_name_filter))
246 vec_add1 (vat_plugin_name_filter, 0);
247 else if (unformat (a, "chroot prefix %s", &chroot_prefix))
248 {
249 vl_set_memory_root_path ((char *) chroot_prefix);
250 }
251 else
252 {
253 fformat (stderr,
254 "%s: usage [in <f1> ... in <fn>] [out <fn>] [script] [json]\n");
255 exit (1);
256 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700257 }
258
Dave Barach72d72232016-08-04 10:15:08 -0400259 if (output_file)
260 vam->ofp = fopen ((char *) output_file, "w");
261 else
262 vam->ofp = stdout;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700263
Dave Barach72d72232016-08-04 10:15:08 -0400264 if (vam->ofp == NULL)
265 {
266 fformat (stderr, "Couldn't open output file %s\n",
267 output_file ? (char *) output_file : "stdout");
268 exit (1);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700269 }
270
Dave Barach72d72232016-08-04 10:15:08 -0400271 clib_time_init (&vam->clib_time);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700272
Dave Barach72d72232016-08-04 10:15:08 -0400273 vat_api_hookup (vam);
274 vat_plugin_api_reference ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700275
Dave Barach72d72232016-08-04 10:15:08 -0400276 if (connect_to_vpe ("vpp_api_test") < 0)
277 {
278 svm_region_exit ();
279 fformat (stderr, "Couldn't connect to vpe, exiting...\n");
280 exit (1);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700281 }
282
Dave Barach72d72232016-08-04 10:15:08 -0400283 vam->json_output = json_output;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700284
Dave Barach72d72232016-08-04 10:15:08 -0400285 if (!json_output)
286 {
287 api_sw_interface_dump (vam);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700288 }
289
Dave Barach72d72232016-08-04 10:15:08 -0400290 vec_validate (vam->inbuf, 4096);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700291
Dave Barach72d72232016-08-04 10:15:08 -0400292 vam->current_file = (u8 *) "plugin-init";
293 vat_plugin_init (vam);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700294
Dave Barach72d72232016-08-04 10:15:08 -0400295 for (i = 0; i < vec_len (input_files); i++)
296 {
297 vam->ifp = fopen ((char *) input_files[i], "r");
298 if (vam->ifp == NULL)
299 {
300 fformat (stderr, "Couldn't open input file %s\n", input_files[i]);
301 continue;
302 }
303 vam->current_file = input_files[i];
304 vam->input_line_number = 0;
305 do_one_file (vam);
306 fclose (vam->ifp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700307 }
308
Dave Barach72d72232016-08-04 10:15:08 -0400309 if (output_file)
310 fclose (vam->ofp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700311
Dave Barach72d72232016-08-04 10:15:08 -0400312 if (interactive)
313 {
314 vam->ifp = stdin;
315 vam->ofp = stdout;
316 vam->current_file = (u8 *) "interactive";
317 do_one_file (vam);
318 fclose (vam->ifp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700319 }
320
Dave Barach72d72232016-08-04 10:15:08 -0400321 vl_client_disconnect_from_vlib ();
322 exit (0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700323}
Dave Barach72d72232016-08-04 10:15:08 -0400324
325/*
326 * fd.io coding-style-patch-verification: ON
327 *
328 * Local Variables:
329 * eval: (c-set-style "gnu")
330 * End:
331 */