+ src = igmp_src_lookup (group, &skey);
+ if (src)
+ {
+ /* add source to block_all_sources group */
+ igmp_key_t new_gkey;
+ igmp_group_t *new_group;
+
+ clib_memcpy (&new_gkey, &gkey, sizeof (igmp_key_t));
+ new_gkey.group_type =
+ IGMP_MEMBERSHIP_GROUP_block_old_sources;
+ new_group = igmp_group_lookup (config, &new_gkey);
+ if (!new_group)
+ {
+ pool_get (config->groups, new_group);
+
+ group = igmp_group_lookup (config, &gkey);
+
+ memset (new_group, 0, sizeof (igmp_group_t));
+ new_group->key = clib_mem_alloc (sizeof (igmp_key_t));
+ clib_memcpy (new_group->key, &new_gkey,
+ sizeof (igmp_key_t));
+ clib_memcpy (&new_group->addr, &group->addr,
+ sizeof (ip46_address_t));
+ new_group->igmp_src_by_key =
+ hash_create_mem (0, sizeof (igmp_key_t),
+ sizeof (uword));
+ new_group->n_srcs = 0;
+ new_group->type = new_gkey.group_type;
+ hash_set_mem (config->igmp_group_by_key, new_group->key,
+ new_group - config->groups);
+ }
+ igmp_src_t *new_src;
+ new_src = igmp_src_lookup (new_group, &skey);
+ if (!new_src)
+ {
+ pool_get (new_group->srcs, new_src);
+ memset (new_src, 0, sizeof (igmp_src_t));
+ new_group->n_srcs += 1;
+ new_src->key = clib_mem_alloc (sizeof (igmp_key_t));
+ clib_memcpy (new_src->key, src->key,
+ sizeof (igmp_key_t));
+ clib_memcpy (&new_src->addr, &src->addr,
+ sizeof (ip46_address_t));
+ hash_set_mem (new_group->igmp_src_by_key, new_src->key,
+ new_src - new_group->srcs);
+ }
+
+ /* notify all registered api clients */
+ if (!cli_api_configured)
+ igmp_event (im, config, new_group, new_src);
+ else
+ igmp_create_group_timer (0, sw_if_index, new_group->key,
+ igmp_send_state_changed);
+ /* remove source form mode_is_filter_include group */
+ hash_unset_mem (group->igmp_src_by_key, src->key);
+ clib_mem_free (src->key);
+ pool_put (group->srcs, src);
+ group->n_srcs -= 1;
+ if (group->n_srcs <= 0)
+ igmp_clear_group (config, group);
+ if (pool_elts (config->groups) <= 0)
+ igmp_clear_config (config);
+ }