]>
Commit | Line | Data |
---|---|---|
1 | // SPDX-License-Identifier: GPL-2.0-or-later | |
2 | /* | |
3 | * PIM for Quagga | |
4 | * Copyright (C) 2008 Everton da Silva Marques | |
5 | */ | |
6 | ||
7 | #ifndef PIM_IFACE_H | |
8 | #define PIM_IFACE_H | |
9 | ||
10 | #include <zebra.h> | |
11 | ||
12 | #include "if.h" | |
13 | #include "vty.h" | |
14 | #include "vrf.h" | |
15 | #include "zclient.h" | |
16 | #include "ferr.h" | |
17 | ||
18 | #include "pim_igmp.h" | |
19 | #include "pim_upstream.h" | |
20 | #include "bfd.h" | |
21 | #include "pim_str.h" | |
22 | ||
23 | #define PIM_IF_IS_DELETED(ifp) ((ifp)->ifindex == IFINDEX_INTERNAL) | |
24 | ||
25 | #define PIM_I_am_DR(pim_ifp) \ | |
26 | !pim_addr_cmp((pim_ifp)->pim_dr_addr, (pim_ifp)->primary_address) | |
27 | #define PIM_I_am_DualActive(pim_ifp) (pim_ifp)->activeactive == true | |
28 | ||
29 | /* Macros for interface flags */ | |
30 | ||
31 | /* | |
32 | * PIM needs to know if hello is required to send before other PIM messages | |
33 | * like Join, prune, assert would go out | |
34 | */ | |
35 | #define PIM_IF_FLAG_HELLO_SENT (1 << 0) | |
36 | ||
37 | #define PIM_IF_FLAG_TEST_HELLO_SENT(flags) ((flags)&PIM_IF_FLAG_HELLO_SENT) | |
38 | ||
39 | #define PIM_IF_FLAG_SET_HELLO_SENT(flags) ((flags) |= PIM_IF_FLAG_HELLO_SENT) | |
40 | ||
41 | #define PIM_IF_FLAG_UNSET_HELLO_SENT(flags) ((flags) &= ~PIM_IF_FLAG_HELLO_SENT) | |
42 | ||
43 | struct pim_iface_upstream_switch { | |
44 | pim_addr address; | |
45 | struct list *us; | |
46 | }; | |
47 | ||
48 | enum pim_secondary_addr_flags { | |
49 | PIM_SEC_ADDRF_NONE = 0, | |
50 | PIM_SEC_ADDRF_STALE = (1 << 0) | |
51 | }; | |
52 | ||
53 | struct pim_secondary_addr { | |
54 | struct prefix addr; | |
55 | enum pim_secondary_addr_flags flags; | |
56 | }; | |
57 | ||
58 | struct gm_if; | |
59 | ||
60 | struct pim_interface { | |
61 | bool pim_enable : 1; | |
62 | bool pim_can_disable_join_suppression : 1; | |
63 | bool pim_passive_enable : 1; | |
64 | ||
65 | bool gm_enable : 1; | |
66 | ||
67 | ifindex_t mroute_vif_index; | |
68 | struct pim_instance *pim; | |
69 | ||
70 | #if PIM_IPV == 6 | |
71 | /* link-locals: MLD uses lowest addr, PIM uses highest... */ | |
72 | pim_addr ll_lowest; | |
73 | pim_addr ll_highest; | |
74 | #endif | |
75 | ||
76 | pim_addr primary_address; /* remember addr to detect change */ | |
77 | struct list *sec_addr_list; /* list of struct pim_secondary_addr */ | |
78 | pim_addr update_source; /* user can statically set the primary | |
79 | * address of the interface */ | |
80 | ||
81 | int igmp_version; /* IGMP version */ | |
82 | int mld_version; | |
83 | int gm_default_robustness_variable; /* IGMP or MLD QRV */ | |
84 | int gm_default_query_interval; /* IGMP or MLD secs between general | |
85 | queries */ | |
86 | int gm_query_max_response_time_dsec; /* IGMP or MLD Max Response Time in | |
87 | dsecs for general queries */ | |
88 | int gm_specific_query_max_response_time_dsec; /* IGMP or MLD Max | |
89 | Response Time in dsecs | |
90 | called as last member | |
91 | query interval, defines | |
92 | the maximum response | |
93 | time advertised in IGMP | |
94 | group-specific | |
95 | queries */ | |
96 | int gm_last_member_query_count; /* IGMP or MLD last member | |
97 | query count | |
98 | */ | |
99 | struct list *gm_socket_list; /* list of struct IGMP or MLD sock */ | |
100 | struct list *gm_join_list; /* list of struct IGMP or MLD join */ | |
101 | struct list *gm_group_list; /* list of struct IGMP or MLD group */ | |
102 | struct hash *gm_group_hash; | |
103 | ||
104 | struct gm_if *mld; | |
105 | ||
106 | int pim_sock_fd; /* PIM socket file descriptor */ | |
107 | struct event *t_pim_sock_read; /* thread for reading PIM socket */ | |
108 | int64_t pim_sock_creation; /* timestamp of PIM socket creation */ | |
109 | ||
110 | struct event *t_pim_hello_timer; | |
111 | int pim_hello_period; | |
112 | int pim_default_holdtime; | |
113 | int pim_triggered_hello_delay; | |
114 | uint32_t pim_generation_id; | |
115 | uint16_t pim_propagation_delay_msec; /* config */ | |
116 | uint16_t pim_override_interval_msec; /* config */ | |
117 | struct list *pim_neighbor_list; /* list of struct pim_neighbor */ | |
118 | struct list *upstream_switch_list; | |
119 | struct pim_ifchannel_rb ifchannel_rb; | |
120 | ||
121 | /* neighbors without lan_delay */ | |
122 | int pim_number_of_nonlandelay_neighbors; | |
123 | uint16_t pim_neighbors_highest_propagation_delay_msec; | |
124 | uint16_t pim_neighbors_highest_override_interval_msec; | |
125 | ||
126 | /* DR Election */ | |
127 | int64_t pim_dr_election_last; /* timestamp */ | |
128 | int pim_dr_election_count; | |
129 | int pim_dr_election_changes; | |
130 | pim_addr pim_dr_addr; | |
131 | uint32_t pim_dr_priority; /* config */ | |
132 | int pim_dr_num_nondrpri_neighbors; /* neighbors without dr_pri */ | |
133 | ||
134 | /* boundary prefix-list */ | |
135 | char *boundary_oil_plist; | |
136 | ||
137 | /* Turn on Active-Active for this interface */ | |
138 | bool activeactive; | |
139 | bool am_i_dr; | |
140 | ||
141 | int64_t pim_ifstat_start; /* start timestamp for stats */ | |
142 | uint64_t pim_ifstat_bsm_rx; | |
143 | uint64_t pim_ifstat_bsm_tx; | |
144 | uint32_t pim_ifstat_hello_sent; | |
145 | uint32_t pim_ifstat_hello_sendfail; | |
146 | uint32_t pim_ifstat_hello_recv; | |
147 | uint32_t pim_ifstat_hello_recvfail; | |
148 | uint32_t pim_ifstat_join_recv; | |
149 | uint32_t pim_ifstat_join_send; | |
150 | uint32_t pim_ifstat_prune_recv; | |
151 | uint32_t pim_ifstat_prune_send; | |
152 | uint32_t pim_ifstat_reg_recv; | |
153 | uint32_t pim_ifstat_reg_send; | |
154 | uint32_t pim_ifstat_reg_stop_recv; | |
155 | uint32_t pim_ifstat_reg_stop_send; | |
156 | uint32_t pim_ifstat_assert_recv; | |
157 | uint32_t pim_ifstat_assert_send; | |
158 | uint32_t pim_ifstat_bsm_cfg_miss; | |
159 | uint32_t pim_ifstat_ucast_bsm_cfg_miss; | |
160 | uint32_t pim_ifstat_bsm_invalid_sz; | |
161 | uint8_t flags; | |
162 | bool bsm_enable; /* bsm processing enable */ | |
163 | bool ucast_bsm_accept; /* ucast bsm processing */ | |
164 | ||
165 | uint32_t igmp_ifstat_joins_sent; | |
166 | uint32_t igmp_ifstat_joins_failed; | |
167 | uint32_t igmp_peak_group_count; | |
168 | ||
169 | struct { | |
170 | bool enabled; | |
171 | uint32_t min_rx; | |
172 | uint32_t min_tx; | |
173 | uint8_t detection_multiplier; | |
174 | char *profile; | |
175 | } bfd_config; | |
176 | }; | |
177 | ||
178 | /* | |
179 | * if default_holdtime is set (>= 0), use it; | |
180 | * otherwise default_holdtime is 3.5 * hello_period | |
181 | */ | |
182 | #define PIM_IF_DEFAULT_HOLDTIME(pim_ifp) \ | |
183 | (((pim_ifp)->pim_default_holdtime < 0) \ | |
184 | ? ((pim_ifp)->pim_hello_period * 7 / 2) \ | |
185 | : ((pim_ifp)->pim_default_holdtime)) | |
186 | ||
187 | void pim_if_init(struct pim_instance *pim); | |
188 | void pim_if_terminate(struct pim_instance *pim); | |
189 | ||
190 | struct pim_interface *pim_if_new(struct interface *ifp, bool igmp, bool pim, | |
191 | bool ispimreg, bool is_vxlan_term); | |
192 | void pim_if_delete(struct interface *ifp); | |
193 | void pim_if_addr_add(struct connected *ifc); | |
194 | void pim_if_addr_del(struct connected *ifc, int force_prim_as_any); | |
195 | void pim_if_addr_add_all(struct interface *ifp); | |
196 | void pim_if_addr_del_all(struct interface *ifp); | |
197 | void pim_if_addr_del_all_igmp(struct interface *ifp); | |
198 | ||
199 | int pim_if_add_vif(struct interface *ifp, bool ispimreg, bool is_vxlan_term); | |
200 | int pim_if_del_vif(struct interface *ifp); | |
201 | void pim_if_add_vif_all(struct pim_instance *pim); | |
202 | void pim_if_del_vif_all(struct pim_instance *pim); | |
203 | ||
204 | struct interface *pim_if_find_by_vif_index(struct pim_instance *pim, | |
205 | ifindex_t vif_index); | |
206 | int pim_if_find_vifindex_by_ifindex(struct pim_instance *pim, | |
207 | ifindex_t ifindex); | |
208 | ||
209 | int pim_if_lan_delay_enabled(struct interface *ifp); | |
210 | uint16_t pim_if_effective_propagation_delay_msec(struct interface *ifp); | |
211 | uint16_t pim_if_effective_override_interval_msec(struct interface *ifp); | |
212 | uint16_t pim_if_jp_override_interval_msec(struct interface *ifp); | |
213 | struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp, pim_addr addr); | |
214 | ||
215 | long pim_if_t_suppressed_msec(struct interface *ifp); | |
216 | int pim_if_t_override_msec(struct interface *ifp); | |
217 | ||
218 | pim_addr pim_find_primary_addr(struct interface *ifp); | |
219 | ||
220 | ferr_r pim_if_gm_join_add(struct interface *ifp, pim_addr group_addr, | |
221 | pim_addr source_addr); | |
222 | int pim_if_gm_join_del(struct interface *ifp, pim_addr group_addr, | |
223 | pim_addr source_addr); | |
224 | ||
225 | void pim_if_update_could_assert(struct interface *ifp); | |
226 | ||
227 | void pim_if_assert_on_neighbor_down(struct interface *ifp, pim_addr neigh_addr); | |
228 | ||
229 | void pim_if_rpf_interface_changed(struct interface *old_rpf_ifp, | |
230 | struct pim_upstream *up); | |
231 | ||
232 | void pim_if_update_join_desired(struct pim_interface *pim_ifp); | |
233 | ||
234 | void pim_if_update_assert_tracking_desired(struct interface *ifp); | |
235 | ||
236 | void pim_if_create_pimreg(struct pim_instance *pim); | |
237 | ||
238 | struct prefix *pim_if_connected_to_source(struct interface *ifp, pim_addr src); | |
239 | int pim_update_source_set(struct interface *ifp, pim_addr source); | |
240 | ||
241 | bool pim_if_is_vrf_device(struct interface *ifp); | |
242 | ||
243 | int pim_if_ifchannel_count(struct pim_interface *pim_ifp); | |
244 | ||
245 | void pim_iface_init(void); | |
246 | ||
247 | #endif /* PIM_IFACE_H */ |