17b867a8eSJakub Grajciar/*
27b867a8eSJakub Grajciar *------------------------------------------------------------------
37b867a8eSJakub Grajciar * Copyright (c) 2017 Cisco and/or its affiliates.
47b867a8eSJakub Grajciar * Licensed under the Apache License, Version 2.0 (the "License");
57b867a8eSJakub Grajciar * you may not use this file except in compliance with the License.
67b867a8eSJakub Grajciar * You may obtain a copy of the License at:
77b867a8eSJakub Grajciar *
87b867a8eSJakub Grajciar *     http://www.apache.org/licenses/LICENSE-2.0
97b867a8eSJakub Grajciar *
107b867a8eSJakub Grajciar * Unless required by applicable law or agreed to in writing, software
117b867a8eSJakub Grajciar * distributed under the License is distributed on an "AS IS" BASIS,
127b867a8eSJakub Grajciar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137b867a8eSJakub Grajciar * See the License for the specific language governing permissions and
147b867a8eSJakub Grajciar * limitations under the License.
157b867a8eSJakub Grajciar *------------------------------------------------------------------
167b867a8eSJakub Grajciar */
177b867a8eSJakub Grajciar
187b867a8eSJakub Grajciar#include <stdint.h>
197b867a8eSJakub Grajciar#include <sys/ioctl.h>
207b867a8eSJakub Grajciar#include <inttypes.h>
217b867a8eSJakub Grajciar
227b867a8eSJakub Grajciar#include <vlib/vlib.h>
237b867a8eSJakub Grajciar#include <vlib/unix/unix.h>
247b867a8eSJakub Grajciar#include <vnet/ip/ip.h>
257b867a8eSJakub Grajciar#include <vnet/fib/fib_entry.h>
267b867a8eSJakub Grajciar#include <vnet/fib/fib_table.h>
277b867a8eSJakub Grajciar#include <vnet/mfib/mfib_table.h>
287b867a8eSJakub Grajciar
297b867a8eSJakub Grajciar#include <igmp/igmp.h>
307b867a8eSJakub Grajciar
317b867a8eSJakub Grajciarstatic clib_error_t *
327b867a8eSJakub Grajciarigmp_clear_interface_command_fn (vlib_main_t * vm, unformat_input_t * input,
337b867a8eSJakub Grajciar				 vlib_cli_command_t * cmd)
347b867a8eSJakub Grajciar{
357b867a8eSJakub Grajciar  unformat_input_t _line_input, *line_input = &_line_input;
367b867a8eSJakub Grajciar  clib_error_t *error = NULL;
377b867a8eSJakub Grajciar  vnet_main_t *vnm = vnet_get_main ();
387b867a8eSJakub Grajciar  u32 sw_if_index;
397b867a8eSJakub Grajciar
407b867a8eSJakub Grajciar  igmp_config_t *config;
417b867a8eSJakub Grajciar
427b867a8eSJakub Grajciar  if (!unformat_user (input, unformat_line_input, line_input))
437b867a8eSJakub Grajciar    {
447b867a8eSJakub Grajciar      error =
457b867a8eSJakub Grajciar	clib_error_return (0, "'help clear igmp' or 'clear igmp ?' for help");
467b867a8eSJakub Grajciar      return error;
477b867a8eSJakub Grajciar    }
487b867a8eSJakub Grajciar
497b867a8eSJakub Grajciar  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
507b867a8eSJakub Grajciar    {
517b867a8eSJakub Grajciar      if (unformat
527b867a8eSJakub Grajciar	  (line_input, "int %U", unformat_vnet_sw_interface, vnm,
537b867a8eSJakub Grajciar	   &sw_if_index));
547b867a8eSJakub Grajciar      else
557b867a8eSJakub Grajciar	{
567b867a8eSJakub Grajciar	  error =
577b867a8eSJakub Grajciar	    clib_error_return (0, "unknown input '%U'", format_unformat_error,
587b867a8eSJakub Grajciar			       line_input);
597b867a8eSJakub Grajciar	  goto done;
607b867a8eSJakub Grajciar	}
617b867a8eSJakub Grajciar    }
627b867a8eSJakub Grajciar
63947ea622SNeale Ranns  config = igmp_config_lookup (sw_if_index);
647b867a8eSJakub Grajciar  if (config)
657b867a8eSJakub Grajciar    igmp_clear_config (config);
667b867a8eSJakub Grajciar
677b867a8eSJakub Grajciardone:
687b867a8eSJakub Grajciar  unformat_free (line_input);
697b867a8eSJakub Grajciar  return error;
707b867a8eSJakub Grajciar}
717b867a8eSJakub Grajciar
727b867a8eSJakub Grajciar/* *INDENT-OFF* */
737b867a8eSJakub GrajciarVLIB_CLI_COMMAND (igmp_clear_interface_command, static) = {
747b867a8eSJakub Grajciar  .path = "clear igmp",
757b867a8eSJakub Grajciar  .short_help = "clear igmp int <interface>",
767b867a8eSJakub Grajciar  .function = igmp_clear_interface_command_fn,
777b867a8eSJakub Grajciar};
787b867a8eSJakub Grajciar/* *INDENT-ON* */
797b867a8eSJakub Grajciar
807b867a8eSJakub Grajciarstatic clib_error_t *
817b867a8eSJakub Grajciarigmp_listen_command_fn (vlib_main_t * vm, unformat_input_t * input,
827b867a8eSJakub Grajciar			vlib_cli_command_t * cmd)
837b867a8eSJakub Grajciar{
847b867a8eSJakub Grajciar  unformat_input_t _line_input, *line_input = &_line_input;
857b867a8eSJakub Grajciar  clib_error_t *error = NULL;
867b867a8eSJakub Grajciar  u8 enable = 1;
874555bb4fSNeale Ranns  ip46_address_t saddr, *saddrs = NULL, gaddr;
887b867a8eSJakub Grajciar  vnet_main_t *vnm = vnet_get_main ();
897b867a8eSJakub Grajciar  u32 sw_if_index;
907b867a8eSJakub Grajciar  int rv;
917b867a8eSJakub Grajciar
927b867a8eSJakub Grajciar  if (!unformat_user (input, unformat_line_input, line_input))
937b867a8eSJakub Grajciar    {
947b867a8eSJakub Grajciar      error =
957b867a8eSJakub Grajciar	clib_error_return (0,
967b867a8eSJakub Grajciar			   "'help igmp listen' or 'igmp listen ?' for help");
977b867a8eSJakub Grajciar      return error;
987b867a8eSJakub Grajciar    }
997b867a8eSJakub Grajciar
1007b867a8eSJakub Grajciar  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1017b867a8eSJakub Grajciar    {
1027b867a8eSJakub Grajciar      if (unformat (line_input, "enable"))
1037b867a8eSJakub Grajciar	enable = 1;
1047b867a8eSJakub Grajciar      else if (unformat (line_input, "disable"))
1057b867a8eSJakub Grajciar	enable = 0;
1067b867a8eSJakub Grajciar      else
1077b867a8eSJakub Grajciar	if (unformat
1087b867a8eSJakub Grajciar	    (line_input, "int %U", unformat_vnet_sw_interface, vnm,
1097b867a8eSJakub Grajciar	     &sw_if_index));
1107b867a8eSJakub Grajciar      else
1114555bb4fSNeale Ranns	if (unformat (line_input, "saddr %U", unformat_ip46_address, &saddr))
1124555bb4fSNeale Ranns	vec_add1 (saddrs, saddr);
1137b867a8eSJakub Grajciar      else
1147b867a8eSJakub Grajciar	if (unformat (line_input, "gaddr %U", unformat_ip46_address, &gaddr));
1157b867a8eSJakub Grajciar      else
1167b867a8eSJakub Grajciar	{
1177b867a8eSJakub Grajciar	  error =
1187b867a8eSJakub Grajciar	    clib_error_return (0, "unknown input '%U'", format_unformat_error,
1197b867a8eSJakub Grajciar			       line_input);
1207b867a8eSJakub Grajciar	  goto done;
1217b867a8eSJakub Grajciar	}
1227b867a8eSJakub Grajciar    }
1237b867a8eSJakub Grajciar
1247b867a8eSJakub Grajciar  if ((vnet_sw_interface_get_flags (vnm, sw_if_index)
1257b867a8eSJakub Grajciar       && VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0)
1267b867a8eSJakub Grajciar    {
1277b867a8eSJakub Grajciar      error = clib_error_return (0, "Interface is down");
1287b867a8eSJakub Grajciar      goto done;
1297b867a8eSJakub Grajciar    }
1307b867a8eSJakub Grajciar
1314555bb4fSNeale Ranns  rv = igmp_listen (vm, enable, sw_if_index, saddrs, &gaddr);
132947ea622SNeale Ranns
1337b867a8eSJakub Grajciar  if (rv == -1)
1347b867a8eSJakub Grajciar    {
1357b867a8eSJakub Grajciar      if (enable)
1367b867a8eSJakub Grajciar	error =
1377b867a8eSJakub Grajciar	  clib_error_return (0, "This igmp configuration already exists");
1387b867a8eSJakub Grajciar      else
1397b867a8eSJakub Grajciar	error =
140bdc0e6b7SPaul Vinciguerra	  clib_error_return (0, "This igmp configuration does not exist");
1417b867a8eSJakub Grajciar    }
1427b867a8eSJakub Grajciar  else if (rv == -2)
1437b867a8eSJakub Grajciar    error =
1447b867a8eSJakub Grajciar      clib_error_return (0,
1457b867a8eSJakub Grajciar			 "Failed to add configuration, interface is in router mode");
1467b867a8eSJakub Grajciar
1477b867a8eSJakub Grajciardone:
1487b867a8eSJakub Grajciar  unformat_free (line_input);
1494555bb4fSNeale Ranns  vec_free (saddrs);
1507b867a8eSJakub Grajciar  return error;
1517b867a8eSJakub Grajciar}
1527b867a8eSJakub Grajciar
1537b867a8eSJakub Grajciar/* *INDENT-OFF* */
1547b867a8eSJakub GrajciarVLIB_CLI_COMMAND (igmp_listen_command, static) = {
1557b867a8eSJakub Grajciar  .path = "igmp listen",
1567b867a8eSJakub Grajciar  .short_help = "igmp listen [<enable|disable>] "
1577b867a8eSJakub Grajciar                "int <interface> saddr <ip4-address> gaddr <ip4-address>",
1587b867a8eSJakub Grajciar  .function = igmp_listen_command_fn,
1597b867a8eSJakub Grajciar};
1607b867a8eSJakub Grajciar/* *INDENT-ON* */
1617b867a8eSJakub Grajciar
162fe0a2c5aSNeale Rannsstatic clib_error_t *
163fe0a2c5aSNeale Rannsigmp_enable_cli (vlib_main_t * vm,
164fe0a2c5aSNeale Ranns		 unformat_input_t * input, vlib_cli_command_t * cmd)
165fe0a2c5aSNeale Ranns{
166fe0a2c5aSNeale Ranns  unformat_input_t _line_input, *line_input = &_line_input;
167fe0a2c5aSNeale Ranns  igmp_mode_t mode = IGMP_MODE_ROUTER;
168fe0a2c5aSNeale Ranns  vnet_main_t *vnm = vnet_get_main ();
169fe0a2c5aSNeale Ranns  clib_error_t *error = NULL;
170fe0a2c5aSNeale Ranns  u32 sw_if_index = ~0;
171fe0a2c5aSNeale Ranns  u8 enable = 1;
172fe0a2c5aSNeale Ranns  int rv;
173fe0a2c5aSNeale Ranns
174fe0a2c5aSNeale Ranns  if (!unformat_user (input, unformat_line_input, line_input))
175fe0a2c5aSNeale Ranns    return error;
176fe0a2c5aSNeale Ranns
177fe0a2c5aSNeale Ranns  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
178fe0a2c5aSNeale Ranns    {
179fe0a2c5aSNeale Ranns      if (unformat (line_input, "enable"))
180fe0a2c5aSNeale Ranns	enable = 1;
181fe0a2c5aSNeale Ranns      else if (unformat (line_input, "disable"))
182fe0a2c5aSNeale Ranns	enable = 0;
183fe0a2c5aSNeale Ranns      if (unformat (line_input, "host"))
184fe0a2c5aSNeale Ranns	mode = IGMP_MODE_HOST;
185fe0a2c5aSNeale Ranns      else if (unformat (line_input, "router"))
186fe0a2c5aSNeale Ranns	mode = IGMP_MODE_ROUTER;
187fe0a2c5aSNeale Ranns      else if (unformat (line_input, "%U",
188fe0a2c5aSNeale Ranns			 unformat_vnet_sw_interface, vnm, &sw_if_index));
189fe0a2c5aSNeale Ranns      else
190fe0a2c5aSNeale Ranns	{
191fe0a2c5aSNeale Ranns	  error =
192fe0a2c5aSNeale Ranns	    clib_error_return (0, "unknown input '%U'", format_unformat_error,
193fe0a2c5aSNeale Ranns			       line_input);
194fe0a2c5aSNeale Ranns	  goto done;
195fe0a2c5aSNeale Ranns	}
196fe0a2c5aSNeale Ranns    }
197fe0a2c5aSNeale Ranns
198fe0a2c5aSNeale Ranns  if (~0 == sw_if_index)
199fe0a2c5aSNeale Ranns    {
200fe0a2c5aSNeale Ranns      error = clib_error_return (0, "interface must be specified");
201fe0a2c5aSNeale Ranns      goto done;
202fe0a2c5aSNeale Ranns    }
203fe0a2c5aSNeale Ranns
204fe0a2c5aSNeale Ranns  rv = igmp_enable_disable (sw_if_index, enable, mode);
205fe0a2c5aSNeale Ranns
206fe0a2c5aSNeale Ranns  if (0 != rv)
207fe0a2c5aSNeale Ranns    error = clib_error_return (0, "result: %d", rv);
208fe0a2c5aSNeale Ranns
209fe0a2c5aSNeale Rannsdone:
210fe0a2c5aSNeale Ranns  unformat_free (line_input);
211fe0a2c5aSNeale Ranns  return error;
212fe0a2c5aSNeale Ranns}
213fe0a2c5aSNeale Ranns
214fe0a2c5aSNeale Ranns/* *INDENT-OFF* */
215fe0a2c5aSNeale RannsVLIB_CLI_COMMAND (igmp_enable_command, static) = {
216fe0a2c5aSNeale Ranns  .path = "igmp",
217fe0a2c5aSNeale Ranns  .short_help = "igmp <enable|disable> <host|router> <interface>",
218fe0a2c5aSNeale Ranns  .function = igmp_enable_cli,
219fe0a2c5aSNeale Ranns};
220fe0a2c5aSNeale Ranns/* *INDENT-ON* */
221fe0a2c5aSNeale Ranns
22297748caeSJakub Grajciarstatic clib_error_t *
22397748caeSJakub Grajciarigmp_proxy_device_add_del_command_fn (vlib_main_t * vm,
22497748caeSJakub Grajciar				      unformat_input_t * input,
22597748caeSJakub Grajciar				      vlib_cli_command_t * cmd)
22697748caeSJakub Grajciar{
22797748caeSJakub Grajciar  unformat_input_t _line_input, *line_input = &_line_input;
22897748caeSJakub Grajciar  vnet_main_t *vnm = vnet_get_main ();
22997748caeSJakub Grajciar  clib_error_t *error = NULL;
23097748caeSJakub Grajciar  u32 sw_if_index = ~0;
23197748caeSJakub Grajciar  u32 vrf_id = ~0;
23297748caeSJakub Grajciar  u8 add = 1;
23397748caeSJakub Grajciar  int rv;
23497748caeSJakub Grajciar
23597748caeSJakub Grajciar  if (!unformat_user (input, unformat_line_input, line_input))
23697748caeSJakub Grajciar    return error;
23797748caeSJakub Grajciar
23897748caeSJakub Grajciar  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23997748caeSJakub Grajciar    {
24097748caeSJakub Grajciar      if (unformat (line_input, "add"))
24197748caeSJakub Grajciar	add = 1;
24297748caeSJakub Grajciar      else if (unformat (line_input, "del"))
24397748caeSJakub Grajciar	add = 0;
24497748caeSJakub Grajciar      else if (unformat (line_input, "vrf-id %u", &vrf_id))
24597748caeSJakub Grajciar	;
24697748caeSJakub Grajciar      else if (unformat (line_input, "%U",
24797748caeSJakub Grajciar			 unformat_vnet_sw_interface, vnm, &sw_if_index));
24897748caeSJakub Grajciar      else
24997748caeSJakub Grajciar	{
25097748caeSJakub Grajciar	  error =
25197748caeSJakub Grajciar	    clib_error_return (0, "unknown input '%U'", format_unformat_error,
25297748caeSJakub Grajciar			       line_input);
25397748caeSJakub Grajciar	  goto done;
25497748caeSJakub Grajciar	}
25597748caeSJakub Grajciar    }
25697748caeSJakub Grajciar
25797748caeSJakub Grajciar  if (~0 == sw_if_index)
25897748caeSJakub Grajciar    {
25997748caeSJakub Grajciar      error = clib_error_return (0, "interface must be specified");
26097748caeSJakub Grajciar      goto done;
26197748caeSJakub Grajciar    }
26297748caeSJakub Grajciar
26397748caeSJakub Grajciar  if (~0 == vrf_id)
26497748caeSJakub Grajciar    {
26597748caeSJakub Grajciar      error = clib_error_return (0, "VRF must be specified");
26697748caeSJakub Grajciar      goto done;
26797748caeSJakub Grajciar    }
26897748caeSJakub Grajciar
26997748caeSJakub Grajciar  rv = igmp_proxy_device_add_del (vrf_id, sw_if_index, add);
27097748caeSJakub Grajciar
27197748caeSJakub Grajciar  if (0 != rv)
27297748caeSJakub Grajciar    error = clib_error_return (0, "result: %d", rv);
27397748caeSJakub Grajciar
27497748caeSJakub Grajciardone:
27597748caeSJakub Grajciar  unformat_free (line_input);
27697748caeSJakub Grajciar  return error;
27797748caeSJakub Grajciar}
27897748caeSJakub Grajciar/* *INDENT-OFF* */
27997748caeSJakub GrajciarVLIB_CLI_COMMAND (igmp_proxy_device_add_del_command, static) = {
28097748caeSJakub Grajciar  .path = "igmp proxy-dev",
28197748caeSJakub Grajciar  .short_help = "igmp proxy-dev <add|del> vrf-id <table-id> <interface>",
28297748caeSJakub Grajciar  .function = igmp_proxy_device_add_del_command_fn,
28397748caeSJakub Grajciar};
28497748caeSJakub Grajciar/* *INDENT-ON* */
28597748caeSJakub Grajciar
28697748caeSJakub Grajciarstatic clib_error_t *
28797748caeSJakub Grajciarigmp_proxy_device_add_del_interface_command_fn (vlib_main_t * vm,
28897748caeSJakub Grajciar						unformat_input_t * input,
28997748caeSJakub Grajciar						vlib_cli_command_t * cmd)
29097748caeSJakub Grajciar{
29197748caeSJakub Grajciar  unformat_input_t _line_input, *line_input = &_line_input;
29297748caeSJakub Grajciar  vnet_main_t *vnm = vnet_get_main ();
29397748caeSJakub Grajciar  clib_error_t *error = NULL;
29497748caeSJakub Grajciar  u32 sw_if_index = ~0;
29597748caeSJakub Grajciar  u32 vrf_id = ~0;
29697748caeSJakub Grajciar  u8 add = 1;
29797748caeSJakub Grajciar  int rv;
29897748caeSJakub Grajciar
29997748caeSJakub Grajciar  if (!unformat_user (input, unformat_line_input, line_input))
30097748caeSJakub Grajciar    return error;
30197748caeSJakub Grajciar
30297748caeSJakub Grajciar  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
30397748caeSJakub Grajciar    {
30497748caeSJakub Grajciar      if (unformat (line_input, "add"))
30597748caeSJakub Grajciar	add = 1;
30697748caeSJakub Grajciar      else if (unformat (line_input, "del"))
30797748caeSJakub Grajciar	add = 0;
30897748caeSJakub Grajciar      else if (unformat (line_input, "vrf-id %u", &vrf_id))
30997748caeSJakub Grajciar	;
31097748caeSJakub Grajciar      else if (unformat (line_input, "%U",
31197748caeSJakub Grajciar			 unformat_vnet_sw_interface, vnm, &sw_if_index));
31297748caeSJakub Grajciar      else
31397748caeSJakub Grajciar	{
31497748caeSJakub Grajciar	  error =
31597748caeSJakub Grajciar	    clib_error_return (0, "unknown input '%U'", format_unformat_error,
31697748caeSJakub Grajciar			       line_input);
31797748caeSJakub Grajciar	  goto done;
31897748caeSJakub Grajciar	}
31997748caeSJakub Grajciar    }
32097748caeSJakub Grajciar
32197748caeSJakub Grajciar  if (~0 == sw_if_index)
32297748caeSJakub Grajciar    {
32397748caeSJakub Grajciar      error = clib_error_return (0, "interface must be specified");
32497748caeSJakub Grajciar      goto done;
32597748caeSJakub Grajciar    }
32697748caeSJakub Grajciar
32797748caeSJakub Grajciar  if (~0 == vrf_id)
32897748caeSJakub Grajciar    {
32997748caeSJakub Grajciar      error = clib_error_return (0, "VRF must be specified");
33097748caeSJakub Grajciar      goto done;
33197748caeSJakub Grajciar    }
33297748caeSJakub Grajciar
33397748caeSJakub Grajciar  rv = igmp_proxy_device_add_del_interface (vrf_id, sw_if_index, add);
33497748caeSJakub Grajciar
33597748caeSJakub Grajciar  if (0 != rv)
33697748caeSJakub Grajciar    error = clib_error_return (0, "result: %d", rv);
33797748caeSJakub Grajciar
33897748caeSJakub Grajciardone:
33997748caeSJakub Grajciar  unformat_free (line_input);
34097748caeSJakub Grajciar  return error;
34197748caeSJakub Grajciar}
34297748caeSJakub Grajciar/* *INDENT-OFF* */
34397748caeSJakub GrajciarVLIB_CLI_COMMAND (igmp_proxy_device_add_del_interface_command, static) = {
34497748caeSJakub Grajciar  .path = "igmp proxy-dev itf",
34597748caeSJakub Grajciar  .short_help = "igmp proxy-dev itf <add|del> vrf-id <table-id> <interface>",
34697748caeSJakub Grajciar  .function = igmp_proxy_device_add_del_interface_command_fn,
34797748caeSJakub Grajciar};
34897748caeSJakub Grajciar/* *INDENT-ON* */
34997748caeSJakub Grajciar
3507b867a8eSJakub Grajciarstatic clib_error_t *
3517b867a8eSJakub Grajciarigmp_show_command_fn (vlib_main_t * vm, unformat_input_t * input,
3527b867a8eSJakub Grajciar		      vlib_cli_command_t * cmd)
3537b867a8eSJakub Grajciar{
3547b867a8eSJakub Grajciar  clib_error_t *error = NULL;
3557b867a8eSJakub Grajciar  igmp_main_t *im = &igmp_main;
3567b867a8eSJakub Grajciar  igmp_config_t *config;
3577b867a8eSJakub Grajciar
3587b867a8eSJakub Grajciar  /* *INDENT-OFF* */
359947ea622SNeale Ranns  pool_foreach (config, im->configs,
360947ea622SNeale Ranns    ({
361e82eb635SNeale Ranns      vlib_cli_output (vm, "%U", format_igmp_config, config);
3627b867a8eSJakub Grajciar    }));
3637b867a8eSJakub Grajciar  /* *INDENT-ON* */
3647b867a8eSJakub Grajciar
3657b867a8eSJakub Grajciar  return error;
3667b867a8eSJakub Grajciar}
3677b867a8eSJakub Grajciar
3687b867a8eSJakub Grajciar/* *INDENT-OFF* */
3697b867a8eSJakub GrajciarVLIB_CLI_COMMAND (igmp_show_command, static) = {
3707b867a8eSJakub Grajciar  .path = "show igmp config",
3717b867a8eSJakub Grajciar  .short_help = "show igmp config",
3727b867a8eSJakub Grajciar  .function = igmp_show_command_fn,
3737b867a8eSJakub Grajciar};
3747b867a8eSJakub Grajciar/* *INDENT-ON* */
3757b867a8eSJakub Grajciar
376947ea622SNeale Rannsstatic clib_error_t *
377947ea622SNeale Rannsigmp_show_timers_command_fn (vlib_main_t * vm,
378947ea622SNeale Ranns			     unformat_input_t * input,
379947ea622SNeale Ranns			     vlib_cli_command_t * cmd)
380947ea622SNeale Ranns{
381947ea622SNeale Ranns#define _(n,f) vlib_cli_output (vm, "%s: %d", #f, igmp_timer_type_get(n));
382947ea622SNeale Ranns  foreach_igmp_timer_type
383947ea622SNeale Ranns#undef _
384947ea622SNeale Ranns    return (NULL);
385947ea622SNeale Ranns}
386947ea622SNeale Ranns
387947ea622SNeale Ranns/* *INDENT-OFF* */
388947ea622SNeale RannsVLIB_CLI_COMMAND (igmp_show_timers_command, static) = {
389947ea622SNeale Ranns  .path = "show igmp timers",
390947ea622SNeale Ranns  .short_help = "show igmp timers",
391947ea622SNeale Ranns  .function = igmp_show_timers_command_fn,
392947ea622SNeale Ranns};
393947ea622SNeale Ranns/* *INDENT-ON* */
394947ea622SNeale Ranns
395947ea622SNeale Rannsstatic clib_error_t *
396947ea622SNeale Rannstest_igmp_command_fn (vlib_main_t * vm,
397947ea622SNeale Ranns		      unformat_input_t * input, vlib_cli_command_t * cmd)
398947ea622SNeale Ranns{
399947ea622SNeale Ranns  clib_error_t *error = NULL;
400947ea622SNeale Ranns  u32 value;
401947ea622SNeale Ranns
402947ea622SNeale Ranns  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
403947ea622SNeale Ranns    {
404947ea622SNeale Ranns      if (unformat (input, "query %d", &value))
405947ea622SNeale Ranns	igmp_timer_type_set (IGMP_TIMER_QUERY, value);
406947ea622SNeale Ranns      else if (unformat (input, "src %d", &value))
407947ea622SNeale Ranns	igmp_timer_type_set (IGMP_TIMER_SRC, value);
408947ea622SNeale Ranns      else if (unformat (input, "leave %d", &value))
409947ea622SNeale Ranns	igmp_timer_type_set (IGMP_TIMER_LEAVE, value);
410947ea622SNeale Ranns      else
411947ea622SNeale Ranns	error = clib_error_return (0, "query or src timers only");
412947ea622SNeale Ranns    }
413947ea622SNeale Ranns
414947ea622SNeale Ranns  return error;
415947ea622SNeale Ranns}
416947ea622SNeale Ranns
417947ea622SNeale Ranns/* *INDENT-OFF* */
418947ea622SNeale RannsVLIB_CLI_COMMAND (test_igmp_command, static) = {
419947ea622SNeale Ranns  .path = "test igmp timers",
420947ea622SNeale Ranns  .short_help = "Change the default values for IGMP timers - only sensible during unit tests",
421947ea622SNeale Ranns  .function = test_igmp_command_fn,
422947ea622SNeale Ranns};
423947ea622SNeale Ranns/* *INDENT-ON* */
424947ea622SNeale Ranns
425947ea622SNeale Ranns
4267b867a8eSJakub Grajciarclib_error_t *
4277b867a8eSJakub Grajciarigmp_cli_init (vlib_main_t * vm)
4287b867a8eSJakub Grajciar{
4297b867a8eSJakub Grajciar  return 0;
4307b867a8eSJakub Grajciar}
4317b867a8eSJakub Grajciar
4327b867a8eSJakub GrajciarVLIB_INIT_FUNCTION (igmp_cli_init);
4337b867a8eSJakub Grajciar
4347b867a8eSJakub Grajciar/*
4357b867a8eSJakub Grajciar * fd.io coding-style-patch-verification: ON
4367b867a8eSJakub Grajciar *
4377b867a8eSJakub Grajciar * Local Variables:
4387b867a8eSJakub Grajciar * eval: (c-set-style "gnu")
4397b867a8eSJakub Grajciar * End:
4407b867a8eSJakub Grajciar */