FD.io VPP  v18.11-rc0-18-g2a3fb1a
Vector Packet Processing
igmp_cli.c
Go to the documentation of this file.
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 *
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 /* *INDENT-OFF* */
73 VLIB_CLI_COMMAND (igmp_clear_interface_command, static) = {
74  .path = "clear igmp",
75  .short_help = "clear igmp int <interface>",
77 };
78 /* *INDENT-ON* */
79 
80 static clib_error_t *
82  vlib_cli_command_t * cmd)
83 {
84  unformat_input_t _line_input, *line_input = &_line_input;
85  clib_error_t *error = NULL;
86  u8 enable = 1;
87  ip46_address_t saddr, *saddrs = NULL, gaddr;
88  vnet_main_t *vnm = vnet_get_main ();
89  u32 sw_if_index;
90  int rv;
91 
92  if (!unformat_user (input, unformat_line_input, line_input))
93  {
94  error =
96  "'help igmp listen' or 'igmp listen ?' for help");
97  return error;
98  }
99 
100  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
101  {
102  if (unformat (line_input, "enable"))
103  enable = 1;
104  else if (unformat (line_input, "disable"))
105  enable = 0;
106  else
107  if (unformat
108  (line_input, "int %U", unformat_vnet_sw_interface, vnm,
109  &sw_if_index));
110  else
111  if (unformat (line_input, "saddr %U", unformat_ip46_address, &saddr))
112  vec_add1 (saddrs, saddr);
113  else
114  if (unformat (line_input, "gaddr %U", unformat_ip46_address, &gaddr));
115  else
116  {
117  error =
118  clib_error_return (0, "unknown input '%U'", format_unformat_error,
119  line_input);
120  goto done;
121  }
122  }
123 
124  if ((vnet_sw_interface_get_flags (vnm, sw_if_index)
126  {
127  error = clib_error_return (0, "Interface is down");
128  goto done;
129  }
130 
131  rv = igmp_listen (vm, enable, sw_if_index, saddrs, &gaddr);
132 
133  if (rv == -1)
134  {
135  if (enable)
136  error =
137  clib_error_return (0, "This igmp configuration already exists");
138  else
139  error =
140  clib_error_return (0, "This igmp configuration does not nexist");
141  }
142  else if (rv == -2)
143  error =
145  "Failed to add configuration, interface is in router mode");
146 
147 done:
148  unformat_free (line_input);
149  vec_free (saddrs);
150  return error;
151 }
152 
153 /* *INDENT-OFF* */
154 VLIB_CLI_COMMAND (igmp_listen_command, static) = {
155  .path = "igmp listen",
156  .short_help = "igmp listen [<enable|disable>] "
157  "int <interface> saddr <ip4-address> gaddr <ip4-address>",
158  .function = igmp_listen_command_fn,
159 };
160 /* *INDENT-ON* */
161 
162 static clib_error_t *
164  vlib_cli_command_t * cmd)
165 {
166  clib_error_t *error = NULL;
167  igmp_main_t *im = &igmp_main;
168  vnet_main_t *vnm = vnet_get_main ();
169  igmp_config_t *config;
170  igmp_group_t *group;
171  igmp_src_t *src;
172 
173  /* *INDENT-OFF* */
174  pool_foreach (config, im->configs,
175  ({
176  vlib_cli_output (vm, "interface: %U", format_vnet_sw_if_index_name,
177  vnm, config->sw_if_index);
178 
179  FOR_EACH_GROUP (group, config,
180  ({
181  vlib_cli_output (vm, "\t%U", format_igmp_key, group->key);
182  FOR_EACH_SRC (src, group, IGMP_FILTER_MODE_INCLUDE,
183  ({
184  vlib_cli_output (vm, "\t\t%U", format_igmp_key, src->key);
185  }));
186  }));
187  }));
188  /* *INDENT-ON* */
189 
190  return error;
191 }
192 
193 /* *INDENT-OFF* */
194 VLIB_CLI_COMMAND (igmp_show_command, static) = {
195  .path = "show igmp config",
196  .short_help = "show igmp config",
197  .function = igmp_show_command_fn,
198 };
199 /* *INDENT-ON* */
200 
201 static clib_error_t *
203  unformat_input_t * input,
204  vlib_cli_command_t * cmd)
205 {
206 #define _(n,f) vlib_cli_output (vm, "%s: %d", #f, igmp_timer_type_get(n));
208 #undef _
209  return (NULL);
210 }
211 
212 /* *INDENT-OFF* */
213 VLIB_CLI_COMMAND (igmp_show_timers_command, static) = {
214  .path = "show igmp timers",
215  .short_help = "show igmp timers",
216  .function = igmp_show_timers_command_fn,
217 };
218 /* *INDENT-ON* */
219 
220 static clib_error_t *
222  unformat_input_t * input, vlib_cli_command_t * cmd)
223 {
224  clib_error_t *error = NULL;
225  u32 value;
226 
228  {
229  if (unformat (input, "query %d", &value))
230  igmp_timer_type_set (IGMP_TIMER_QUERY, value);
231  else if (unformat (input, "src %d", &value))
232  igmp_timer_type_set (IGMP_TIMER_SRC, value);
233  else if (unformat (input, "leave %d", &value))
234  igmp_timer_type_set (IGMP_TIMER_LEAVE, value);
235  else
236  error = clib_error_return (0, "query or src timers only");
237  }
238 
239  return error;
240 }
241 
242 /* *INDENT-OFF* */
243 VLIB_CLI_COMMAND (test_igmp_command, static) = {
244  .path = "test igmp timers",
245  .short_help = "Change the default values for IGMP timers - only sensible during unit tests",
246  .function = test_igmp_command_fn,
247 };
248 /* *INDENT-ON* */
249 
250 
251 clib_error_t *
253 {
254  return 0;
255 }
256 
258 
259 /*
260  * fd.io coding-style-patch-verification: ON
261  *
262  * Local Variables:
263  * eval: (c-set-style "gnu")
264  * End:
265  */
int igmp_listen(vlib_main_t *vm, igmp_filter_mode_t mode, u32 sw_if_index, const ip46_address_t *saddrs, const ip46_address_t *gaddr)
igmp listen Called by a host to request reception of multicast packets
Definition: igmp.c:133
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
igmp_main_t igmp_main
Definition: igmp.c:36
#define NULL
Definition: clib.h:55
igmp_config_t * configs
pool of configs
Definition: igmp.h:94
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:983
unformat_function_t unformat_vnet_sw_interface
static clib_error_t * igmp_show_timers_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: igmp_cli.c:202
unsigned char u8
Definition: types.h:56
void igmp_clear_config(igmp_config_t *config)
igmp clear config
Definition: igmp_config.c:22
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:443
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:156
#define clib_error_return(e, args...)
Definition: error.h:99
unsigned int u32
Definition: types.h:88
static clib_error_t * test_igmp_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: igmp_cli.c:221
unformat_function_t unformat_line_input
Definition: format.h:282
igmp_config_t * igmp_config_lookup(u32 sw_if_index)
igmp config lookup
Definition: igmp_config.c:45
struct _unformat_input_t unformat_input_t
static clib_error_t * igmp_clear_interface_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: igmp_cli.c:32
void igmp_timer_type_set(igmp_timer_type_t t, u32 v)
Definition: igmp_timer.c:75
static clib_error_t * igmp_listen_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: igmp_cli.c:81
collection of data related to IGMP
Definition: igmp.h:62
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
vlib_main_t * vm
Definition: buffer.c:294
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
static clib_error_t * igmp_show_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: igmp_cli.c:163
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:661
unformat_function_t unformat_ip46_address
Definition: format.h:71
IGMP interface configuration.
Definition: igmp_config.h:43
IGMP group A multicast group address for which reception has been requested.
Definition: igmp_group.h:55
static void unformat_free(unformat_input_t *i)
Definition: format.h:162
clib_error_t * igmp_cli_init(vlib_main_t *vm)
Definition: igmp_cli.c:252
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
static uword vnet_sw_interface_get_flags(vnet_main_t *vnm, u32 sw_if_index)
IGMP source The representation of a specified source address with in multicast group.
Definition: igmp_src.h:41
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170