snort: snort3 plugin and DAQ
[vpp.git] / src / plugins / snort / cli.c
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright(c) 2021 Cisco Systems, Inc.
3  */
4
5 #include <vlib/vlib.h>
6 #include <vnet/vnet.h>
7 #include <snort/snort.h>
8
9 static u8 *
10 format_snort_instance (u8 *s, va_list *args)
11 {
12   snort_instance_t *i = va_arg (*args, snort_instance_t *);
13   s = format (s, "%s [idx:%d sz:%d fd:%d]", i->name, i->index, i->shm_size,
14               i->shm_fd);
15
16   return s;
17 }
18
19 static clib_error_t *
20 snort_create_instance_command_fn (vlib_main_t *vm, unformat_input_t *input,
21                                   vlib_cli_command_t *cmd)
22 {
23   unformat_input_t _line_input, *line_input = &_line_input;
24   clib_error_t *err = 0;
25   u8 *name = 0;
26   u32 queue_size = 1024;
27   u8 drop_on_diconnect = 1;
28
29   /* Get a line of input. */
30   if (!unformat_user (input, unformat_line_input, line_input))
31     return 0;
32
33   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
34     {
35       if (unformat (line_input, "queue-size %u", &queue_size))
36         ;
37       else if (unformat (line_input, "on-disconnect drop"))
38         drop_on_diconnect = 1;
39       else if (unformat (line_input, "on-disconnect pass"))
40         drop_on_diconnect = 0;
41       else if (unformat (line_input, "name %s", &name))
42         ;
43       else
44         {
45           err = clib_error_return (0, "unknown input `%U'",
46                                    format_unformat_error, input);
47           goto done;
48         }
49     }
50
51   if (!is_pow2 (queue_size))
52     {
53       err = clib_error_return (0, "Queue size must be a power of two");
54       goto done;
55     }
56
57   if (!name)
58     {
59       err = clib_error_return (0, "please specify instance name");
60       goto done;
61     }
62
63   err = snort_instance_create (vm, (char *) name, min_log2 (queue_size),
64                                drop_on_diconnect);
65
66 done:
67   vec_free (name);
68   unformat_free (line_input);
69   return err;
70 }
71
72 VLIB_CLI_COMMAND (snort_create_instance_command, static) = {
73   .path = "snort create-instance",
74   .short_help = "snort create-instaince name <name> [queue-size <size>] "
75                 "[on-disconnect drop|pass]",
76   .function = snort_create_instance_command_fn,
77 };
78
79 static clib_error_t *
80 snort_attach_command_fn (vlib_main_t *vm, unformat_input_t *input,
81                          vlib_cli_command_t *cmd)
82 {
83   unformat_input_t _line_input, *line_input = &_line_input;
84   vnet_main_t *vnm = vnet_get_main ();
85   clib_error_t *err = 0;
86   u8 *name = 0;
87   u32 sw_if_index = ~0;
88
89   /* Get a line of input. */
90   if (!unformat_user (input, unformat_line_input, line_input))
91     return 0;
92
93   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
94     {
95       if (unformat (line_input, "interface %U", unformat_vnet_sw_interface,
96                     vnm, &sw_if_index))
97         ;
98       else if (unformat (line_input, "instance %s", &name))
99         ;
100       else
101         {
102           err = clib_error_return (0, "unknown input `%U'",
103                                    format_unformat_error, input);
104           goto done;
105         }
106     }
107
108   if (sw_if_index == ~0)
109     {
110       err = clib_error_return (0, "please specify interface");
111       goto done;
112     }
113
114   if (!name)
115     {
116       err = clib_error_return (0, "please specify instance name");
117       goto done;
118     }
119
120   err = snort_interface_enable_disable (vm, (char *) name, sw_if_index, 1);
121
122 done:
123   vec_free (name);
124   unformat_free (line_input);
125   return err;
126 }
127
128 VLIB_CLI_COMMAND (snort_attach_command, static) = {
129   .path = "snort attach",
130   .short_help = "snort attach instance <name> interface <if-name>",
131   .function = snort_attach_command_fn,
132 };
133
134 static clib_error_t *
135 snort_detach_command_fn (vlib_main_t *vm, unformat_input_t *input,
136                          vlib_cli_command_t *cmd)
137 {
138   unformat_input_t _line_input, *line_input = &_line_input;
139   vnet_main_t *vnm = vnet_get_main ();
140   clib_error_t *err = 0;
141   u32 sw_if_index = ~0;
142
143   /* Get a line of input. */
144   if (!unformat_user (input, unformat_line_input, line_input))
145     return 0;
146
147   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
148     {
149       if (unformat (line_input, "interface %U", unformat_vnet_sw_interface,
150                     vnm, &sw_if_index))
151         ;
152       else
153         {
154           err = clib_error_return (0, "unknown input `%U'",
155                                    format_unformat_error, input);
156           goto done;
157         }
158     }
159
160   if (sw_if_index == ~0)
161     {
162       err = clib_error_return (0, "please specify interface");
163       goto done;
164     }
165
166   err = snort_interface_enable_disable (vm, 0, sw_if_index, 0);
167
168 done:
169   unformat_free (line_input);
170   return err;
171 }
172
173 VLIB_CLI_COMMAND (snort_detach_command, static) = {
174   .path = "snort detach",
175   .short_help = "snort detach interface <if-name>",
176   .function = snort_detach_command_fn,
177 };
178
179 static clib_error_t *
180 snort_show_instances_command_fn (vlib_main_t *vm, unformat_input_t *input,
181                                  vlib_cli_command_t *cmd)
182 {
183   snort_main_t *sm = &snort_main;
184   snort_instance_t *si;
185
186   pool_foreach (si, sm->instances)
187     vlib_cli_output (vm, "%U", format_snort_instance, si);
188
189   return 0;
190 }
191
192 VLIB_CLI_COMMAND (snort_show_instances_command, static) = {
193   .path = "show snort instances",
194   .short_help = "show snort instances",
195   .function = snort_show_instances_command_fn,
196 };
197
198 static clib_error_t *
199 snort_show_interfaces_command_fn (vlib_main_t *vm, unformat_input_t *input,
200                                   vlib_cli_command_t *cmd)
201 {
202   snort_main_t *sm = &snort_main;
203   vnet_main_t *vnm = vnet_get_main ();
204   snort_instance_t *si;
205   u32 *index;
206
207   vlib_cli_output (vm, "interface\tsnort instance");
208   vec_foreach (index, sm->instance_by_sw_if_index)
209     {
210       if (index[0] != ~0)
211         {
212           si = vec_elt_at_index (sm->instances, index[0]);
213           vlib_cli_output (vm, "%U:\t%s", format_vnet_sw_if_index_name, vnm,
214                            index - sm->instance_by_sw_if_index, si->name);
215         }
216     }
217   return 0;
218 }
219
220 VLIB_CLI_COMMAND (snort_show_interfaces_command, static) = {
221   .path = "show snort interfaces",
222   .short_help = "show snort interfaces",
223   .function = snort_show_interfaces_command_fn,
224 };
225
226 static clib_error_t *
227 snort_show_clients_command_fn (vlib_main_t *vm, unformat_input_t *input,
228                                vlib_cli_command_t *cmd)
229 {
230   snort_main_t *sm = &snort_main;
231   vlib_cli_output (vm, "number of clients: %d", pool_elts (sm->clients));
232   return 0;
233 }
234
235 VLIB_CLI_COMMAND (snort_show_clients_command, static) = {
236   .path = "show snort clients",
237   .short_help = "show snort clients",
238   .function = snort_show_clients_command_fn,
239 };
240
241 static clib_error_t *
242 snort_mode_polling_command_fn (vlib_main_t *vm, unformat_input_t *input,
243                                vlib_cli_command_t *cmd)
244 {
245   return snort_set_node_mode (vm, VLIB_NODE_STATE_POLLING);
246 }
247
248 static clib_error_t *
249 snort_mode_interrupt_command_fn (vlib_main_t *vm, unformat_input_t *input,
250                                  vlib_cli_command_t *cmd)
251 {
252   return snort_set_node_mode (vm, VLIB_NODE_STATE_INTERRUPT);
253 }
254
255 VLIB_CLI_COMMAND (snort_mode_polling_command, static) = {
256   .path = "snort mode polling",
257   .short_help = "snort mode polling|interrupt",
258   .function = snort_mode_polling_command_fn,
259 };
260
261 VLIB_CLI_COMMAND (snort_mode_interrupt_command, static) = {
262   .path = "snort mode interrupt",
263   .short_help = "snort mode polling|interrupt",
264   .function = snort_mode_interrupt_command_fn,
265 };
266
267 static clib_error_t *
268 snort_show_mode_command_fn (vlib_main_t *vm, unformat_input_t *input,
269                             vlib_cli_command_t *cmd)
270 {
271   snort_main_t *sm = &snort_main;
272   char *mode =
273     sm->input_mode == VLIB_NODE_STATE_POLLING ? "polling" : "interrupt";
274   vlib_cli_output (vm, "input mode: %s", mode);
275   return 0;
276 }
277
278 VLIB_CLI_COMMAND (snort_show_mode_command, static) = {
279   .path = "show snort mode",
280   .short_help = "show snort mode",
281   .function = snort_show_mode_command_fn,
282 };