]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * PIM for Quagga | |
3 | * Copyright (C) 2008 Everton da Silva Marques | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation; either version 2 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, but | |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | * General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License along | |
16 | * with this program; see the file COPYING; if not, write to the Free Software | |
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
18 | */ | |
19 | ||
20 | #ifndef PIM_UPSTREAM_H | |
21 | #define PIM_UPSTREAM_H | |
22 | ||
23 | #include <zebra.h> | |
24 | #include <prefix.h> | |
25 | #include "plist.h" | |
26 | ||
27 | #include <pimd/pim_rpf.h> | |
28 | #include "pim_str.h" | |
29 | #include "pim_ifchannel.h" | |
30 | ||
31 | #define PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED (1 << 0) | |
32 | #define PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED (1 << 1) | |
33 | #define PIM_UPSTREAM_FLAG_MASK_FHR (1 << 2) | |
34 | #define PIM_UPSTREAM_FLAG_MASK_SRC_IGMP (1 << 3) | |
35 | #define PIM_UPSTREAM_FLAG_MASK_SRC_PIM (1 << 4) | |
36 | #define PIM_UPSTREAM_FLAG_MASK_SRC_STREAM (1 << 5) | |
37 | #define PIM_UPSTREAM_FLAG_MASK_SRC_MSDP (1 << 6) | |
38 | #define PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE (1 << 7) | |
39 | #define PIM_UPSTREAM_FLAG_MASK_SRC_LHR (1 << 8) | |
40 | #define PIM_UPSTREAM_FLAG_ALL 0xFFFFFFFF | |
41 | ||
42 | #define PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED) | |
43 | #define PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED_UPDATED(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED) | |
44 | #define PIM_UPSTREAM_FLAG_TEST_FHR(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_FHR) | |
45 | #define PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) | |
46 | #define PIM_UPSTREAM_FLAG_TEST_SRC_PIM(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SRC_PIM) | |
47 | #define PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM) | |
48 | #define PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP) | |
49 | #define PIM_UPSTREAM_FLAG_TEST_SEND_SG_RPT_PRUNE(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE) | |
50 | #define PIM_UPSTREAM_FLAG_TEST_SRC_LHR(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_SRC_LHR) | |
51 | ||
52 | #define PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED) | |
53 | #define PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED_UPDATED(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED) | |
54 | #define PIM_UPSTREAM_FLAG_SET_FHR(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_FHR) | |
55 | #define PIM_UPSTREAM_FLAG_SET_SRC_IGMP(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) | |
56 | #define PIM_UPSTREAM_FLAG_SET_SRC_PIM(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SRC_PIM) | |
57 | #define PIM_UPSTREAM_FLAG_SET_SRC_STREAM(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SRC_STREAM) | |
58 | #define PIM_UPSTREAM_FLAG_SET_SRC_MSDP(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SRC_MSDP) | |
59 | #define PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE) | |
60 | #define PIM_UPSTREAM_FLAG_SET_SRC_LHR(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SRC_LHR) | |
61 | ||
62 | #define PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED) | |
63 | #define PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED_UPDATED(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED) | |
64 | #define PIM_UPSTREAM_FLAG_UNSET_FHR(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_FHR) | |
65 | #define PIM_UPSTREAM_FLAG_UNSET_SRC_IGMP(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) | |
66 | #define PIM_UPSTREAM_FLAG_UNSET_SRC_PIM(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_PIM) | |
67 | #define PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_STREAM) | |
68 | #define PIM_UPSTREAM_FLAG_UNSET_SRC_MSDP(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_MSDP) | |
69 | #define PIM_UPSTREAM_FLAG_UNSET_SEND_SG_RPT_PRUNE(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE) | |
70 | #define PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_LHR) | |
71 | ||
72 | enum pim_upstream_state { | |
73 | PIM_UPSTREAM_NOTJOINED, | |
74 | PIM_UPSTREAM_JOINED, | |
75 | }; | |
76 | ||
77 | enum pim_reg_state { | |
78 | PIM_REG_NOINFO, | |
79 | PIM_REG_JOIN, | |
80 | PIM_REG_JOIN_PENDING, | |
81 | PIM_REG_PRUNE, | |
82 | }; | |
83 | ||
84 | enum pim_upstream_sptbit { | |
85 | PIM_UPSTREAM_SPTBIT_FALSE, | |
86 | PIM_UPSTREAM_SPTBIT_TRUE | |
87 | }; | |
88 | ||
89 | /* | |
90 | Upstream (S,G) channel in Joined state | |
91 | ||
92 | (S,G) in the "Not Joined" state is not represented | |
93 | ||
94 | See RFC 4601: 4.5.7. Sending (S,G) Join/Prune Message | |
95 | */ | |
96 | struct pim_upstream { | |
97 | struct pim_upstream *parent; | |
98 | struct in_addr upstream_addr; /* Who we are talking to */ | |
99 | struct in_addr upstream_register; /*Who we received a register from*/ | |
100 | struct prefix_sg sg; /* (S,G) group key */ | |
101 | char sg_str[PIM_SG_LEN]; | |
102 | uint32_t flags; | |
103 | struct channel_oil *channel_oil; | |
104 | struct list *sources; | |
105 | struct list *ifchannels; | |
106 | ||
107 | enum pim_upstream_state join_state; | |
108 | enum pim_reg_state reg_state; | |
109 | enum pim_upstream_sptbit sptbit; | |
110 | ||
111 | int ref_count; | |
112 | ||
113 | struct pim_rpf rpf; | |
114 | ||
115 | struct thread *t_join_timer; | |
116 | ||
117 | /* | |
118 | * RST(S,G) | |
119 | */ | |
120 | struct thread *t_rs_timer; | |
121 | #define PIM_REGISTER_SUPPRESSION_PERIOD (60) | |
122 | #define PIM_REGISTER_PROBE_PERIOD (5) | |
123 | ||
124 | /* | |
125 | * KAT(S,G) | |
126 | */ | |
127 | struct thread *t_ka_timer; | |
128 | #define PIM_KEEPALIVE_PERIOD (210) | |
129 | #define PIM_RP_KEEPALIVE_PERIOD ( 3 * qpim_register_suppress_time + qpim_register_probe_time ) | |
130 | ||
131 | /* on the RP we restart a timer to indicate if registers are being rxed | |
132 | * for | |
133 | * SG. This is needed by MSDP to determine its local SA cache */ | |
134 | struct thread *t_msdp_reg_timer; | |
135 | #define PIM_MSDP_REG_RXED_PERIOD (3 * (1.5 * qpim_register_suppress_time)) | |
136 | ||
137 | int64_t state_transition; /* Record current state uptime */ | |
138 | }; | |
139 | ||
140 | struct pim_upstream *pim_upstream_find(struct pim_instance *pim, | |
141 | struct prefix_sg *sg); | |
142 | struct pim_upstream *pim_upstream_find_or_add(struct prefix_sg *sg, | |
143 | struct interface *ifp, int flags, | |
144 | const char *name); | |
145 | struct pim_upstream *pim_upstream_add(struct pim_instance *pim, | |
146 | struct prefix_sg *sg, | |
147 | struct interface *ifp, int flags, | |
148 | const char *name, | |
149 | struct pim_ifchannel *ch); | |
150 | void pim_upstream_ref(struct pim_upstream *up, int flags, const char *name); | |
151 | struct pim_upstream *pim_upstream_del(struct pim_instance *pim, | |
152 | struct pim_upstream *up, | |
153 | const char *name); | |
154 | ||
155 | int pim_upstream_evaluate_join_desired(struct pim_instance *pim, | |
156 | struct pim_upstream *up); | |
157 | int pim_upstream_evaluate_join_desired_interface(struct pim_upstream *up, | |
158 | struct pim_ifchannel *ch, | |
159 | struct pim_ifchannel *starch); | |
160 | void pim_upstream_update_join_desired(struct pim_instance *pim, | |
161 | struct pim_upstream *up); | |
162 | ||
163 | void pim_upstream_join_suppress(struct pim_upstream *up, | |
164 | struct in_addr rpf_addr, int holdtime); | |
165 | ||
166 | void pim_upstream_join_timer_decrease_to_t_override(const char *debug_label, | |
167 | struct pim_upstream *up); | |
168 | ||
169 | void pim_upstream_join_timer_restart(struct pim_upstream *up, | |
170 | struct pim_rpf *old); | |
171 | void pim_upstream_rpf_genid_changed(struct pim_instance *pim, | |
172 | struct in_addr neigh_addr); | |
173 | void pim_upstream_rpf_interface_changed(struct pim_upstream *up, | |
174 | struct interface *old_rpf_ifp); | |
175 | ||
176 | void pim_upstream_update_could_assert(struct pim_upstream *up); | |
177 | void pim_upstream_update_my_assert_metric(struct pim_upstream *up); | |
178 | ||
179 | void pim_upstream_keep_alive_timer_start(struct pim_upstream *up, | |
180 | uint32_t time); | |
181 | ||
182 | int pim_upstream_switch_to_spt_desired(struct pim_instance *pim, | |
183 | struct prefix_sg *sg); | |
184 | #define SwitchToSptDesired(pim, sg) pim_upstream_switch_to_spt_desired (pim, sg) | |
185 | int pim_upstream_is_sg_rpt(struct pim_upstream *up); | |
186 | ||
187 | void pim_upstream_set_sptbit(struct pim_upstream *up, | |
188 | struct interface *incoming); | |
189 | ||
190 | void pim_upstream_start_register_stop_timer(struct pim_upstream *up, | |
191 | int null_register); | |
192 | ||
193 | void pim_upstream_send_join(struct pim_upstream *up); | |
194 | ||
195 | void pim_upstream_switch(struct pim_instance *pim, struct pim_upstream *up, | |
196 | enum pim_upstream_state new_state); | |
197 | ||
198 | const char *pim_upstream_state2str(enum pim_upstream_state join_state); | |
199 | #define PIM_REG_STATE_STR_LEN 12 | |
200 | const char *pim_reg_state2str(enum pim_reg_state state, char *state_str); | |
201 | ||
202 | int pim_upstream_inherited_olist_decide(struct pim_instance *pim, | |
203 | struct pim_upstream *up); | |
204 | int pim_upstream_inherited_olist(struct pim_instance *pim, | |
205 | struct pim_upstream *up); | |
206 | int pim_upstream_empty_inherited_olist(struct pim_upstream *up); | |
207 | ||
208 | void pim_upstream_find_new_rpf(struct pim_instance *pim); | |
209 | void pim_upstream_msdp_reg_timer_start(struct pim_upstream *up); | |
210 | ||
211 | void pim_upstream_init(struct pim_instance *pim); | |
212 | void pim_upstream_terminate(struct pim_instance *pim); | |
213 | ||
214 | void join_timer_start(struct pim_upstream *up); | |
215 | int pim_upstream_compare(void *arg1, void *arg2); | |
216 | void pim_upstream_register_reevaluate(struct pim_instance *pim); | |
217 | ||
218 | void pim_upstream_add_lhr_star_pimreg(struct pim_instance *pim); | |
219 | void pim_upstream_remove_lhr_star_pimreg(struct pim_instance *pim, | |
220 | const char *nlist); | |
221 | ||
222 | void pim_upstream_spt_prefix_list_update(struct pim_instance *pim, | |
223 | struct prefix_list *pl); | |
224 | ||
225 | unsigned int pim_upstream_hash_key(void *arg); | |
226 | bool pim_upstream_equal(const void *arg1, const void *arg2); | |
227 | #endif /* PIM_UPSTREAM_H */ |