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:
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 *------------------------------------------------------------------
21 #include <vlib/vlib.h>
22 #include <vnet/ip/ip.h>
23 #include <vnet/ip/igmp_packet.h>
24 #include <vnet/adj/adj_mcast.h>
25 #include <igmp/igmp_format.h>
27 #define IGMP_QUERY_TIMER (60)
28 #define IGMP_SG_TIMER (3 * IGMP_QUERY_TIMER)
29 #define IGMP_DEFAULT_ROBUSTNESS_VARIABLE (2)
34 #define DBG(...) clib_warning(__VA_ARGS__)
39 #define group_ptr(p, l) ((igmp_membership_group_v3_t *)((char*)p + l))
43 IGMP_PROCESS_EVENT_UPDATE_TIMER = 1,
44 } igmp_process_event_t;
53 struct igmp_config_t_;
55 typedef struct igmp_config_t_ igmp_config_t;
57 /* populate supplied bufefr with IGMP message */
58 typedef void (create_msg_t) (vlib_buffer_t * b, igmp_config_t * config);
60 typedef struct igmp_index_t_
66 typedef struct igmp_sg_key_t_
72 typedef struct igmp_sg_t_
77 igmp_membership_group_v3_type_t group_type;
79 /* check if expired (S,G) timer is valid */
85 typedef struct igmp_config_t_
89 adj_index_t adj_index;
91 u8 cli_api_configured;
93 create_msg_t *next_create_msg;
100 #define IGMP_CONFIG_FLAG_QUERY_RESP_RECVED (1 << 0)
101 #define IGMP_CONFIG_FLAG_CAN_SEND_REPORT (1 << 1)
103 uword *igmp_sg_by_key;
105 /* pool of (S,G)s per interface */
109 struct igmp_timer_t_;
111 typedef struct igmp_timer_t_ igmp_timer_t;
113 typedef struct igmp_api_client_t_
128 igmp_membership_group_v3_type_t type;
129 } igmp_report_type_info_t;
131 typedef struct igmp_main_t_
133 /** API message ID base */
136 /* get api client by client_index */
137 uword *igmp_api_client_by_client_index;
139 /** pool of api clients registered for join/leave notifications */
140 igmp_api_client_t *api_clients;
142 /* get config index by config key */
143 uword *igmp_config_by_sw_if_index;
145 /** pool of igmp configurations */
146 igmp_config_t *configs;
151 /* next report/deletion */
152 igmp_index_t next_index;
154 /** pool of igmp timers */
155 igmp_timer_t *timers;
157 igmp_type_info_t *type_infos;
158 igmp_report_type_info_t *report_type_infos;
160 uword *type_info_by_type;
161 uword *report_type_info_by_report_type;
165 extern igmp_main_t igmp_main;
167 typedef void (igmp_timer_function_t) (vlib_main_t * vm,
168 vlib_node_runtime_t * rt,
169 igmp_main_t * im, igmp_timer_t * timer);
171 typedef struct igmp_timer_t_
174 igmp_timer_function_t *func;
180 extern vlib_node_registration_t igmp_timer_process_node;
181 extern vlib_node_registration_t igmp_input_node;
182 extern vlib_node_registration_t igmp_parse_query_node;
183 extern vlib_node_registration_t igmp_parse_report_node;
185 int igmp_listen (vlib_main_t * vm, u8 enable, u32 sw_if_index,
186 ip46_address_t saddr, ip46_address_t gaddr,
187 u8 cli_api_configured);
189 void igmp_clear_config (igmp_config_t * config);
191 void igmp_sort_timers (igmp_timer_t * timers);
193 void igmp_create_int_timer (f64 time, u32 sw_if_index,
194 igmp_timer_function_t * func);
195 void igmp_create_sg_timer (f64 time, u32 sw_if_index, igmp_sg_key_t * key,
196 igmp_timer_function_t * func);
198 void igmp_send_query (vlib_main_t * vm, vlib_node_runtime_t * rt,
199 igmp_main_t * im, igmp_timer_t * timer);
200 void igmp_query_resp_exp (vlib_main_t * vm, vlib_node_runtime_t * rt,
201 igmp_main_t * im, igmp_timer_t * timer);
202 void igmp_send_report (vlib_main_t * vm, vlib_node_runtime_t * rt,
203 igmp_main_t * im, igmp_timer_t * timer);
204 void igmp_send_state_changed (vlib_main_t * vm, vlib_node_runtime_t * rt,
205 igmp_main_t * im, igmp_timer_t * timer);
206 void igmp_sg_exp (vlib_main_t * vm, vlib_node_runtime_t * rt,
207 igmp_main_t * im, igmp_timer_t * timer);
209 static inline igmp_type_info_t *
210 igmp_get_type_info (igmp_main_t * im, u32 type)
214 p = hash_get (im->type_info_by_type, type);
215 return p ? vec_elt_at_index (im->type_infos, p[0]) : 0;
218 static inline igmp_report_type_info_t *
219 igmp_get_report_type_info (igmp_main_t * im, u8 report_type)
223 p = hash_get (im->report_type_info_by_report_type, report_type);
224 return p ? vec_elt_at_index (im->report_type_infos, p[0]) : 0;
227 void igmp_event (igmp_main_t * im, igmp_config_t * config, igmp_sg_t * sg);
231 IGMP_NEXT_IP4_REWRITE_MCAST_NODE,
232 IGMP_NEXT_IP6_REWRITE_MCAST_NODE,
237 always_inline igmp_config_t *
238 igmp_config_lookup (igmp_main_t * im, u32 sw_if_index)
241 igmp_config_t *config = NULL;
243 p = hash_get_mem (im->igmp_config_by_sw_if_index, &sw_if_index);
245 config = vec_elt_at_index (im->configs, p[0]);
250 always_inline igmp_sg_t *
251 igmp_sg_lookup (igmp_config_t * config, igmp_sg_key_t * key)
254 igmp_sg_t *sg = NULL;
258 p = hash_get_mem (config->igmp_sg_by_key, key);
260 sg = vec_elt_at_index (config->sg, p[0]);
265 always_inline igmp_api_client_t *
266 igmp_api_client_lookup (igmp_main_t * im, u32 client_index)
269 igmp_api_client_t *api_client = NULL;
271 p = hash_get_mem (im->igmp_api_client_by_client_index, &client_index);
273 api_client = vec_elt_at_index (im->api_clients, p[0]);
278 #endif /* _IGMP_H_ */
281 * fd.io coding-style-patch-verification: ON
284 * eval: (c-set-style "gnu")