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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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 *------------------------------------------------------------------
19 #include <sys/ioctl.h>
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>
29 #include <igmp/igmp.h>
32 igmp_clear_interface_command_fn (vlib_main_t * vm, unformat_input_t * input,
33 vlib_cli_command_t * cmd)
35 unformat_input_t _line_input, *line_input = &_line_input;
36 clib_error_t *error = NULL;
37 vnet_main_t *vnm = vnet_get_main ();
40 igmp_config_t *config;
42 if (!unformat_user (input, unformat_line_input, line_input))
45 clib_error_return (0, "'help clear igmp' or 'clear igmp ?' for help");
49 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
52 (line_input, "int %U", unformat_vnet_sw_interface, vnm,
57 clib_error_return (0, "unknown input '%U'", format_unformat_error,
63 config = igmp_config_lookup (sw_if_index);
65 igmp_clear_config (config);
68 unformat_free (line_input);
72 VLIB_CLI_COMMAND (igmp_clear_interface_command, static) = {
74 .short_help = "clear igmp int <interface>",
75 .function = igmp_clear_interface_command_fn,
79 igmp_listen_command_fn (vlib_main_t * vm, unformat_input_t * input,
80 vlib_cli_command_t * cmd)
82 unformat_input_t _line_input, *line_input = &_line_input;
83 clib_error_t *error = NULL;
85 ip46_address_t saddr, *saddrs = NULL, gaddr;
86 vnet_main_t *vnm = vnet_get_main ();
90 if (!unformat_user (input, unformat_line_input, line_input))
94 "'help igmp listen' or 'igmp listen ?' for help");
98 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
100 if (unformat (line_input, "enable"))
102 else if (unformat (line_input, "disable"))
106 (line_input, "int %U", unformat_vnet_sw_interface, vnm,
109 if (unformat (line_input, "saddr %U", unformat_ip46_address, &saddr))
110 vec_add1 (saddrs, saddr);
112 if (unformat (line_input, "gaddr %U", unformat_ip46_address, &gaddr));
116 clib_error_return (0, "unknown input '%U'", format_unformat_error,
122 if ((vnet_sw_interface_get_flags (vnm, sw_if_index)
123 && VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0)
125 error = clib_error_return (0, "Interface is down");
129 rv = igmp_listen (vm, enable, sw_if_index, saddrs, &gaddr);
135 clib_error_return (0, "This igmp configuration already exists");
138 clib_error_return (0, "This igmp configuration does not exist");
142 clib_error_return (0,
143 "Failed to add configuration, interface is in router mode");
146 unformat_free (line_input);
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,
158 static clib_error_t *
159 igmp_enable_cli (vlib_main_t * vm,
160 unformat_input_t * input, vlib_cli_command_t * cmd)
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;
170 if (!unformat_user (input, unformat_line_input, line_input))
173 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
175 if (unformat (line_input, "enable"))
177 else if (unformat (line_input, "disable"))
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));
188 clib_error_return (0, "unknown input '%U'", format_unformat_error,
194 if (~0 == sw_if_index)
196 error = clib_error_return (0, "interface must be specified");
200 rv = igmp_enable_disable (sw_if_index, enable, mode);
203 error = clib_error_return (0, "result: %d", rv);
206 unformat_free (line_input);
210 VLIB_CLI_COMMAND (igmp_enable_command, static) = {
212 .short_help = "igmp <enable|disable> <host|router> <interface>",
213 .function = igmp_enable_cli,
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)
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;
229 if (!unformat_user (input, unformat_line_input, line_input))
232 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
234 if (unformat (line_input, "add"))
236 else if (unformat (line_input, "del"))
238 else if (unformat (line_input, "vrf-id %u", &vrf_id))
240 else if (unformat (line_input, "%U",
241 unformat_vnet_sw_interface, vnm, &sw_if_index));
245 clib_error_return (0, "unknown input '%U'", format_unformat_error,
251 if (~0 == sw_if_index)
253 error = clib_error_return (0, "interface must be specified");
259 error = clib_error_return (0, "VRF must be specified");
263 rv = igmp_proxy_device_add_del (vrf_id, sw_if_index, add);
266 error = clib_error_return (0, "result: %d", rv);
269 unformat_free (line_input);
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,
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)
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;
291 if (!unformat_user (input, unformat_line_input, line_input))
294 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
296 if (unformat (line_input, "add"))
298 else if (unformat (line_input, "del"))
300 else if (unformat (line_input, "vrf-id %u", &vrf_id))
302 else if (unformat (line_input, "%U",
303 unformat_vnet_sw_interface, vnm, &sw_if_index));
307 clib_error_return (0, "unknown input '%U'", format_unformat_error,
313 if (~0 == sw_if_index)
315 error = clib_error_return (0, "interface must be specified");
321 error = clib_error_return (0, "VRF must be specified");
325 rv = igmp_proxy_device_add_del_interface (vrf_id, sw_if_index, add);
328 error = clib_error_return (0, "result: %d", rv);
331 unformat_free (line_input);
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,
340 static clib_error_t *
341 igmp_show_command_fn (vlib_main_t * vm, unformat_input_t * input,
342 vlib_cli_command_t * cmd)
344 clib_error_t *error = NULL;
345 igmp_main_t *im = &igmp_main;
346 igmp_config_t *config;
348 pool_foreach (config, im->configs)
350 vlib_cli_output (vm, "%U", format_igmp_config, config);
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,
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)
367 #define _(n,f) vlib_cli_output (vm, "%s: %d", #f, igmp_timer_type_get(n));
368 foreach_igmp_timer_type
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,
379 static clib_error_t *
380 test_igmp_command_fn (vlib_main_t * vm,
381 unformat_input_t * input, vlib_cli_command_t * cmd)
383 clib_error_t *error = NULL;
386 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
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);
395 error = clib_error_return (0, "query or src timers only");
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,
409 igmp_cli_init (vlib_main_t * vm)
414 VLIB_INIT_FUNCTION (igmp_cli_init);
417 * fd.io coding-style-patch-verification: ON
420 * eval: (c-set-style "gnu")