2 *------------------------------------------------------------------
3 * Copyright (c) 2018 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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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 *------------------------------------------------------------------
18 #include <igmp/igmp_group.h>
19 #include <igmp/igmp.h>
22 igmp_group_free_all_srcs (igmp_group_t * group)
27 FOR_EACH_SRC (src, group, IGMP_FILTER_MODE_INCLUDE,
33 hash_free (group->igmp_src_by_key[IGMP_FILTER_MODE_INCLUDE]);
34 hash_free (group->igmp_src_by_key[IGMP_FILTER_MODE_EXCLUDE]);
38 igmp_group_src_remove (igmp_group_t * group, igmp_src_t * src)
40 hash_unset_mem (group->igmp_src_by_key[IGMP_FILTER_MODE_INCLUDE], src->key);
41 hash_unset_mem (group->igmp_src_by_key[IGMP_FILTER_MODE_EXCLUDE], src->key);
45 igmp_group_src_update (igmp_group_t * group,
46 const igmp_key_t * skey, igmp_mode_t mode)
50 src = igmp_src_lookup (group, skey);
54 src = igmp_src_alloc (igmp_group_index (group), skey, mode);
56 hash_set_mem (group->igmp_src_by_key[IGMP_FILTER_MODE_INCLUDE],
57 src->key, igmp_src_index (src));
61 igmp_src_refresh (src);
68 igmp_group_clear (igmp_group_t * group)
70 igmp_config_t *config;
75 config = igmp_config_get (group->config);
77 IGMP_DBG ("clear-group: %U %U",
78 format_igmp_key, group->key,
79 format_vnet_sw_if_index_name,
80 vnet_get_main (), config->sw_if_index);
82 igmp_group_free_all_srcs (group);
84 for (ii = 0; ii < IGMP_GROUP_N_TIMERS; ii++)
86 igmp_timer_retire (&group->timers[ii]);
89 hash_unset_mem (config->igmp_group_by_key, group->key);
90 clib_mem_free (group->key);
91 pool_put (igmp_main.groups, group);
95 igmp_group_alloc (igmp_config_t * config,
96 const igmp_key_t * gkey, igmp_filter_mode_t mode)
98 igmp_main_t *im = &igmp_main;
102 IGMP_DBG ("new-group: %U", format_igmp_key, gkey);
103 pool_get (im->groups, group);
104 memset (group, 0, sizeof (igmp_group_t));
105 group->key = clib_mem_alloc (sizeof (igmp_key_t));
106 clib_memcpy (group->key, gkey, sizeof (igmp_key_t));
107 group->igmp_src_by_key[IGMP_FILTER_MODE_INCLUDE] =
108 hash_create_mem (0, sizeof (igmp_key_t), sizeof (uword));
109 group->igmp_src_by_key[IGMP_FILTER_MODE_EXCLUDE] =
110 hash_create_mem (0, sizeof (igmp_key_t), sizeof (uword));
111 group->router_filter_mode = mode;
112 group->config = igmp_config_index (config);
113 group->n_reports_sent = 0;
115 for (ii = 0; ii < IGMP_GROUP_N_TIMERS; ii++)
116 group->timers[ii] = IGMP_TIMER_ID_INVALID;
118 hash_set_mem (config->igmp_group_by_key, group->key, group - im->groups);
123 * the set of present sources minus the new set
126 igmp_group_present_minus_new (igmp_group_t * group,
127 igmp_filter_mode_t mode,
128 const ip46_address_t * saddrs)
130 const ip46_address_t *s1;
138 if (0 == vec_len(saddrs))
140 FOR_EACH_SRC(src, group, mode,
142 vec_add1(pmn, *src->key);
147 FOR_EACH_SRC(src, group, mode,
150 vec_foreach(s1, saddrs)
152 if (ip46_address_is_equal(s1, src->key))
160 vec_add1(pmn, *src->key);
169 * the set of new sources minus the present set
172 igmp_group_new_minus_present (igmp_group_t * group,
173 igmp_filter_mode_t mode,
174 const ip46_address_t * saddrs)
176 const ip46_address_t *s1;
184 vec_foreach(s1, saddrs)
187 FOR_EACH_SRC(src, group, mode,
189 if (ip46_address_is_equal(s1, src->key))
205 igmp_group_new_intersect_present (igmp_group_t * group,
206 igmp_filter_mode_t mode,
207 const ip46_address_t * saddrs)
209 ip46_address_t *intersect;
210 const ip46_address_t *s1;
216 FOR_EACH_SRC(src, group, mode,
218 vec_foreach(s1, saddrs)
220 if (s1->ip4.as_u32 == src->key->ip4.as_u32)
222 vec_add1(intersect, *s1);
233 igmp_group_n_srcs (const igmp_group_t * group, igmp_filter_mode_t mode)
235 return (hash_elts (group->igmp_src_by_key[mode]));
240 igmp_src_lookup (igmp_group_t * group, const igmp_key_t * key)
243 igmp_src_t *src = NULL;
247 p = hash_get_mem (group->igmp_src_by_key[IGMP_FILTER_MODE_INCLUDE], key);
249 src = vec_elt_at_index (igmp_main.srcs, p[0]);
255 igmp_group_index (const igmp_group_t * g)
257 return (g - igmp_main.groups);
261 igmp_group_get (u32 index)
263 return (pool_elt_at_index (igmp_main.groups, index));
267 * fd.io coding-style-patch-verification: ON
270 * eval: (c-set-style "gnu")