X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Figmp%2Figmp.c;h=1e9f647cd11bb15db263511c1574bb7441aebbe9;hb=097fa66b9;hp=85ba35c31d60163cde4e76620df2ed2e113e1bad;hpb=bdc0e6b7204ea0211d4f7881497e4306586fb9ef;p=vpp.git diff --git a/src/plugins/igmp/igmp.c b/src/plugins/igmp/igmp.c index 85ba35c31d6..1e9f647cd11 100644 --- a/src/plugins/igmp/igmp.c +++ b/src/plugins/igmp/igmp.c @@ -142,12 +142,12 @@ igmp_listen (vlib_main_t * vm, /* * 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", @@ -346,15 +346,6 @@ igmp_enable_disable (u32 sw_if_index, u8 enable, igmp_mode_t mode) 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), @@ -362,7 +353,18 @@ igmp_enable_disable (u32 sw_if_index, u8 enable, igmp_mode_t mode) .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 doesn't exist, create new */ config = igmp_config_lookup (sw_if_index); @@ -375,12 +377,13 @@ igmp_enable_disable (u32 sw_if_index, u8 enable, igmp_mode_t mode) 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; @@ -404,24 +407,19 @@ igmp_enable_disable (u32 sw_if_index, u8 enable, igmp_mode_t mode) 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) @@ -437,6 +435,7 @@ igmp_enable_disable (u32 sw_if_index, u8 enable, igmp_mode_t mode) 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, @@ -445,6 +444,18 @@ igmp_enable_disable (u32 sw_if_index, u8 enable, igmp_mode_t mode) 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); @@ -466,26 +477,25 @@ igmp_enable_disable (u32 sw_if_index, u8 enable, igmp_mode_t mode) 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* */