builtinurl: mark api as deprecated
[vpp.git] / src / plugins / igmp / igmp_cli.c
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2017 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17
18 #include <stdint.h>
19 #include <sys/ioctl.h>
20 #include <inttypes.h>
21
22 #include <vlib/vlib.h>
23 #include <vlib/unix/unix.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/fib/fib_entry.h>
26 #include <vnet/fib/fib_table.h>
27 #include <vnet/mfib/mfib_table.h>
28
29 #include <igmp/igmp.h>
30
31 static clib_error_t *
32 igmp_clear_interface_command_fn (vlib_main_t * vm, unformat_input_t * input,
33                                  vlib_cli_command_t * cmd)
34 {
35   unformat_input_t _line_input, *line_input = &_line_input;
36   clib_error_t *error = NULL;
37   vnet_main_t *vnm = vnet_get_main ();
38   u32 sw_if_index;
39
40   igmp_config_t *config;
41
42   if (!unformat_user (input, unformat_line_input, line_input))
43     {
44       error =
45         clib_error_return (0, "'help clear igmp' or 'clear igmp ?' for help");
46       return error;
47     }
48
49   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
50     {
51       if (unformat
52           (line_input, "int %U", unformat_vnet_sw_interface, vnm,
53            &sw_if_index));
54       else
55         {
56           error =
57             clib_error_return (0, "unknown input '%U'", format_unformat_error,
58                                line_input);
59           goto done;
60         }
61     }
62
63   config = igmp_config_lookup (sw_if_index);
64   if (config)
65     igmp_clear_config (config);
66
67 done:
68   unformat_free (line_input);
69   return error;
70 }
71
72 VLIB_CLI_COMMAND (igmp_clear_interface_command, static) = {
73   .path = "clear igmp",
74   .short_help = "clear igmp int <interface>",
75   .function = igmp_clear_interface_command_fn,
76 };
77
78 static clib_error_t *
79 igmp_listen_command_fn (vlib_main_t * vm, unformat_input_t * input,
80                         vlib_cli_command_t * cmd)
81 {
82   unformat_input_t _line_input, *line_input = &_line_input;
83   clib_error_t *error = NULL;
84   u8 enable = 1;
85   ip46_address_t saddr, *saddrs = NULL, gaddr;
86   vnet_main_t *vnm = vnet_get_main ();
87   u32 sw_if_index;
88   int rv;
89
90   if (!unformat_user (input, unformat_line_input, line_input))
91     {
92       error =
93         clib_error_return (0,
94                            "'help igmp listen' or 'igmp listen ?' for help");
95       return error;
96     }
97
98   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
99     {
100       if (unformat (line_input, "enable"))
101         enable = 1;
102       else if (unformat (line_input, "disable"))
103         enable = 0;
104       else
105         if (unformat
106             (line_input, "int %U", unformat_vnet_sw_interface, vnm,
107              &sw_if_index));
108       else
109         if (unformat (line_input, "saddr %U", unformat_ip46_address, &saddr))
110         vec_add1 (saddrs, saddr);
111       else
112         if (unformat (line_input, "gaddr %U", unformat_ip46_address, &gaddr));
113       else
114         {
115           error =
116             clib_error_return (0, "unknown input '%U'", format_unformat_error,
117                                line_input);
118           goto done;
119         }
120     }
121
122   if ((vnet_sw_interface_get_flags (vnm, sw_if_index)
123        && VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0)
124     {
125       error = clib_error_return (0, "Interface is down");
126       goto done;
127     }
128
129   rv = igmp_listen (vm, enable, sw_if_index, saddrs, &gaddr);
130
131   if (rv == -1)
132     {
133       if (enable)
134         error =
135           clib_error_return (0, "This igmp configuration already exists");
136       else
137         error =
138           clib_error_return (0, "This igmp configuration does not exist");
139     }
140   else if (rv == -2)
141     error =
142       clib_error_return (0,
143                          "Failed to add configuration, interface is in router mode");
144
145 done:
146   unformat_free (line_input);
147   vec_free (saddrs);
148   return error;
149 }
150
151 VLIB_CLI_COMMAND (igmp_listen_command, static) = {
152   .path = "igmp listen",
153   .short_help = "igmp listen [<enable|disable>] "
154                 "int <interface> saddr <ip4-address> gaddr <ip4-address>",
155   .function = igmp_listen_command_fn,
156 };
157
158 static clib_error_t *
159 igmp_enable_cli (vlib_main_t * vm,
160                  unformat_input_t * input, vlib_cli_command_t * cmd)
161 {
162   unformat_input_t _line_input, *line_input = &_line_input;
163   igmp_mode_t mode = IGMP_MODE_ROUTER;
164   vnet_main_t *vnm = vnet_get_main ();
165   clib_error_t *error = NULL;
166   u32 sw_if_index = ~0;
167   u8 enable = 1;
168   int rv;
169
170   if (!unformat_user (input, unformat_line_input, line_input))
171     return error;
172
173   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
174     {
175       if (unformat (line_input, "enable"))
176         enable = 1;
177       else if (unformat (line_input, "disable"))
178         enable = 0;
179       if (unformat (line_input, "host"))
180         mode = IGMP_MODE_HOST;
181       else if (unformat (line_input, "router"))
182         mode = IGMP_MODE_ROUTER;
183       else if (unformat (line_input, "%U",
184                          unformat_vnet_sw_interface, vnm, &sw_if_index));
185       else
186         {
187           error =
188             clib_error_return (0, "unknown input '%U'", format_unformat_error,
189                                line_input);
190           goto done;
191         }
192     }
193
194   if (~0 == sw_if_index)
195     {
196       error = clib_error_return (0, "interface must be specified");
197       goto done;
198     }
199
200   rv = igmp_enable_disable (sw_if_index, enable, mode);
201
202   if (0 != rv)
203     error = clib_error_return (0, "result: %d", rv);
204
205 done:
206   unformat_free (line_input);
207   return error;
208 }
209
210 VLIB_CLI_COMMAND (igmp_enable_command, static) = {
211   .path = "igmp",
212   .short_help = "igmp <enable|disable> <host|router> <interface>",
213   .function = igmp_enable_cli,
214 };
215
216 static clib_error_t *
217 igmp_proxy_device_add_del_command_fn (vlib_main_t * vm,
218                                       unformat_input_t * input,
219                                       vlib_cli_command_t * cmd)
220 {
221   unformat_input_t _line_input, *line_input = &_line_input;
222   vnet_main_t *vnm = vnet_get_main ();
223   clib_error_t *error = NULL;
224   u32 sw_if_index = ~0;
225   u32 vrf_id = ~0;
226   u8 add = 1;
227   int rv;
228
229   if (!unformat_user (input, unformat_line_input, line_input))
230     return error;
231
232   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
233     {
234       if (unformat (line_input, "add"))
235         add = 1;
236       else if (unformat (line_input, "del"))
237         add = 0;
238       else if (unformat (line_input, "vrf-id %u", &vrf_id))
239         ;
240       else if (unformat (line_input, "%U",
241                          unformat_vnet_sw_interface, vnm, &sw_if_index));
242       else
243         {
244           error =
245             clib_error_return (0, "unknown input '%U'", format_unformat_error,
246                                line_input);
247           goto done;
248         }
249     }
250
251   if (~0 == sw_if_index)
252     {
253       error = clib_error_return (0, "interface must be specified");
254       goto done;
255     }
256
257   if (~0 == vrf_id)
258     {
259       error = clib_error_return (0, "VRF must be specified");
260       goto done;
261     }
262
263   rv = igmp_proxy_device_add_del (vrf_id, sw_if_index, add);
264
265   if (0 != rv)
266     error = clib_error_return (0, "result: %d", rv);
267
268 done:
269   unformat_free (line_input);
270   return error;
271 }
272 VLIB_CLI_COMMAND (igmp_proxy_device_add_del_command, static) = {
273   .path = "igmp proxy-dev",
274   .short_help = "igmp proxy-dev <add|del> vrf-id <table-id> <interface>",
275   .function = igmp_proxy_device_add_del_command_fn,
276 };
277
278 static clib_error_t *
279 igmp_proxy_device_add_del_interface_command_fn (vlib_main_t * vm,
280                                                 unformat_input_t * input,
281                                                 vlib_cli_command_t * cmd)
282 {
283   unformat_input_t _line_input, *line_input = &_line_input;
284   vnet_main_t *vnm = vnet_get_main ();
285   clib_error_t *error = NULL;
286   u32 sw_if_index = ~0;
287   u32 vrf_id = ~0;
288   u8 add = 1;
289   int rv;
290
291   if (!unformat_user (input, unformat_line_input, line_input))
292     return error;
293
294   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
295     {
296       if (unformat (line_input, "add"))
297         add = 1;
298       else if (unformat (line_input, "del"))
299         add = 0;
300       else if (unformat (line_input, "vrf-id %u", &vrf_id))
301         ;
302       else if (unformat (line_input, "%U",
303                          unformat_vnet_sw_interface, vnm, &sw_if_index));
304       else
305         {
306           error =
307             clib_error_return (0, "unknown input '%U'", format_unformat_error,
308                                line_input);
309           goto done;
310         }
311     }
312
313   if (~0 == sw_if_index)
314     {
315       error = clib_error_return (0, "interface must be specified");
316       goto done;
317     }
318
319   if (~0 == vrf_id)
320     {
321       error = clib_error_return (0, "VRF must be specified");
322       goto done;
323     }
324
325   rv = igmp_proxy_device_add_del_interface (vrf_id, sw_if_index, add);
326
327   if (0 != rv)
328     error = clib_error_return (0, "result: %d", rv);
329
330 done:
331   unformat_free (line_input);
332   return error;
333 }
334 VLIB_CLI_COMMAND (igmp_proxy_device_add_del_interface_command, static) = {
335   .path = "igmp proxy-dev itf",
336   .short_help = "igmp proxy-dev itf <add|del> vrf-id <table-id> <interface>",
337   .function = igmp_proxy_device_add_del_interface_command_fn,
338 };
339
340 static clib_error_t *
341 igmp_show_command_fn (vlib_main_t * vm, unformat_input_t * input,
342                       vlib_cli_command_t * cmd)
343 {
344   clib_error_t *error = NULL;
345   igmp_main_t *im = &igmp_main;
346   igmp_config_t *config;
347
348   pool_foreach (config, im->configs)
349      {
350       vlib_cli_output (vm, "%U", format_igmp_config, config);
351     }
352
353   return error;
354 }
355
356 VLIB_CLI_COMMAND (igmp_show_command, static) = {
357   .path = "show igmp config",
358   .short_help = "show igmp config",
359   .function = igmp_show_command_fn,
360 };
361
362 static clib_error_t *
363 igmp_show_timers_command_fn (vlib_main_t * vm,
364                              unformat_input_t * input,
365                              vlib_cli_command_t * cmd)
366 {
367 #define _(n,f) vlib_cli_output (vm, "%s: %d", #f, igmp_timer_type_get(n));
368   foreach_igmp_timer_type
369 #undef _
370     return (NULL);
371 }
372
373 VLIB_CLI_COMMAND (igmp_show_timers_command, static) = {
374   .path = "show igmp timers",
375   .short_help = "show igmp timers",
376   .function = igmp_show_timers_command_fn,
377 };
378
379 static clib_error_t *
380 test_igmp_command_fn (vlib_main_t * vm,
381                       unformat_input_t * input, vlib_cli_command_t * cmd)
382 {
383   clib_error_t *error = NULL;
384   u32 value;
385
386   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
387     {
388       if (unformat (input, "query %d", &value))
389         igmp_timer_type_set (IGMP_TIMER_QUERY, value);
390       else if (unformat (input, "src %d", &value))
391         igmp_timer_type_set (IGMP_TIMER_SRC, value);
392       else if (unformat (input, "leave %d", &value))
393         igmp_timer_type_set (IGMP_TIMER_LEAVE, value);
394       else
395         error = clib_error_return (0, "query or src timers only");
396     }
397
398   return error;
399 }
400
401 VLIB_CLI_COMMAND (test_igmp_command, static) = {
402   .path = "test igmp timers",
403   .short_help = "Change the default values for IGMP timers - only sensible during unit tests",
404   .function = test_igmp_command_fn,
405 };
406
407
408 clib_error_t *
409 igmp_cli_init (vlib_main_t * vm)
410 {
411   return 0;
412 }
413
414 VLIB_INIT_FUNCTION (igmp_cli_init);
415
416 /*
417  * fd.io coding-style-patch-verification: ON
418  *
419  * Local Variables:
420  * eval: (c-set-style "gnu")
421  * End:
422  */