/*
* RFC 3376 Section 2
" For a given combination of socket, interface, and multicast address,
- only a single filter mode and source list can be in effect at any one
- time. However, either the filter mode or the source list, or both,
- may be changed by subsequent IPMulticastListen requests that specify
- the same socket, interface, and multicast address. Each subsequent
- request completely replaces any earlier request for the given socket,
- interface and multicast address."
+ * only a single filter mode and source list can be in effect at any one
+ * time. However, either the filter mode or the source list, or both,
+ * may be changed by subsequent IPMulticastListen requests that specify
+ * the same socket, interface, and multicast address. Each subsequent
+ * request completely replaces any earlier request for the given socket,
+ * interface and multicast address."
*/
int rv = 0;
IGMP_DBG ("listen: (%U, %U) %U %U",
format_vnet_sw_if_index_name, vnet_get_main (),
sw_if_index, format_igmp_filter_mode, mode);
/*
- * find configuration, if it dosn't exist, then this interface is
+ * find configuration, if it doesn't exist, then this interface is
* not IGMP enabled
*/
config = igmp_config_lookup (sw_if_index);
goto error;
}
- /* find igmp group, if it dosn't exist, create new */
+ /* find igmp group, if it doesn't exist, create new */
group = igmp_group_lookup (config, gaddr);
if (!group)
}
if (0 == igmp_group_n_srcs (group, mode))
- igmp_group_clear (group);
+ igmp_group_clear (&group);
vec_free (added);
vec_free (removed);
/*
* The control plane is excluding some sources.
* - First; check for those that are present in the include list
- * - Second; check add them to the exlude list
+ * - Second; check add them to the exclude list
*
* TODO
*/
format_vnet_sw_if_index_name, vnet_get_main (), sw_if_index);
/* *INDENT-OFF* */
- fib_route_path_t for_us_path =
- {
- .frp_proto = fib_proto_to_dpo (FIB_PROTOCOL_IP4),
- .frp_addr = zero_addr,
- .frp_sw_if_index = 0xffffffff,
- .frp_fib_index = 0,
- .frp_weight = 1,
- .frp_flags = FIB_ROUTE_PATH_LOCAL,
- };
fib_route_path_t via_itf_path =
{
.frp_proto = fib_proto_to_dpo (FIB_PROTOCOL_IP4),
.frp_sw_if_index = sw_if_index,
.frp_fib_index = 0,
.frp_weight = 1,
+ .frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT,
};
+ fib_route_path_t for_us_path = {
+ .frp_proto = fib_proto_to_dpo (FIB_PROTOCOL_IP4),
+ .frp_addr = zero_addr,
+ .frp_sw_if_index = 0xffffffff,
+ .frp_fib_index = 1,
+ .frp_weight = 0,
+ .frp_flags = FIB_ROUTE_PATH_LOCAL,
+ .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
+ };
+
/* *INDENT-ON* */
- /* find configuration, if it dosn't exist, create new */
+ /* find configuration, if it doesn't exist, create new */
config = igmp_config_lookup (sw_if_index);
mfib_index = mfib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4,
sw_if_index);
vec_validate_init_empty (im->igmp_config_by_sw_if_index,
sw_if_index, ~0);
pool_get (im->configs, config);
- memset (config, 0, sizeof (igmp_config_t));
+ clib_memset (config, 0, sizeof (igmp_config_t));
config->sw_if_index = sw_if_index;
config->igmp_group_by_key =
hash_create_mem (0, sizeof (igmp_key_t), sizeof (uword));
config->robustness_var = IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
config->mode = mode;
+ config->proxy_device_id = ~0;
for (ii = 0; ii < IGMP_CONFIG_N_TIMERS; ii++)
config->timers[ii] = IGMP_TIMER_ID_INVALID;
if (1 == im->n_configs_per_mfib_index[mfib_index])
{
/* first config in this FIB */
+ mfib_table_lock (mfib_index, FIB_PROTOCOL_IP4, MFIB_SOURCE_IGMP);
mfib_table_entry_path_update (mfib_index,
&mpfx_general_query,
- MFIB_SOURCE_IGMP,
- &for_us_path,
- MFIB_ITF_FLAG_FORWARD);
+ MFIB_SOURCE_IGMP, &for_us_path);
mfib_table_entry_path_update (mfib_index,
&mpfx_report,
- MFIB_SOURCE_IGMP,
- &for_us_path,
- MFIB_ITF_FLAG_FORWARD);
+ MFIB_SOURCE_IGMP, &for_us_path);
}
mfib_table_entry_path_update (mfib_index,
&mpfx_general_query,
- MFIB_SOURCE_IGMP,
- &via_itf_path, MFIB_ITF_FLAG_ACCEPT);
+ MFIB_SOURCE_IGMP, &via_itf_path);
mfib_table_entry_path_update (mfib_index, &mpfx_report,
- MFIB_SOURCE_IGMP, &via_itf_path,
- MFIB_ITF_FLAG_ACCEPT);
+ MFIB_SOURCE_IGMP, &via_itf_path);
}
}
else if (config && !enable)
mfib_table_entry_path_remove (mfib_index,
&mpfx_report,
MFIB_SOURCE_IGMP, &for_us_path);
+ mfib_table_unlock (mfib_index, FIB_PROTOCOL_IP4, MFIB_SOURCE_IGMP);
}
mfib_table_entry_path_remove (mfib_index,
mfib_table_entry_path_remove (mfib_index,
&mpfx_report,
MFIB_SOURCE_IGMP, &via_itf_path);
+
+ /*
+ * remove interface from proxy device
+ * if this device is upstream, delete proxy device
+ */
+ if (config->mode == IGMP_MODE_ROUTER)
+ igmp_proxy_device_add_del_interface (config->proxy_device_id,
+ config->sw_if_index, 0);
+ else if (config->mode == IGMP_MODE_HOST)
+ igmp_proxy_device_add_del (config->proxy_device_id,
+ config->sw_if_index, 0);
+
igmp_clear_config (config);
im->igmp_config_by_sw_if_index[config->sw_if_index] = ~0;
hash_free (config->igmp_group_by_key);
pool_put (im->configs, config);
}
+ else
+ {
+ return -1;
+ }
return (0);
}
static clib_error_t *
igmp_init (vlib_main_t * vm)
{
- clib_error_t *error;
igmp_main_t *im = &igmp_main;
- if ((error = vlib_call_init_function (vm, ip4_lookup_init)))
- return error;
-
im->igmp_api_client_by_client_index = hash_create (0, sizeof (u32));
-
im->logger = vlib_log_register_class ("igmp", 0);
IGMP_DBG ("initialized");
- return (error);
+ return (0);
}
-VLIB_INIT_FUNCTION (igmp_init);
/* *INDENT-OFF* */
-VLIB_PLUGIN_REGISTER () = {
+VLIB_INIT_FUNCTION (igmp_init) =
+{
+ .runs_after = VLIB_INITS("ip4_lookup_init"),
+};
+VLIB_PLUGIN_REGISTER () =
+{
.version = VPP_BUILD_VER,
- .description = "IGMP messaging",
+ .description = "Internet Group Management Protocol (IGMP)",
};
/* *INDENT-ON* */