IGMP plugin
[vpp.git] / src / plugins / igmp / igmp.h
1 /*
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:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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  *------------------------------------------------------------------
16  */
17
18 #ifndef _IGMP_H_
19 #define _IGMP_H_
20
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>
26
27 #define IGMP_QUERY_TIMER                        (60)
28 #define IGMP_SG_TIMER                           (3 * IGMP_QUERY_TIMER)
29 #define IGMP_DEFAULT_ROBUSTNESS_VARIABLE        (2)
30
31 #define IGMP_DBG 1
32
33 #if IGMP_DBG
34 #define DBG(...) clib_warning(__VA_ARGS__)
35 #else
36 #define DBG(...)
37 #endif /* IGMP_DBG */
38
39 #define group_ptr(p, l) ((igmp_membership_group_v3_t *)((void*)p + l))
40
41 enum
42 {
43   IGMP_PROCESS_EVENT_UPDATE_TIMER = 1,
44 } igmp_process_event_t;
45
46 typedef enum
47 {
48   IGMP_V1,
49   IGMP_V2,
50   IGMP_V3,
51 } igmp_ver_t;
52
53 struct igmp_config_t_;
54
55 typedef struct igmp_config_t_ igmp_config_t;
56
57 /* populate supplied bufefr with IGMP message */
58 typedef void (create_msg_t) (vlib_buffer_t * b, igmp_config_t * config);
59
60 typedef struct igmp_index_t_
61 {
62   u32 config_index;
63   u32 sg_index;
64 } igmp_index_t;
65
66 typedef struct igmp_sg_key_t_
67 {
68   ip46_address_t gaddr;
69   ip46_address_t saddr;
70 } igmp_sg_key_t;
71
72 typedef struct igmp_sg_t_
73 {
74   ip46_address_t gaddr;
75   ip46_address_t saddr;
76
77   igmp_membership_group_v3_type_t group_type;
78
79   /* check if expired (S,G) timer is valid */
80   f64 exp_time;
81
82   igmp_sg_key_t *key;
83 } igmp_sg_t;
84
85 typedef struct igmp_config_t_
86 {
87   u32 sw_if_index;
88
89   adj_index_t adj_index;
90
91   u8 cli_api_configured;
92
93   create_msg_t *next_create_msg;
94
95   igmp_ver_t igmp_ver;
96
97   u8 robustness_var;
98
99   u8 flags;
100 #define IGMP_CONFIG_FLAG_QUERY_RESP_RECVED      (1 << 0)
101 #define IGMP_CONFIG_FLAG_CAN_SEND_REPORT        (1 << 1)
102
103   uword *igmp_sg_by_key;
104
105   /* pool of (S,G)s per interface */
106   igmp_sg_t *sg;
107 } igmp_config_t;
108
109 struct igmp_timer_t_;
110
111 typedef struct igmp_timer_t_ igmp_timer_t;
112
113 typedef struct igmp_api_client_t_
114 {
115   u32 client_index;
116   u32 pid;
117 } igmp_api_client_t;
118
119 typedef struct
120 {
121   u8 *name;
122   igmp_type_t type;
123 } igmp_type_info_t;
124
125 typedef struct
126 {
127   u8 *name;
128   igmp_membership_group_v3_type_t type;
129 } igmp_report_type_info_t;
130
131 typedef struct igmp_main_t_
132 {
133   /** API message ID base */
134   u16 msg_id_base;
135
136   /* get api client by client_index */
137   uword *igmp_api_client_by_client_index;
138
139   /** pool of api clients registered for join/leave notifications */
140   igmp_api_client_t *api_clients;
141
142   /* get config index by config key */
143   uword *igmp_config_by_sw_if_index;
144
145   /** pool of igmp configurations */
146   igmp_config_t *configs;
147
148   /** buffer cache */
149   u32 **buffers;
150
151   /* next report/deletion */
152   igmp_index_t next_index;
153
154   /** pool of igmp timers */
155   igmp_timer_t *timers;
156
157   igmp_type_info_t *type_infos;
158   igmp_report_type_info_t *report_type_infos;
159
160   uword *type_info_by_type;
161   uword *report_type_info_by_report_type;
162
163 } igmp_main_t;
164
165 extern igmp_main_t igmp_main;
166
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);
170
171 typedef struct igmp_timer_t_
172 {
173   f64 exp_time;
174   igmp_timer_function_t *func;
175
176   u32 sw_if_index;
177   void *data;
178 } igmp_timer_t;
179
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;
184
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);
188
189 void igmp_clear_config (igmp_config_t * config);
190
191 void igmp_sort_timers (igmp_timer_t * timers);
192
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);
197
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);
208
209 static inline igmp_type_info_t *
210 igmp_get_type_info (igmp_main_t * im, u32 type)
211 {
212   uword *p;
213
214   p = hash_get (im->type_info_by_type, type);
215   return p ? vec_elt_at_index (im->type_infos, p[0]) : 0;
216 }
217
218 static inline igmp_report_type_info_t *
219 igmp_get_report_type_info (igmp_main_t * im, u8 report_type)
220 {
221   uword *p;
222
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;
225 }
226
227 void igmp_event (igmp_main_t * im, igmp_config_t * config, igmp_sg_t * sg);
228
229 typedef enum
230 {
231   IGMP_NEXT_IP4_REWRITE_MCAST_NODE,
232   IGMP_NEXT_IP6_REWRITE_MCAST_NODE,
233   IGMP_N_NEXT,
234 } igmp_next_t;
235
236
237 always_inline igmp_config_t *
238 igmp_config_lookup (igmp_main_t * im, u32 sw_if_index)
239 {
240   uword *p;
241   igmp_config_t *config = NULL;
242
243   p = hash_get_mem (im->igmp_config_by_sw_if_index, &sw_if_index);
244   if (p)
245     config = vec_elt_at_index (im->configs, p[0]);
246
247   return config;
248 }
249
250 always_inline igmp_sg_t *
251 igmp_sg_lookup (igmp_config_t * config, igmp_sg_key_t * key)
252 {
253   uword *p;
254   igmp_sg_t *sg = NULL;
255   if (!config)
256     return NULL;
257
258   p = hash_get_mem (config->igmp_sg_by_key, key);
259   if (p)
260     sg = vec_elt_at_index (config->sg, p[0]);
261
262   return sg;
263 }
264
265 always_inline igmp_api_client_t *
266 igmp_api_client_lookup (igmp_main_t * im, u32 client_index)
267 {
268   uword *p;
269   igmp_api_client_t *api_client = NULL;
270
271   p = hash_get_mem (im->igmp_api_client_by_client_index, &client_index);
272   if (p)
273     api_client = vec_elt_at_index (im->api_clients, p[0]);
274
275   return api_client;
276 }
277
278 #endif /* _IGMP_H_ */
279
280 /*
281  * fd.io coding-style-patch-verification: ON
282  *
283  * Local Variables:
284  * eval: (c-set-style "gnu")
285  * End:
286  */