FD.io VPP  v19.04.2-12-g66b1689
Vector Packet Processing
igmp.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 <vlib/vlib.h>
19 #include <vnet/plugin/plugin.h>
20 #include <vpp/app/version.h>
21 #include <vnet/ip/ip.h>
22 #include <vnet/mfib/mfib_entry.h>
23 #include <vlib/unix/unix.h>
24 #include <vnet/adj/adj_mcast.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 #include <igmp/igmp_format.h>
31 #include <igmp/igmp_pkt.h>
32 
33 #include <limits.h>
34 #include <float.h>
35 
37 
38 /* *INDENT-OFF* */
39 /* General Query address */
40 const static mfib_prefix_t mpfx_general_query = {
42  .fp_len = 32,
43  .fp_grp_addr = {
44  .ip4 = {
46  },
47  },
48 };
49 
50 /* Report address */
51 const static mfib_prefix_t mpfx_report = {
53  .fp_len = 32,
54  .fp_grp_addr = {
55  .ip4 = {
57  },
58  },
59 };
60 /* *INDENT-ON* */
61 
62 /**
63  * @brief igmp send query (igmp_timer_function_t)
64  *
65  * Send an igmp query.
66  * If the timer holds group key, send Group-Specific query,
67  * else send General query.
68  */
69 static void
70 igmp_send_general_query (u32 obj, void *dat)
71 {
73  igmp_config_t *config;
74 
75  config = igmp_config_get (obj);
76 
77  IGMP_DBG ("send-general-query: %U",
79  config->sw_if_index);
80 
81  igmp_timer_retire (&config->timers[IGMP_CONFIG_TIMER_GENERAL_QUERY]);
82 
86 
87  /*
88  * re-schedule
89  */
90  config->timers[IGMP_CONFIG_TIMER_GENERAL_QUERY] =
91  igmp_timer_schedule (igmp_timer_type_get (IGMP_TIMER_QUERY),
92  igmp_config_index (config),
94 }
95 
96 static void
98  const igmp_group_t * group)
99 {
101 
102  IGMP_DBG ("state-change-group: %U", format_igmp_key, group->key);
103 
104  igmp_pkt_build_report_init (&br, sw_if_index);
106  group,
107  IGMP_MEMBERSHIP_GROUP_allow_new_sources);
109 }
110 
111 static void
113 {
114  igmp_config_t *config;
115  igmp_group_t *group;
116 
117  group = igmp_group_get (gi);
118  config = igmp_config_get (group->config);
119 
120  igmp_timer_retire (&group->timers[IGMP_GROUP_TIMER_RESEND_REPORT]);
122 
123  if (++group->n_reports_sent < config->robustness_var)
124  {
125  group->timers[IGMP_GROUP_TIMER_RESEND_REPORT] =
126  igmp_timer_schedule (igmp_timer_type_get (IGMP_TIMER_REPORT_INTERVAL),
127  igmp_group_index (group),
129  }
130 }
131 
132 int
136  const ip46_address_t * saddrs, const ip46_address_t * gaddr)
137 {
138  const ip46_address_t *saddr;
139  igmp_config_t *config;
140  igmp_group_t *group;
141 
142  /*
143  * RFC 3376 Section 2
144  " For a given combination of socket, interface, and multicast address,
145  * only a single filter mode and source list can be in effect at any one
146  * time. However, either the filter mode or the source list, or both,
147  * may be changed by subsequent IPMulticastListen requests that specify
148  * the same socket, interface, and multicast address. Each subsequent
149  * request completely replaces any earlier request for the given socket,
150  * interface and multicast address."
151  */
152  int rv = 0;
153  IGMP_DBG ("listen: (%U, %U) %U %U",
155  format_igmp_key, gaddr,
157  sw_if_index, format_igmp_filter_mode, mode);
158  /*
159  * find configuration, if it doesn't exist, then this interface is
160  * not IGMP enabled
161  */
162  config = igmp_config_lookup (sw_if_index);
163 
164  if (!config)
165  {
166  rv = VNET_API_ERROR_INVALID_INTERFACE;
167  goto error;
168  }
169  if (config->mode != IGMP_MODE_HOST)
170  {
171  rv = VNET_API_ERROR_INVALID_INTERFACE;
172  goto error;
173  }
174 
175  /* find igmp group, if it doesn't exist, create new */
176  group = igmp_group_lookup (config, gaddr);
177 
178  if (!group)
179  {
180  group = igmp_group_alloc (config, gaddr, mode);
181 
182  /* new group implies create all sources */
183  vec_foreach (saddr, saddrs)
184  {
185  igmp_group_src_update (group, saddr, IGMP_MODE_HOST);
186  }
187 
188  /*
189  * Send state changed event report for the group.
190  *
191  * RFC3376 Section 5.1
192  * "To cover the possibility of the State-Change Report being missed by
193  * one or more multicast routers, it is retransmitted [Robustness
194  * Variable] - 1 more times, at intervals chosen at random from the
195  * range (0, [Unsolicited Report Interval])."
196  */
198 
199  igmp_timer_retire (&group->timers[IGMP_GROUP_TIMER_RESEND_REPORT]);
200 
201  group->n_reports_sent = 1;
202  group->timers[IGMP_GROUP_TIMER_RESEND_REPORT] =
203  igmp_timer_schedule (igmp_timer_type_get (IGMP_TIMER_REPORT_INTERVAL),
204  igmp_group_index (group),
206  }
207  else
208  {
209  IGMP_DBG ("... update (%U, %U) %U %U",
211  format_igmp_key, gaddr,
213  sw_if_index, format_igmp_filter_mode, mode);
214 
215  /*
216  * RFC 3367 Section 5.1
217  *
218  * Old State New State State-Change Record Sent
219  * --------- --------- ------------------------
220  *
221  * 1) INCLUDE (A) INCLUDE (B) ALLOW (B-A), BLOCK (A-B)
222  * 2) EXCLUDE (A) EXCLUDE (B) ALLOW (A-B), BLOCK (B-A)
223  * 3) INCLUDE (A) EXCLUDE (B) TO_EX (B)
224  * 4) EXCLUDE (A) INCLUDE (B) TO_IN (B)
225  *
226  * N.B. We do not split state-change records for pending transfer
227  * hence there is no merge logic required.
228  */
229 
230  if (IGMP_FILTER_MODE_INCLUDE == mode)
231  {
232  ip46_address_t *added, *removed;
234 
235  /*
236  * find the list of sources that have been added and removed from
237  * the include set
238  */
239  removed =
240  igmp_group_present_minus_new (group, IGMP_FILTER_MODE_INCLUDE,
241  saddrs);
242  added =
243  igmp_group_new_minus_present (group, IGMP_FILTER_MODE_INCLUDE,
244  saddrs);
245 
246  if (!(vec_len (added) || vec_len (removed)))
247  /* no change => done */
248  goto error;
249 
251 
252  if (vec_len (added))
253  {
255  group->key,
256  added,
257  IGMP_MEMBERSHIP_GROUP_allow_new_sources);
258  }
259 
260  if (vec_len (removed))
261  {
263  group->key,
264  removed,
265  IGMP_MEMBERSHIP_GROUP_block_old_sources);
266  }
267 
268  IGMP_DBG ("... added %U", format_igmp_src_addr_list, added);
269  IGMP_DBG ("... removed %U", format_igmp_src_addr_list, removed);
270 
272 
273  /*
274  * clear the group of the old sources and populate it with the new
275  * set requested
276  */
277  igmp_group_free_all_srcs (group);
278 
279  vec_foreach (saddr, saddrs)
280  {
281  igmp_group_src_update (group, saddr, IGMP_MODE_HOST);
282  }
283 
284  if (0 == igmp_group_n_srcs (group, mode))
285  igmp_group_clear (group);
286 
287  vec_free (added);
288  vec_free (removed);
289  }
290  else
291  {
292  /*
293  * The control plane is excluding some sources.
294  * - First; check for those that are present in the include list
295  * - Second; check add them to the exclude list
296  *
297  * TODO
298  */
299  }
300  }
301 
302 error:
303  return (rv);
304 }
305 
306 /** \brief igmp hardware interface link up down
307  @param vnm - vnet main
308  @param hw_if_index - interface hw_if_index
309  @param flags - hw interface flags
310 
311  If an interface goes down, remove its (S,G)s.
312 */
313 static walk_rc_t
315 {
316  igmp_config_t *config;
317  config = igmp_config_lookup (sw_if_index);
318  IGMP_DBG ("down: %U",
320  if (NULL != config)
321  {
322  igmp_clear_config (config);
323  }
324 
325  return (WALK_CONTINUE);
326 }
327 
328 static clib_error_t *
330 {
331  clib_error_t *error = NULL;
332  /* remove igmp state from down interfaces */
333  if (!(flags & VNET_HW_INTERFACE_FLAG_LINK_UP))
334  vnet_hw_interface_walk_sw (vnm, hw_if_index, igmp_sw_if_down, NULL);
335  return error;
336 }
337 
339 int
341 {
342  igmp_config_t *config;
343  igmp_main_t *im = &igmp_main;
344  u32 mfib_index;
345  IGMP_DBG ("%s: %U", (enable ? "Enabled" : "Disabled"),
347 
348  /* *INDENT-OFF* */
349  fib_route_path_t for_us_path =
350  {
352  .frp_addr = zero_addr,
353  .frp_sw_if_index = 0xffffffff,
354  .frp_fib_index = 0,
355  .frp_weight = 1,
356  .frp_flags = FIB_ROUTE_PATH_LOCAL,
357  };
358  fib_route_path_t via_itf_path =
359  {
361  .frp_addr = zero_addr,
362  .frp_sw_if_index = sw_if_index,
363  .frp_fib_index = 0,
364  .frp_weight = 1,
365  };
366  /* *INDENT-ON* */
367  /* find configuration, if it doesn't exist, create new */
368  config = igmp_config_lookup (sw_if_index);
370  sw_if_index);
371  if (!config && enable)
372  {
373  u32 ii;
374 
376  sw_if_index, ~0);
377  pool_get (im->configs, config);
378  clib_memset (config, 0, sizeof (igmp_config_t));
379  config->sw_if_index = sw_if_index;
380  config->igmp_group_by_key =
381  hash_create_mem (0, sizeof (igmp_key_t), sizeof (uword));
383  config->mode = mode;
384  config->proxy_device_id = ~0;
385 
386  for (ii = 0; ii < IGMP_CONFIG_N_TIMERS; ii++)
387  config->timers[ii] = IGMP_TIMER_ID_INVALID;
388 
389  if (IGMP_MODE_ROUTER == mode)
390  {
391  config->timers[IGMP_CONFIG_TIMER_GENERAL_QUERY] =
392  igmp_timer_schedule (igmp_timer_type_get (IGMP_TIMER_QUERY),
393  igmp_config_index (config),
395  }
396 
397  config->adj_index =
399  config->sw_if_index);
401  (config - im->configs);
402  {
403  vec_validate (im->n_configs_per_mfib_index, mfib_index);
404  im->n_configs_per_mfib_index[mfib_index]++;
405  if (1 == im->n_configs_per_mfib_index[mfib_index])
406  {
407  /* first config in this FIB */
408  mfib_table_entry_path_update (mfib_index,
409  &mpfx_general_query,
411  &for_us_path,
413  mfib_table_entry_path_update (mfib_index,
414  &mpfx_report,
416  &for_us_path,
418  }
419  mfib_table_entry_path_update (mfib_index,
420  &mpfx_general_query,
422  &via_itf_path, MFIB_ITF_FLAG_ACCEPT);
423  mfib_table_entry_path_update (mfib_index, &mpfx_report,
424  MFIB_SOURCE_IGMP, &via_itf_path,
426  }
427  }
428  else if (config && !enable)
429  {
430  vec_validate (im->n_configs_per_mfib_index, mfib_index);
431  im->n_configs_per_mfib_index[mfib_index]--;
432  if (0 == im->n_configs_per_mfib_index[mfib_index])
433  {
434  /* last config in this FIB */
435  mfib_table_entry_path_remove (mfib_index,
436  &mpfx_general_query,
437  MFIB_SOURCE_IGMP, &for_us_path);
438  mfib_table_entry_path_remove (mfib_index,
439  &mpfx_report,
440  MFIB_SOURCE_IGMP, &for_us_path);
441  }
442 
443  mfib_table_entry_path_remove (mfib_index,
444  &mpfx_general_query,
445  MFIB_SOURCE_IGMP, &via_itf_path);
446  mfib_table_entry_path_remove (mfib_index,
447  &mpfx_report,
448  MFIB_SOURCE_IGMP, &via_itf_path);
449 
450  /*
451  * remove interface from proxy device
452  * if this device is upstream, delete proxy device
453  */
454  if (config->mode == IGMP_MODE_ROUTER)
456  config->sw_if_index, 0);
457  else if (config->mode == IGMP_MODE_HOST)
459  config->sw_if_index, 0);
460 
461  igmp_clear_config (config);
462  im->igmp_config_by_sw_if_index[config->sw_if_index] = ~0;
463  hash_free (config->igmp_group_by_key);
464  pool_put (im->configs, config);
465  }
466  else
467  {
468  return -1;
469  }
470 
471  return (0);
472 }
473 
474 /** \brief igmp initialization
475  @param vm - vlib main
476 
477  initialize igmp plugin. Initialize igmp_main, set mfib to allow igmp traffic.
478 */
479 static clib_error_t *
481 {
482  clib_error_t *error;
483  igmp_main_t *im = &igmp_main;
484 
485  if ((error = vlib_call_init_function (vm, ip4_lookup_init)))
486  return error;
487 
488  im->igmp_api_client_by_client_index = hash_create (0, sizeof (u32));
489 
490  im->logger = vlib_log_register_class ("igmp", 0);
491 
492  IGMP_DBG ("initialized");
493 
494  return (error);
495 }
496 
498 /* *INDENT-OFF* */
500  .version = VPP_BUILD_VER,
501  .description = "Internet Group Management Protocol (IGMP)",
502 };
503 /* *INDENT-ON* */
504 
505 /*
506  * fd.io coding-style-patch-verification: ON
507  *
508  * Local Variables:
509  * eval: (c-set-style "gnu")
510  * End:
511  */
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
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:227
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
u32 sw_if_index
Definition: ipsec_gre.api:37
igmp_timer_id_t timers[IGMP_CONFIG_N_TIMERS]
A vector of scheduled query-response timers.
Definition: igmp_config.h:77
u8 * format_igmp_src_addr_list(u8 *s, va_list *args)
Definition: igmp_format.c:186
u32 flags
Definition: vhost_user.h:115
u8 * format_igmp_key(u8 *s, va_list *args)
Definition: igmp_format.c:203
void igmp_pkt_query_v3_send(igmp_pkt_build_query_t *bq)
Definition: igmp_pkt.c:513
static void igmp_send_state_change_group_report_v3(u32 sw_if_index, const igmp_group_t *group)
Definition: igmp.c:97
void igmp_timer_retire(igmp_timer_id_t *tid)
Definition: igmp_timer.c:222
igmp_group_t * igmp_group_lookup(igmp_config_t *config, const igmp_key_t *key)
igmp group lookup
Definition: igmp_config.c:76
A representation of a path as described by a route producer.
Definition: fib_types.h:470
int igmp_proxy_device_add_del_interface(u32 vrf_id, u32 sw_if_index, u8 add)
IGMP proxy device add/del interface.
Definition: igmp_proxy.c:141
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
static clib_error_t * ip4_lookup_init(vlib_main_t *vm)
Definition: ip4_forward.c:909
igmp_main_t igmp_main
Definition: igmp.c:36
void vnet_hw_interface_walk_sw(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_sw_interface_walk_t fn, void *ctx)
Walk the SW interfaces on a HW interface - this is the super interface and any sub-interfaces.
Definition: interface.c:1021
void igmp_group_free_all_srcs(igmp_group_t *group)
Definition: igmp_group.c:22
#define NULL
Definition: clib.h:58
igmp_config_t * configs
pool of configs
Definition: igmp.h:95
VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION(igmp_hw_interface_link_up_down)
adj_index_t adj_index
Definition: igmp_config.h:57
void igmp_pkt_report_v3_add_group(igmp_pkt_build_report_t *br, const igmp_group_t *group, igmp_membership_group_v3_type_t type)
Definition: igmp_pkt.c:349
igmp_src_t * igmp_group_src_update(igmp_group_t *group, const igmp_key_t *skey, igmp_mode_t mode)
Definition: igmp_group.c:45
static clib_error_t * igmp_hw_interface_link_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: igmp.c:329
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
dpo_proto_t frp_proto
The protocol of the address below.
Definition: fib_types.h:475
u8 data[128]
Definition: ipsec.api:248
#define IGMP_GENERAL_QUERY_ADDRESS
General Query address - 224.0.0.1 Membership Report address - 224.0.0.22 SSM default range 232/8...
Definition: igmp.h:51
static clib_error_t * igmp_init(vlib_main_t *vm)
igmp initialization
Definition: igmp.c:480
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:236
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
void igmp_pkt_build_report_init(igmp_pkt_build_report_t *br, u32 sw_if_index)
Definition: igmp_pkt.c:400
#define IGMP_DBG(...)
Definition: igmp.h:38
igmp_timer_id_t igmp_timer_schedule(f64 when, u32 obj, igmp_timer_function_t fn, void *data)
Schedule a timer to expire in &#39;when&#39; seconds.
Definition: igmp_timer.c:196
void igmp_clear_config(igmp_config_t *config)
igmp clear config
Definition: igmp_config.c:22
u32 igmp_timer_type_get(igmp_timer_type_t t)
Definition: igmp_timer.c:68
enum walk_rc_t_ walk_rc_t
Walk return code.
u32 n_reports_sent
The number of times the last report has been sent.
Definition: igmp_group.h:82
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:163
u32 mfib_table_get_index_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the index of the FIB bound to the interface.
Definition: mfib_table.c:476
ip46_address_t * igmp_group_present_minus_new(igmp_group_t *group, igmp_filter_mode_t mode, const ip46_address_t *saddrs)
the set of present sources minus the new set
Definition: igmp_group.c:143
u32 igmp_config_index(const igmp_config_t *c)
Get the pool index for a config.
Definition: igmp_config.c:64
fib_node_index_t mfib_table_entry_path_update(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, const fib_route_path_t *rpath, mfib_itf_flags_t itf_flags)
Add n paths to an entry (aka route) in the FIB.
Definition: mfib_table.c:290
igmp_config_t * igmp_config_get(u32 index)
Get the config from the pool index.
Definition: igmp_config.c:70
unsigned int u32
Definition: types.h:88
#define vlib_call_init_function(vm, x)
Definition: init.h:260
void igmp_pkt_report_v3_send(igmp_pkt_build_report_t *br)
Definition: igmp_pkt.c:208
uword * igmp_group_by_key
Database of groups joined on the link.
Definition: igmp_config.h:72
igmp_config_t * igmp_config_lookup(u32 sw_if_index)
igmp config lookup
Definition: igmp_config.c:45
#define IGMP_CONFIG_N_TIMERS
Definition: igmp_config.h:40
#define hash_create_mem(elts, key_bytes, value_bytes)
Definition: hash.h:661
int igmp_enable_disable(u32 sw_if_index, u8 enable, igmp_mode_t mode)
IGMP interface enable/disable.
Definition: igmp.c:340
#define IGMP_DEFAULT_ROBUSTNESS_VARIABLE
RFC 3376 Section 8.1.
Definition: igmp.h:36
vlib_log_class_t logger
logger - VLIB log class
Definition: igmp.h:90
long ctx[MAX_CONNS]
Definition: main.c:144
u32 config
The pool index of the config object this group is in.
Definition: igmp_group.h:77
#define IGMP_MEMBERSHIP_REPORT_ADDRESS
Definition: igmp.h:52
#define hash_free(h)
Definition: hash.h:310
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:286
collection of data related to IGMP
Definition: igmp.h:63
igmp_group_t * igmp_group_alloc(igmp_config_t *config, const igmp_key_t *gkey, igmp_filter_mode_t mode)
Definition: igmp_group.c:103
vlib_main_t * vm
Definition: buffer.c:312
u32 timers[IGMP_GROUP_N_TIMERS]
A vector of running timers for the group.
Definition: igmp_group.h:67
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
u32 * igmp_config_by_sw_if_index
per-interface DB of configs
Definition: igmp.h:80
void igmp_pkt_query_v3_add_group(igmp_pkt_build_query_t *bq, const igmp_group_t *group, const ip46_address_t *srcs)
Definition: igmp_pkt.c:448
enum igmp_filter_mode_t_ igmp_filter_mode_t
vl_api_vxlan_gbp_api_tunnel_mode_t mode
Definition: vxlan_gbp.api:44
Aggregrate type for a prefix.
Definition: mfib_types.h:24
#define IGMP_TIMER_ID_INVALID
Definition: igmp_timer.h:28
VLIB_PLUGIN_REGISTER()
#define hash_create(elts, value_bytes)
Definition: hash.h:696
void igmp_pkt_report_v3_add_report(igmp_pkt_build_report_t *br, const ip46_address_t *grp, const ip46_address_t *srcs, igmp_membership_group_v3_type_t type)
Definition: igmp_pkt.c:309
igmp_group_t * igmp_group_get(u32 index)
Definition: igmp_group.c:278
u32 * n_configs_per_mfib_index
the number of igmp configs for each mfib_index (VRF)
Definition: igmp.h:85
u8 * format_igmp_filter_mode(u8 *s, va_list *args)
Definition: igmp_format.c:50
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:237
ip46_address_t igmp_key_t
IGMP Key Used to index groups within an interface config and sources within a list.
Definition: igmp_types.h:49
u8 robustness_var
Robustness variable (section 5.1)
Definition: igmp_config.h:67
IGMP interface configuration.
Definition: igmp_config.h:47
u32 proxy_device_id
ID of a proxy device this configuration is on.
Definition: igmp_config.h:82
fib_protocol_t fp_proto
protocol type
Definition: mfib_types.h:33
A for-us/local path.
Definition: fib_types.h:332
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
igmp_key_t * key
The group&#39;s key within the per-interface config.
Definition: igmp_group.h:59
IGMP group A multicast group address for which reception has been requested.
Definition: igmp_group.h:56
u64 uword
Definition: types.h:112
static void igmp_send_general_query(u32 obj, void *dat)
igmp send query (igmp_timer_function_t)
Definition: igmp.c:70
void igmp_pkt_build_query_init(igmp_pkt_build_query_t *bq, u32 sw_if_index)
Definition: igmp_pkt.c:523
enum igmp_mode_t_ igmp_mode_t
adj_index_t adj_mcast_add_or_lock(fib_protocol_t proto, vnet_link_t link_type, u32 sw_if_index)
Mcast Adjacency.
Definition: adj_mcast.c:51
static void igmp_resend_state_change_group_report_v3(u32 gi, void *data)
Definition: igmp.c:112
#define vec_foreach(var, vec)
Vector iterator.
uword * igmp_api_client_by_client_index
Definition: igmp.h:70
ip46_address_t * igmp_group_new_minus_present(igmp_group_t *group, igmp_filter_mode_t mode, const ip46_address_t *saddrs)
the set of new sources minus the present set
Definition: igmp_group.c:189
igmp_mode_t mode
Definition: igmp_config.h:62
u32 igmp_group_n_srcs(const igmp_group_t *group, igmp_filter_mode_t mode)
Definition: igmp_group.c:250
void igmp_group_clear(igmp_group_t *group)
Definition: igmp_group.c:68
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:486
void mfib_table_entry_path_remove(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, const fib_route_path_t *rpath)
Remove n paths to an entry (aka route) in the FIB.
Definition: mfib_table.c:329
int igmp_proxy_device_add_del(u32 vrf_id, u32 sw_if_index, u8 add)
IGMP proxy device add/del.
Definition: igmp_proxy.c:80
u32 igmp_group_index(const igmp_group_t *g)
Definition: igmp_group.c:272
const ip46_address_t zero_addr
Definition: lookup.c:319
static walk_rc_t igmp_sw_if_down(vnet_main_t *vnm, u32 sw_if_index, void *ctx)
igmp hardware interface link up down
Definition: igmp.c:314