IGMP: improve CLI debug output
[vpp.git] / src / plugins / igmp / igmp_group.h
1 /*
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:
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_GROUP_H__
19 #define __IGMP_GROUP_H__
20
21 #include <igmp/igmp_types.h>
22 #include <igmp/igmp_src.h>
23
24 /**
25  * QUERY_REPLY = Timer running to reply to a G/SG specific query
26  * QUERY_SENT  = wait for response from a sent G/SG specific query.
27  *               Sent when a host leaves a group
28  * RESEND_REPORT = Timer running to resend report
29  * FILTER_MODE_CHANGE = to check if the group can swap to
30  *                      INCLUDE mode (section 6.2.2)
31  */
32 #define foreach_igmp_group_timer                \
33   _(QUERY_REPLY, "query-reply")                 \
34   _(QUERY_SENT,  "query-sent")                  \
35   _(RESEND_REPORT, "resend-report")             \
36   _(FILTER_MODE_CHANGE, "filter-mode-change")
37
38 /**
39  * Types of timers maintained for each group
40  */
41 typedef enum igmp_group_timer_type_t_
42 {
43 #define _(v,s) IGMP_GROUP_TIMER_##v,
44   foreach_igmp_group_timer
45 #undef _
46 } igmp_group_timer_type_t;
47
48 #define IGMP_GROUP_N_TIMERS (IGMP_GROUP_TIMER_FILTER_MODE_CHANGE + 1)
49
50 extern u8 *format_igmp_group_timer_type (u8 * s, va_list * args);
51
52 /**
53  * @brief IGMP group
54  *  A multicast group address for which reception has been requested.
55  */
56 typedef struct igmp_group_t_
57 {
58   /** The group's key within the per-interface config */
59   igmp_key_t *key;
60
61   /**
62    * A vector of running timers for the group. this can include:
63    *  - group-specific query, sent on reception of a host 'leave'
64    *  - filter-mode change timer, to check if the group can swap to
65    *      INCLUDE mode (section 6.2.2)
66    */
67   u32 timers[IGMP_GROUP_N_TIMERS];
68
69   /**
70    * The current filter mode of the group (see 6.2.1)
71    */
72   igmp_filter_mode_t router_filter_mode;
73
74   /**
75    * The pool index of the config object this group is in
76    */
77   u32 config;
78
79   /**
80    * The number of times the last report has been sent
81    */
82   u32 n_reports_sent;
83
84   /**
85    * Source list per-filter mode
86    */
87   uword *igmp_src_by_key[IGMP_N_FILTER_MODES];
88 } igmp_group_t;
89
90 #define FOR_EACH_SRC(_src, _group, _filter, _body)                       \
91 do {                                                                    \
92   igmp_key_t *__key__;                                                  \
93   u32 __sid__;                                                          \
94   hash_foreach_mem(__key__, __sid__, ((igmp_group_t*)_group)->igmp_src_by_key[(_filter)], \
95   ({                                                                    \
96     _src = pool_elt_at_index(igmp_main.srcs, __sid__);                  \
97     do { _body; } while (0);                                            \
98   }));                                                                  \
99  } while (0);
100
101 /**
102  * Forward declarations
103  */
104 struct igmp_config_t_;
105
106 extern void igmp_group_clear (igmp_group_t * group);
107 extern void igmp_group_free_all_srcs (igmp_group_t * group);
108
109 extern igmp_group_t *igmp_group_alloc (struct igmp_config_t_ *config,
110                                        const igmp_key_t * gkey,
111                                        igmp_filter_mode_t mode);
112
113 extern igmp_src_t *igmp_group_src_update (igmp_group_t * group,
114                                           const igmp_key_t * skey,
115                                           igmp_mode_t mode);
116
117 extern void igmp_group_src_remove (igmp_group_t * group, igmp_src_t * src);
118 extern u8 *format_igmp_group (u8 * s, va_list * args);
119
120
121 extern ip46_address_t *igmp_group_present_minus_new (igmp_group_t * group,
122                                                      igmp_filter_mode_t mode,
123                                                      const ip46_address_t *
124                                                      saddrs);
125
126 extern ip46_address_t *igmp_group_new_minus_present (igmp_group_t * group,
127                                                      igmp_filter_mode_t mode,
128                                                      const ip46_address_t *
129                                                      saddrs);
130
131 extern ip46_address_t *igmp_group_new_intersect_present (igmp_group_t * group,
132                                                          igmp_filter_mode_t
133                                                          mode,
134                                                          const ip46_address_t
135                                                          * saddrs);
136
137 extern u32 igmp_group_n_srcs (const igmp_group_t * group,
138                               igmp_filter_mode_t mode);
139
140
141 /** \brief igmp group lookup
142     @param group - igmp group
143     @param key - igmp key
144 */
145 extern igmp_src_t *igmp_src_lookup (igmp_group_t * group,
146                                     const igmp_key_t * key);
147
148 extern u32 igmp_group_index (const igmp_group_t * g);
149 extern igmp_group_t *igmp_group_get (u32 index);
150
151 #endif
152
153 /*
154  * fd.io coding-style-patch-verification: ON
155  *
156  * Local Variables:
157  * eval: (c-set-style "gnu")
158  * End:
159  */