]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_igmp.h
Merge pull request #13332 from LabNConsulting/chopps/new-opts
[mirror_frr.git] / pimd / pim_igmp.h
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
12e41d03 2/*
896014f4
DL
3 * PIM for Quagga
4 * Copyright (C) 2008 Everton da Silva Marques
896014f4 5 */
12e41d03
DL
6
7#ifndef PIM_IGMP_H
8#define PIM_IGMP_H
9
10#include <netinet/in.h>
11
12#include <zebra.h>
13#include "vty.h"
14#include "linklist.h"
21313cbf 15#include "pim_igmp_stats.h"
5e8d3f4f 16#include "pim_str.h"
12e41d03
DL
17
18/*
19 The following sizes are likely to support
20 any message sent within local MTU.
21*/
22#define PIM_IGMP_BUFSIZE_READ (20000)
23#define PIM_IGMP_BUFSIZE_WRITE (20000)
24
25#define PIM_IGMP_MEMBERSHIP_QUERY (0x11)
26#define PIM_IGMP_V1_MEMBERSHIP_REPORT (0x12)
27#define PIM_IGMP_V2_MEMBERSHIP_REPORT (0x16)
28#define PIM_IGMP_V2_LEAVE_GROUP (0x17)
4d9ad5dc
MS
29#define PIM_IGMP_MTRACE_RESPONSE (0x1E)
30#define PIM_IGMP_MTRACE_QUERY_REQUEST (0x1F)
12e41d03
DL
31#define PIM_IGMP_V3_MEMBERSHIP_REPORT (0x22)
32
33#define IGMP_V3_REPORT_HEADER_SIZE (8)
34#define IGMP_V3_GROUP_RECORD_MIN_SIZE (8)
d62a17ae 35#define IGMP_V3_MSG_MIN_SIZE \
36 (IGMP_V3_REPORT_HEADER_SIZE + IGMP_V3_GROUP_RECORD_MIN_SIZE)
12e41d03
DL
37#define IGMP_V12_MSG_SIZE (8)
38
39#define IGMP_V3_GROUP_RECORD_TYPE_OFFSET (0)
40#define IGMP_V3_GROUP_RECORD_AUXDATALEN_OFFSET (1)
41#define IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET (2)
42#define IGMP_V3_GROUP_RECORD_GROUP_OFFSET (4)
43#define IGMP_V3_GROUP_RECORD_SOURCE_OFFSET (8)
b05b72e8 44#define IGMP_CHECKSUM_OFFSET (2)
12e41d03 45
b05b72e8
DW
46#define IGMP_DEFAULT_VERSION (3)
47
9041c30a
MR
48#define IGMP_GET_INT16(ptr, output) \
49 do { \
50 output = *(ptr) << 8; \
51 output |= *((ptr) + 1); \
52 } while (0)
53
7caa9451 54struct gm_join {
5e8d3f4f
MR
55 pim_addr group_addr;
56 pim_addr source_addr;
d62a17ae 57 int sock_fd;
58 time_t sock_creation;
12e41d03
DL
59};
60
c5f76fad 61struct gm_sock {
d62a17ae 62 int fd;
63 struct interface *interface;
ca7613e2 64 pim_addr ifaddr;
d62a17ae 65 time_t sock_creation;
66
e6685141
DS
67 struct event *t_igmp_read; /* read: IGMP sockets */
68 /* timer: issue IGMP general queries */
69 struct event *t_igmp_query_timer;
70 struct event *t_other_querier_timer; /* timer: other querier present */
ca7613e2 71 pim_addr querier_addr; /* IP address of the querier */
9a7cee26 72 int querier_query_interval; /* QQI */
d62a17ae 73 int querier_robustness_variable; /* QRV */
74 int startup_query_count;
75
f83f3966
MS
76 bool mtrace_only;
77
f2058cb4 78 struct igmp_stats igmp_stats;
12e41d03
DL
79};
80
dda4d23c
DL
81struct pim_interface;
82
5a46a3de 83#if PIM_IPV == 4
dda4d23c
DL
84void pim_igmp_if_init(struct pim_interface *pim_ifp, struct interface *ifp);
85void pim_igmp_if_reset(struct pim_interface *pim_ifp);
86void pim_igmp_if_fini(struct pim_interface *pim_ifp);
87
c5f76fad
SG
88struct gm_sock *pim_igmp_sock_lookup_ifaddr(struct list *igmp_sock_list,
89 struct in_addr ifaddr);
90struct gm_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
91 struct in_addr ifaddr, struct interface *ifp,
92 bool mtrace_only);
93void igmp_sock_delete(struct gm_sock *igmp);
94void igmp_sock_free(struct gm_sock *igmp);
d62a17ae 95void igmp_sock_delete_all(struct interface *ifp);
c5f76fad 96int pim_igmp_packet(struct gm_sock *igmp, char *buf, size_t len);
88ea79ad 97bool pim_igmp_verify_header(struct ip *ip_hdr, size_t len, size_t *ip_hlen);
c5f76fad
SG
98void pim_igmp_general_query_on(struct gm_sock *igmp);
99void pim_igmp_general_query_off(struct gm_sock *igmp);
100void pim_igmp_other_querier_timer_on(struct gm_sock *igmp);
101void pim_igmp_other_querier_timer_off(struct gm_sock *igmp);
12e41d03 102
9041c30a
MR
103int igmp_validate_checksum(char *igmp_msg, int igmp_msg_len);
104
5a46a3de 105#else /* PIM_IPV != 4 */
97feb13f
DL
106static inline void pim_igmp_if_init(struct pim_interface *pim_ifp,
107 struct interface *ifp)
108{
109}
110
111static inline void pim_igmp_if_fini(struct pim_interface *pim_ifp)
112{
113}
114
5a46a3de
DL
115static inline void pim_igmp_general_query_on(struct gm_sock *igmp)
116{
117}
118
119static inline void pim_igmp_general_query_off(struct gm_sock *igmp)
120{
121}
122
123static inline void pim_igmp_other_querier_timer_on(struct gm_sock *igmp)
124{
125}
126
127static inline void pim_igmp_other_querier_timer_off(struct gm_sock *igmp)
128{
129}
130#endif /* PIM_IPV == 4 */
131
12e41d03
DL
132#define IGMP_SOURCE_MASK_FORWARDING (1 << 0)
133#define IGMP_SOURCE_MASK_DELETE (1 << 1)
134#define IGMP_SOURCE_MASK_SEND (1 << 2)
135#define IGMP_SOURCE_TEST_FORWARDING(flags) ((flags) & IGMP_SOURCE_MASK_FORWARDING)
136#define IGMP_SOURCE_TEST_DELETE(flags) ((flags) & IGMP_SOURCE_MASK_DELETE)
137#define IGMP_SOURCE_TEST_SEND(flags) ((flags) & IGMP_SOURCE_MASK_SEND)
138#define IGMP_SOURCE_DO_FORWARDING(flags) ((flags) |= IGMP_SOURCE_MASK_FORWARDING)
139#define IGMP_SOURCE_DO_DELETE(flags) ((flags) |= IGMP_SOURCE_MASK_DELETE)
140#define IGMP_SOURCE_DO_SEND(flags) ((flags) |= IGMP_SOURCE_MASK_SEND)
141#define IGMP_SOURCE_DONT_FORWARDING(flags) ((flags) &= ~IGMP_SOURCE_MASK_FORWARDING)
142#define IGMP_SOURCE_DONT_DELETE(flags) ((flags) &= ~IGMP_SOURCE_MASK_DELETE)
143#define IGMP_SOURCE_DONT_SEND(flags) ((flags) &= ~IGMP_SOURCE_MASK_SEND)
144
51700107 145struct gm_source {
b050b030 146 pim_addr source_addr;
e6685141 147 struct event *t_source_timer;
a16db099 148 struct gm_group *source_group; /* back pointer */
d62a17ae 149 time_t source_creation;
150 uint32_t source_flags;
151 struct channel_oil *source_channel_oil;
152
153 /*
154 RFC 3376: 6.6.3.2. Building and Sending Group and Source Specific
155 Queries
156 */
157 int source_query_retransmit_count;
12e41d03
DL
158};
159
a16db099 160struct gm_group {
d62a17ae 161 /*
162 RFC 3376: 6.2.2. Definition of Group Timers
163
164 The group timer is only used when a group is in EXCLUDE mode and it
165 represents the time for the *filter-mode* of the group to expire and
166 switch to INCLUDE mode.
167 */
e6685141 168 struct event *t_group_timer;
d62a17ae 169
170 /* Shared between group-specific and
171 group-and-source-specific retransmissions */
e6685141 172 struct event *t_group_query_retransmit_timer;
d62a17ae 173
174 /* Counter exclusive for group-specific retransmissions
175 (not used by group-and-source-specific retransmissions,
176 since sources have their counters) */
177 int group_specific_query_retransmit_count;
178
179 /* compatibility mode - igmp v1, v2 or v3 */
180 int igmp_version;
d1257ae9 181 pim_addr group_addr;
d62a17ae 182 int group_filtermode_isexcl; /* 0=INCLUDE, 1=EXCLUDE */
51700107 183 struct list *group_source_list; /* list of struct gm_source */
d62a17ae 184 time_t group_creation;
dda4d23c 185 struct interface *interface;
d62a17ae 186 int64_t last_igmp_v1_report_dsec;
187 int64_t last_igmp_v2_report_dsec;
12e41d03
DL
188};
189
5a46a3de 190#if PIM_IPV == 4
cd6d2858
DL
191struct pim_instance;
192
193void igmp_anysource_forward_start(struct pim_instance *pim,
194 struct gm_group *group);
195void igmp_anysource_forward_stop(struct gm_group *group);
196
197void igmp_source_forward_start(struct pim_instance *pim,
198 struct gm_source *source);
199void igmp_source_forward_stop(struct gm_source *source);
200void igmp_source_forward_reevaluate_all(struct pim_instance *pim);
201
c5f76fad 202struct gm_group *find_group_by_addr(struct gm_sock *igmp,
a16db099 203 struct in_addr group_addr);
c5f76fad 204struct gm_group *igmp_add_group_by_addr(struct gm_sock *igmp,
a16db099 205 struct in_addr group_addr);
12e41d03 206
a16db099
SG
207struct gm_source *igmp_get_source_by_addr(struct gm_group *group,
208 struct in_addr src_addr,
209 bool *created);
5421bf8f 210
a16db099 211void igmp_group_delete_empty_include(struct gm_group *group);
12e41d03 212
c5f76fad 213void igmp_startup_mode_on(struct gm_sock *igmp);
12e41d03 214
a16db099 215void igmp_group_timer_on(struct gm_group *group, long interval_msec,
d62a17ae 216 const char *ifname);
217
278912ea
DA
218void igmp_send_query(int igmp_version, struct gm_group *group, char *query_buf,
219 int query_buf_size, int num_sources,
220 struct in_addr dst_addr, struct in_addr group_addr,
d62a17ae 221 int query_max_response_time_dsec, uint8_t s_flag,
278912ea 222 struct gm_sock *igmp);
a16db099 223void igmp_group_delete(struct gm_group *group);
6741a5bb 224
225void igmp_send_query_on_intf(struct interface *ifp, int igmp_ver);
5a46a3de
DL
226
227#else /* PIM_IPV != 4 */
228static inline void igmp_startup_mode_on(struct gm_sock *igmp)
229{
230}
231#endif /* PIM_IPV != 4 */
232
12e41d03 233#endif /* PIM_IGMP_H */