File: | home/sharpd/frr3/pimd/pim_upstream.c |
Warning: | line 912, column 4 Value stored to 'rpf_result' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | #include <zebra.h> |
8 | |
9 | #include "log.h" |
10 | #include "zclient.h" |
11 | #include "memory.h" |
12 | #include "frrevent.h" |
13 | #include "linklist.h" |
14 | #include "vty.h" |
15 | #include "plist.h" |
16 | #include "hash.h" |
17 | #include "jhash.h" |
18 | #include "wheel.h" |
19 | #include "network.h" |
20 | #include "frrdistance.h" |
21 | |
22 | #include "pimd.h" |
23 | #include "pim_pim.h" |
24 | #include "pim_str.h" |
25 | #include "pim_time.h" |
26 | #include "pim_iface.h" |
27 | #include "pim_join.h" |
28 | #include "pim_zlookup.h" |
29 | #include "pim_upstream.h" |
30 | #include "pim_ifchannel.h" |
31 | #include "pim_neighbor.h" |
32 | #include "pim_rpf.h" |
33 | #include "pim_zebra.h" |
34 | #include "pim_oil.h" |
35 | #include "pim_macro.h" |
36 | #include "pim_rp.h" |
37 | #include "pim_register.h" |
38 | #include "pim_msdp.h" |
39 | #include "pim_jp_agg.h" |
40 | #include "pim_nht.h" |
41 | #include "pim_ssm.h" |
42 | #include "pim_vxlan.h" |
43 | #include "pim_mlag.h" |
44 | |
45 | static void join_timer_stop(struct pim_upstream *up); |
46 | static void |
47 | pim_upstream_update_assert_tracking_desired(struct pim_upstream *up); |
48 | static bool_Bool pim_upstream_sg_running_proc(struct pim_upstream *up); |
49 | |
50 | /* |
51 | * A (*,G) or a (*,*) is going away |
52 | * remove the parent pointer from |
53 | * those pointing at us |
54 | */ |
55 | static void pim_upstream_remove_children(struct pim_instance *pim, |
56 | struct pim_upstream *up) |
57 | { |
58 | struct pim_upstream *child; |
59 | |
60 | if (!up->sources) |
61 | return; |
62 | |
63 | while (!list_isempty(up->sources)((up->sources)->head == ((void*)0) && (up->sources )->tail == ((void*)0))) { |
64 | child = listnode_head(up->sources); |
65 | listnode_delete(up->sources, child); |
66 | if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(child->flags)((child->flags) & (1 << 8))) { |
67 | PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(child->flags)((child->flags) &= ~(1 << 8)); |
68 | child = pim_upstream_del(pim, child, __func__); |
69 | } |
70 | if (child) { |
71 | child->parent = NULL((void*)0); |
72 | if (PIM_UPSTREAM_FLAG_TEST_USE_RPT(child->flags)((child->flags) & (1 << 20))) |
73 | pim_upstream_mroute_iif_update( |
74 | child->channel_oil, |
75 | __func__); |
76 | } |
77 | } |
78 | list_delete(&up->sources); |
79 | } |
80 | |
81 | /* |
82 | * A (*,G) or a (*,*) is being created |
83 | * Find the children that would point |
84 | * at us. |
85 | */ |
86 | static void pim_upstream_find_new_children(struct pim_instance *pim, |
87 | struct pim_upstream *up) |
88 | { |
89 | struct pim_upstream *child; |
90 | |
91 | if (!pim_addr_is_any(up->sg.src) && !pim_addr_is_any(up->sg.grp)) |
92 | return; |
93 | |
94 | if (pim_addr_is_any(up->sg.src) && pim_addr_is_any(up->sg.grp)) |
95 | return; |
96 | |
97 | frr_each (rb_pim_upstream, &pim->upstream_head, child)for (child = rb_pim_upstream_first(&pim->upstream_head ); child; child = rb_pim_upstream_next(&pim->upstream_head , child)) { |
98 | if (!pim_addr_is_any(up->sg.grp) && |
99 | !pim_addr_cmp(child->sg.grp, up->sg.grp) && (child != up)) { |
100 | child->parent = up; |
101 | listnode_add_sort(up->sources, child); |
102 | if (PIM_UPSTREAM_FLAG_TEST_USE_RPT(child->flags)((child->flags) & (1 << 20))) |
103 | pim_upstream_mroute_iif_update( |
104 | child->channel_oil, |
105 | __func__); |
106 | } |
107 | } |
108 | } |
109 | |
110 | /* |
111 | * If we have a (*,*) || (S,*) there is no parent |
112 | * If we have a (S,G), find the (*,G) |
113 | * If we have a (*,G), find the (*,*) |
114 | */ |
115 | static struct pim_upstream *pim_upstream_find_parent(struct pim_instance *pim, |
116 | struct pim_upstream *child) |
117 | { |
118 | pim_sgaddr any = child->sg; |
119 | struct pim_upstream *up = NULL((void*)0); |
120 | |
121 | // (S,G) |
122 | if (!pim_addr_is_any(child->sg.src) && |
123 | !pim_addr_is_any(child->sg.grp)) { |
124 | any.src = PIMADDR_ANY(pim_addr){ }; |
125 | up = pim_upstream_find(pim, &any); |
126 | |
127 | if (up) |
128 | listnode_add(up->sources, child); |
129 | |
130 | /* |
131 | * In case parent is MLAG entry copy the data to child |
132 | */ |
133 | if (up && PIM_UPSTREAM_FLAG_TEST_MLAG_INTERFACE(up->flags)((up->flags)&(1 << 21))) { |
134 | PIM_UPSTREAM_FLAG_SET_MLAG_INTERFACE(child->flags)((child->flags) |= (1 << 21)); |
135 | if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags)((up->flags) & (1 << 17))) |
136 | PIM_UPSTREAM_FLAG_SET_MLAG_NON_DF(child->flags)((child->flags) |= (1 << 17)); |
137 | else |
138 | PIM_UPSTREAM_FLAG_UNSET_MLAG_NON_DF(((child->flags) &= ~(1 << 17)) |
139 | child->flags)((child->flags) &= ~(1 << 17)); |
140 | } |
141 | |
142 | return up; |
143 | } |
144 | |
145 | return NULL((void*)0); |
146 | } |
147 | |
148 | static void upstream_channel_oil_detach(struct pim_upstream *up) |
149 | { |
150 | struct channel_oil *channel_oil = up->channel_oil; |
151 | |
152 | if (channel_oil) { |
153 | /* Detaching from channel_oil, channel_oil may exist post del, |
154 | but upstream would not keep reference of it |
155 | */ |
156 | channel_oil->up = NULL((void*)0); |
157 | up->channel_oil = NULL((void*)0); |
158 | |
159 | /* attempt to delete channel_oil; if channel_oil is being held |
160 | * because of other references cleanup info such as "Mute" |
161 | * inferred from the parent upstream |
162 | */ |
163 | pim_channel_oil_upstream_deref(channel_oil); |
164 | } |
165 | |
166 | } |
167 | |
168 | static void pim_upstream_timers_stop(struct pim_upstream *up) |
169 | { |
170 | EVENT_OFF(up->t_ka_timer)do { if ((up->t_ka_timer)) event_cancel(&(up->t_ka_timer )); } while (0); |
171 | EVENT_OFF(up->t_rs_timer)do { if ((up->t_rs_timer)) event_cancel(&(up->t_rs_timer )); } while (0); |
172 | EVENT_OFF(up->t_msdp_reg_timer)do { if ((up->t_msdp_reg_timer)) event_cancel(&(up-> t_msdp_reg_timer)); } while (0); |
173 | EVENT_OFF(up->t_join_timer)do { if ((up->t_join_timer)) event_cancel(&(up->t_join_timer )); } while (0); |
174 | } |
175 | |
176 | struct pim_upstream *pim_upstream_del(struct pim_instance *pim, |
177 | struct pim_upstream *up, const char *name) |
178 | { |
179 | struct listnode *node, *nnode; |
180 | struct pim_ifchannel *ch; |
181 | bool_Bool notify_msdp = false0; |
182 | |
183 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
184 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 188, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)" ), .priority = (7), .ec = (0), .args = ("__func__, name, up->sg_str, pim->vrf->name, up->ref_count, up->flags, up->channel_oil->oil_ref_count" ), }; static const struct xref * const xref_p_84 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)" ), __func__, name, up->sg_str, pim->vrf->name, up-> ref_count, up->flags, up->channel_oil->oil_ref_count ); } while (0) |
185 | "%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 188, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)" ), .priority = (7), .ec = (0), .args = ("__func__, name, up->sg_str, pim->vrf->name, up->ref_count, up->flags, up->channel_oil->oil_ref_count" ), }; static const struct xref * const xref_p_84 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)" ), __func__, name, up->sg_str, pim->vrf->name, up-> ref_count, up->flags, up->channel_oil->oil_ref_count ); } while (0) |
186 | __func__, name, up->sg_str, pim->vrf->name,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 188, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)" ), .priority = (7), .ec = (0), .args = ("__func__, name, up->sg_str, pim->vrf->name, up->ref_count, up->flags, up->channel_oil->oil_ref_count" ), }; static const struct xref * const xref_p_84 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)" ), __func__, name, up->sg_str, pim->vrf->name, up-> ref_count, up->flags, up->channel_oil->oil_ref_count ); } while (0) |
187 | up->ref_count, up->flags,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 188, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)" ), .priority = (7), .ec = (0), .args = ("__func__, name, up->sg_str, pim->vrf->name, up->ref_count, up->flags, up->channel_oil->oil_ref_count" ), }; static const struct xref * const xref_p_84 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)" ), __func__, name, up->sg_str, pim->vrf->name, up-> ref_count, up->flags, up->channel_oil->oil_ref_count ); } while (0) |
188 | up->channel_oil->oil_ref_count)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 188, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)" ), .priority = (7), .ec = (0), .args = ("__func__, name, up->sg_str, pim->vrf->name, up->ref_count, up->flags, up->channel_oil->oil_ref_count" ), }; static const struct xref * const xref_p_84 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s(%s): Delete %s[%s] ref count: %d, flags: %d c_oil ref count %d (Pre decrement)" ), __func__, name, up->sg_str, pim->vrf->name, up-> ref_count, up->flags, up->channel_oil->oil_ref_count ); } while (0); |
189 | |
190 | assert(up->ref_count > 0)({ static const struct xref_assert _xref __attribute__( (used )) = { .xref = { (((void*)0)), (XREFT_ASSERT), 190, "pimd/pim_upstream.c" , __func__, }, .expr = "up->ref_count > 0", }; static const struct xref * const xref_p_85 __attribute__((used, section("xref_array" ))) = &(_xref.xref); if (__builtin_expect((up->ref_count > 0) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, (( void*)0)); } while (up->ref_count > 0); }); |
191 | |
192 | --up->ref_count; |
193 | |
194 | if (up->ref_count >= 1) |
195 | return up; |
196 | |
197 | if (PIM_DEBUG_TRACE(router->debugs & ((1 << 5) | (1 << 9)))) |
198 | zlog_debug("pim_upstream free vrf:%s %s flags 0x%x",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("pim_upstream free vrf:%s %s flags 0x%x" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 199, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("pim_upstream free vrf:%s %s flags 0x%x"), .priority = (7), .ec = (0), .args = ("pim->vrf->name, up->sg_str, up->flags" ), }; static const struct xref * const xref_p_86 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("pim_upstream free vrf:%s %s flags 0x%x"), pim-> vrf->name, up->sg_str, up->flags); } while (0) |
199 | pim->vrf->name, up->sg_str, up->flags)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("pim_upstream free vrf:%s %s flags 0x%x" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 199, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("pim_upstream free vrf:%s %s flags 0x%x"), .priority = (7), .ec = (0), .args = ("pim->vrf->name, up->sg_str, up->flags" ), }; static const struct xref * const xref_p_86 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("pim_upstream free vrf:%s %s flags 0x%x"), pim-> vrf->name, up->sg_str, up->flags); } while (0); |
200 | |
201 | if (pim_up_mlag_is_local(up)) |
202 | pim_mlag_up_local_del(pim, up); |
203 | |
204 | pim_upstream_timers_stop(up); |
205 | |
206 | if (up->join_state == PIM_UPSTREAM_JOINED) { |
207 | pim_jp_agg_single_upstream_send(&up->rpf, up, 0); |
208 | |
209 | if (pim_addr_is_any(up->sg.src)) { |
210 | /* if a (*, G) entry in the joined state is being |
211 | * deleted we |
212 | * need to notify MSDP */ |
213 | notify_msdp = true1; |
214 | } |
215 | } |
216 | |
217 | join_timer_stop(up); |
218 | pim_jp_agg_upstream_verification(up, false0); |
219 | up->rpf.source_nexthop.interface = NULL((void*)0); |
220 | |
221 | if (!pim_addr_is_any(up->sg.src)) { |
222 | if (pim->upstream_sg_wheel) |
223 | wheel_remove_item(pim->upstream_sg_wheel, up); |
224 | notify_msdp = true1; |
225 | } |
226 | |
227 | pim_mroute_del(up->channel_oil, __func__); |
228 | upstream_channel_oil_detach(up); |
229 | |
230 | for (ALL_LIST_ELEMENTS(up->ifchannels, node, nnode, ch)(node) = ((up->ifchannels) ? ((up->ifchannels)->head ) : ((void*)0)), ((ch) = ((void*)0)); (node) != ((void*)0) && ((ch) = ((({ static const struct xref_assert _xref __attribute__ ( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 230, "pimd/pim_upstream.c" , __func__, }, .expr = "node", }; static const struct xref * const xref_p_87 __attribute__((used, section("xref_array"))) = & (_xref.xref); if (__builtin_expect((node) ? 0 : 1, 0)) do { _zlog_assert_failed (&_xref, ((void*)0)); } while (node); }), ({ static const struct xref_assert _xref __attribute__( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 230, "pimd/pim_upstream.c", __func__ , }, .expr = "(node)->data != NULL", }; static const struct xref * const xref_p_88 __attribute__((used, section("xref_array" ))) = &(_xref.xref); if (__builtin_expect(((node)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref , ((void*)0)); } while ((node)->data != ((void*)0)); }), ( node)->data)), (nnode) = node->next, 1); (node) = (nnode ), ((ch) = ((void*)0))) |
231 | pim_ifchannel_delete(ch); |
232 | list_delete(&up->ifchannels); |
233 | |
234 | pim_upstream_remove_children(pim, up); |
235 | if (up->sources) |
236 | list_delete(&up->sources); |
237 | |
238 | if (up->parent && up->parent->sources) |
239 | listnode_delete(up->parent->sources, up); |
240 | up->parent = NULL((void*)0); |
241 | |
242 | rb_pim_upstream_del(&pim->upstream_head, up); |
243 | |
244 | if (notify_msdp) { |
245 | pim_msdp_up_del(pim, &up->sg); |
246 | } |
247 | |
248 | /* When RP gets deleted, pim_rp_del() deregister addr with Zebra NHT |
249 | * and assign up->upstream_addr as INADDR_ANY. |
250 | * So before de-registering the upstream address, check if is not equal |
251 | * to INADDR_ANY. This is done in order to avoid de-registering for |
252 | * 255.255.255.255 which is maintained for some reason.. |
253 | */ |
254 | if (!pim_addr_is_any(up->upstream_addr)) { |
255 | /* Deregister addr with Zebra NHT */ |
256 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
257 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Deregister upstream %s addr %pPA with Zebra NHT" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 259, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Deregister upstream %s addr %pPA with Zebra NHT" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, &up->upstream_addr" ), }; static const struct xref * const xref_p_89 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Deregister upstream %s addr %pPA with Zebra NHT" ), __func__, up->sg_str, &up->upstream_addr); } while (0) |
258 | "%s: Deregister upstream %s addr %pPA with Zebra NHT",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Deregister upstream %s addr %pPA with Zebra NHT" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 259, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Deregister upstream %s addr %pPA with Zebra NHT" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, &up->upstream_addr" ), }; static const struct xref * const xref_p_89 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Deregister upstream %s addr %pPA with Zebra NHT" ), __func__, up->sg_str, &up->upstream_addr); } while (0) |
259 | __func__, up->sg_str, &up->upstream_addr)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Deregister upstream %s addr %pPA with Zebra NHT" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 259, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Deregister upstream %s addr %pPA with Zebra NHT" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, &up->upstream_addr" ), }; static const struct xref * const xref_p_89 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Deregister upstream %s addr %pPA with Zebra NHT" ), __func__, up->sg_str, &up->upstream_addr); } while (0); |
260 | pim_delete_tracked_nexthop(pim, up->upstream_addr, up, NULL((void*)0)); |
261 | } |
262 | |
263 | XFREE(MTYPE_PIM_UPSTREAM, up)do { qfree(MTYPE_PIM_UPSTREAM, up); up = ((void*)0); } while ( 0); |
264 | |
265 | return NULL((void*)0); |
266 | } |
267 | |
268 | void pim_upstream_send_join(struct pim_upstream *up) |
269 | { |
270 | if (!up->rpf.source_nexthop.interface) { |
271 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
272 | zlog_debug("%s: up %s RPF is not present", __func__,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: up %s RPF is not present" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 273, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: up %s RPF is not present"), .priority = (7) , .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_90 __attribute__((used, section("xref_array" ))) = &(_xref.xref); zlog_ref(&_xref, ("%s: up %s RPF is not present" ), __func__, up->sg_str); } while (0) |
273 | up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: up %s RPF is not present" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 273, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: up %s RPF is not present"), .priority = (7) , .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_90 __attribute__((used, section("xref_array" ))) = &(_xref.xref); zlog_ref(&_xref, ("%s: up %s RPF is not present" ), __func__, up->sg_str); } while (0); |
274 | return; |
275 | } |
276 | |
277 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) { |
278 | zlog_debug("%s: RPF'%s=%pPA(%s) for Interface %s", __func__,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: RPF'%s=%pPA(%s) for Interface %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 281, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: RPF'%s=%pPA(%s) for Interface %s"), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, &up->rpf.rpf_addr, pim_upstream_state2str(up->join_state), up->rpf.source_nexthop.interface->name" ), }; static const struct xref * const xref_p_91 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: RPF'%s=%pPA(%s) for Interface %s"), __func__ , up->sg_str, &up->rpf.rpf_addr, pim_upstream_state2str (up->join_state), up->rpf.source_nexthop.interface-> name); } while (0) |
279 | up->sg_str, &up->rpf.rpf_addr,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: RPF'%s=%pPA(%s) for Interface %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 281, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: RPF'%s=%pPA(%s) for Interface %s"), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, &up->rpf.rpf_addr, pim_upstream_state2str(up->join_state), up->rpf.source_nexthop.interface->name" ), }; static const struct xref * const xref_p_91 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: RPF'%s=%pPA(%s) for Interface %s"), __func__ , up->sg_str, &up->rpf.rpf_addr, pim_upstream_state2str (up->join_state), up->rpf.source_nexthop.interface-> name); } while (0) |
280 | pim_upstream_state2str(up->join_state),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: RPF'%s=%pPA(%s) for Interface %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 281, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: RPF'%s=%pPA(%s) for Interface %s"), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, &up->rpf.rpf_addr, pim_upstream_state2str(up->join_state), up->rpf.source_nexthop.interface->name" ), }; static const struct xref * const xref_p_91 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: RPF'%s=%pPA(%s) for Interface %s"), __func__ , up->sg_str, &up->rpf.rpf_addr, pim_upstream_state2str (up->join_state), up->rpf.source_nexthop.interface-> name); } while (0) |
281 | up->rpf.source_nexthop.interface->name)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: RPF'%s=%pPA(%s) for Interface %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 281, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: RPF'%s=%pPA(%s) for Interface %s"), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, &up->rpf.rpf_addr, pim_upstream_state2str(up->join_state), up->rpf.source_nexthop.interface->name" ), }; static const struct xref * const xref_p_91 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: RPF'%s=%pPA(%s) for Interface %s"), __func__ , up->sg_str, &up->rpf.rpf_addr, pim_upstream_state2str (up->join_state), up->rpf.source_nexthop.interface-> name); } while (0); |
282 | if (pim_rpf_addr_is_inaddr_any(&up->rpf)) { |
283 | zlog_debug("%s: can't send join upstream: RPF'%s=%pPA",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: can't send join upstream: RPF'%s=%pPA" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 284, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: can't send join upstream: RPF'%s=%pPA"), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, &up->rpf.rpf_addr" ), }; static const struct xref * const xref_p_92 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: can't send join upstream: RPF'%s=%pPA"), __func__ , up->sg_str, &up->rpf.rpf_addr); } while (0) |
284 | __func__, up->sg_str, &up->rpf.rpf_addr)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: can't send join upstream: RPF'%s=%pPA" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 284, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: can't send join upstream: RPF'%s=%pPA"), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, &up->rpf.rpf_addr" ), }; static const struct xref * const xref_p_92 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: can't send join upstream: RPF'%s=%pPA"), __func__ , up->sg_str, &up->rpf.rpf_addr); } while (0); |
285 | /* warning only */ |
286 | } |
287 | } |
288 | |
289 | /* send Join(S,G) to the current upstream neighbor */ |
290 | pim_jp_agg_single_upstream_send(&up->rpf, up, 1 /* join */); |
291 | } |
292 | |
293 | static void on_join_timer(struct event *t) |
294 | { |
295 | struct pim_upstream *up; |
296 | |
297 | up = EVENT_ARG(t)((t)->arg); |
298 | |
299 | if (!up->rpf.source_nexthop.interface) { |
300 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
301 | zlog_debug("%s: up %s RPF is not present", __func__,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: up %s RPF is not present" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 302, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: up %s RPF is not present"), .priority = (7) , .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_93 __attribute__((used, section("xref_array" ))) = &(_xref.xref); zlog_ref(&_xref, ("%s: up %s RPF is not present" ), __func__, up->sg_str); } while (0) |
302 | up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: up %s RPF is not present" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 302, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: up %s RPF is not present"), .priority = (7) , .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_93 __attribute__((used, section("xref_array" ))) = &(_xref.xref); zlog_ref(&_xref, ("%s: up %s RPF is not present" ), __func__, up->sg_str); } while (0); |
303 | return; |
304 | } |
305 | |
306 | /* |
307 | * In the case of a HFR we will not ahve anyone to send this to. |
308 | */ |
309 | if (PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)((up->flags) & (1 << 2))) |
310 | return; |
311 | |
312 | /* |
313 | * Don't send the join if the outgoing interface is a loopback |
314 | * But since this might change leave the join timer running |
315 | */ |
316 | if (up->rpf.source_nexthop |
317 | .interface && !if_is_loopback(up->rpf.source_nexthop.interface)) |
318 | pim_upstream_send_join(up); |
319 | |
320 | join_timer_start(up); |
321 | } |
322 | |
323 | static void join_timer_stop(struct pim_upstream *up) |
324 | { |
325 | struct pim_neighbor *nbr = NULL((void*)0); |
326 | |
327 | EVENT_OFF(up->t_join_timer)do { if ((up->t_join_timer)) event_cancel(&(up->t_join_timer )); } while (0); |
328 | |
329 | if (up->rpf.source_nexthop.interface) |
330 | nbr = pim_neighbor_find(up->rpf.source_nexthop.interface, |
331 | up->rpf.rpf_addr, true1); |
332 | |
333 | if (nbr) |
334 | pim_jp_agg_remove_group(nbr->upstream_jp_agg, up, nbr); |
335 | |
336 | pim_jp_agg_upstream_verification(up, false0); |
337 | } |
338 | |
339 | void join_timer_start(struct pim_upstream *up) |
340 | { |
341 | struct pim_neighbor *nbr = NULL((void*)0); |
342 | |
343 | if (up->rpf.source_nexthop.interface) { |
344 | nbr = pim_neighbor_find(up->rpf.source_nexthop.interface, |
345 | up->rpf.rpf_addr, true1); |
346 | |
347 | if (PIM_DEBUG_PIM_EVENTS(router->debugs & (1 << 0))) { |
348 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: starting %d sec timer for upstream (S,G)=%s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 350, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: starting %d sec timer for upstream (S,G)=%s" ), .priority = (7), .ec = (0), .args = ("__func__, router->t_periodic, up->sg_str" ), }; static const struct xref * const xref_p_94 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: starting %d sec timer for upstream (S,G)=%s" ), __func__, router->t_periodic, up->sg_str); } while ( 0) |
349 | "%s: starting %d sec timer for upstream (S,G)=%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: starting %d sec timer for upstream (S,G)=%s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 350, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: starting %d sec timer for upstream (S,G)=%s" ), .priority = (7), .ec = (0), .args = ("__func__, router->t_periodic, up->sg_str" ), }; static const struct xref * const xref_p_94 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: starting %d sec timer for upstream (S,G)=%s" ), __func__, router->t_periodic, up->sg_str); } while ( 0) |
350 | __func__, router->t_periodic, up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: starting %d sec timer for upstream (S,G)=%s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 350, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: starting %d sec timer for upstream (S,G)=%s" ), .priority = (7), .ec = (0), .args = ("__func__, router->t_periodic, up->sg_str" ), }; static const struct xref * const xref_p_94 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: starting %d sec timer for upstream (S,G)=%s" ), __func__, router->t_periodic, up->sg_str); } while ( 0); |
351 | } |
352 | } |
353 | |
354 | if (nbr) |
355 | pim_jp_agg_add_group(nbr->upstream_jp_agg, up, 1, nbr); |
356 | else { |
357 | EVENT_OFF(up->t_join_timer)do { if ((up->t_join_timer)) event_cancel(&(up->t_join_timer )); } while (0); |
358 | event_add_timer(router->master, on_join_timer, up,({ static const struct xref_eventsched _xref __attribute__( ( used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 359, "pimd/pim_upstream.c" , __func__, }, .funcname = "on_join_timer", .dest = "&up->t_join_timer" , .event_type = EVENT_TIMER, }; static const struct xref * const xref_p_95 __attribute__((used, section("xref_array"))) = & (_xref.xref); _event_add_timer(&_xref, router->master, on_join_timer, up, router->t_periodic, &up->t_join_timer ); }) |
359 | router->t_periodic, &up->t_join_timer)({ static const struct xref_eventsched _xref __attribute__( ( used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 359, "pimd/pim_upstream.c" , __func__, }, .funcname = "on_join_timer", .dest = "&up->t_join_timer" , .event_type = EVENT_TIMER, }; static const struct xref * const xref_p_95 __attribute__((used, section("xref_array"))) = & (_xref.xref); _event_add_timer(&_xref, router->master, on_join_timer, up, router->t_periodic, &up->t_join_timer ); }); |
360 | } |
361 | pim_jp_agg_upstream_verification(up, true1); |
362 | } |
363 | |
364 | /* |
365 | * This is only called when we are switching the upstream |
366 | * J/P from one neighbor to another |
367 | * |
368 | * As such we need to remove from the old list and |
369 | * add to the new list. |
370 | */ |
371 | void pim_upstream_join_timer_restart(struct pim_upstream *up, |
372 | struct pim_rpf *old) |
373 | { |
374 | // EVENT_OFF(up->t_join_timer); |
375 | join_timer_start(up); |
376 | } |
377 | |
378 | static void pim_upstream_join_timer_restart_msec(struct pim_upstream *up, |
379 | int interval_msec) |
380 | { |
381 | if (PIM_DEBUG_PIM_EVENTS(router->debugs & (1 << 0))) { |
382 | zlog_debug("%s: restarting %d msec timer for upstream (S,G)=%s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: restarting %d msec timer for upstream (S,G)=%s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 383, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: restarting %d msec timer for upstream (S,G)=%s" ), .priority = (7), .ec = (0), .args = ("__func__, interval_msec, up->sg_str" ), }; static const struct xref * const xref_p_96 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: restarting %d msec timer for upstream (S,G)=%s" ), __func__, interval_msec, up->sg_str); } while (0) |
383 | __func__, interval_msec, up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: restarting %d msec timer for upstream (S,G)=%s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 383, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: restarting %d msec timer for upstream (S,G)=%s" ), .priority = (7), .ec = (0), .args = ("__func__, interval_msec, up->sg_str" ), }; static const struct xref * const xref_p_96 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: restarting %d msec timer for upstream (S,G)=%s" ), __func__, interval_msec, up->sg_str); } while (0); |
384 | } |
385 | |
386 | EVENT_OFF(up->t_join_timer)do { if ((up->t_join_timer)) event_cancel(&(up->t_join_timer )); } while (0); |
387 | event_add_timer_msec(router->master, on_join_timer, up, interval_msec,({ static const struct xref_eventsched _xref __attribute__( ( used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 388, "pimd/pim_upstream.c" , __func__, }, .funcname = "on_join_timer", .dest = "&up->t_join_timer" , .event_type = EVENT_TIMER, }; static const struct xref * const xref_p_97 __attribute__((used, section("xref_array"))) = & (_xref.xref); _event_add_timer_msec(&_xref, router->master , on_join_timer, up, interval_msec, &up->t_join_timer) ; }) |
388 | &up->t_join_timer)({ static const struct xref_eventsched _xref __attribute__( ( used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 388, "pimd/pim_upstream.c" , __func__, }, .funcname = "on_join_timer", .dest = "&up->t_join_timer" , .event_type = EVENT_TIMER, }; static const struct xref * const xref_p_97 __attribute__((used, section("xref_array"))) = & (_xref.xref); _event_add_timer_msec(&_xref, router->master , on_join_timer, up, interval_msec, &up->t_join_timer) ; }); |
389 | } |
390 | |
391 | void pim_update_suppress_timers(uint32_t suppress_time) |
392 | { |
393 | struct pim_instance *pim; |
394 | struct vrf *vrf; |
395 | unsigned int old_rp_ka_time; |
396 | |
397 | /* stash the old one so we know which values were manually configured */ |
398 | old_rp_ka_time = (3 * router->register_suppress_time |
399 | + router->register_probe_time); |
400 | router->register_suppress_time = suppress_time; |
401 | |
402 | RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)for ((vrf) = vrf_name_head_RB_MIN((&vrfs_by_name)); (vrf) != ((void*)0); (vrf) = vrf_name_head_RB_NEXT((vrf))) { |
403 | pim = vrf->info; |
404 | if (!pim) |
405 | continue; |
406 | |
407 | /* Only adjust if not manually configured */ |
408 | if (pim->rp_keep_alive_time == old_rp_ka_time) |
409 | pim->rp_keep_alive_time = PIM_RP_KEEPALIVE_PERIOD(3 * router->register_suppress_time + router->register_probe_time ); |
410 | } |
411 | } |
412 | |
413 | void pim_upstream_join_suppress(struct pim_upstream *up, pim_addr rpf, |
414 | int holdtime) |
415 | { |
416 | long t_joinsuppress_msec; |
417 | long join_timer_remain_msec = 0; |
418 | struct pim_neighbor *nbr = NULL((void*)0); |
419 | |
420 | if (!up->rpf.source_nexthop.interface) { |
421 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
422 | zlog_debug("%s: up %s RPF is not present", __func__,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: up %s RPF is not present" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 423, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: up %s RPF is not present"), .priority = (7) , .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_98 __attribute__((used, section("xref_array" ))) = &(_xref.xref); zlog_ref(&_xref, ("%s: up %s RPF is not present" ), __func__, up->sg_str); } while (0) |
423 | up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: up %s RPF is not present" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 423, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: up %s RPF is not present"), .priority = (7) , .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_98 __attribute__((used, section("xref_array" ))) = &(_xref.xref); zlog_ref(&_xref, ("%s: up %s RPF is not present" ), __func__, up->sg_str); } while (0); |
424 | return; |
425 | } |
426 | |
427 | t_joinsuppress_msec = |
428 | MIN(pim_if_t_suppressed_msec(up->rpf.source_nexthop.interface),(((pim_if_t_suppressed_msec(up->rpf.source_nexthop.interface ))<(1000 * holdtime))?(pim_if_t_suppressed_msec(up->rpf .source_nexthop.interface)):(1000 * holdtime)) |
429 | 1000 * holdtime)(((pim_if_t_suppressed_msec(up->rpf.source_nexthop.interface ))<(1000 * holdtime))?(pim_if_t_suppressed_msec(up->rpf .source_nexthop.interface)):(1000 * holdtime)); |
430 | |
431 | if (up->t_join_timer) |
432 | join_timer_remain_msec = |
433 | pim_time_timer_remain_msec(up->t_join_timer); |
434 | else { |
435 | /* Remove it from jp agg from the nbr for suppression */ |
436 | nbr = pim_neighbor_find(up->rpf.source_nexthop.interface, |
437 | up->rpf.rpf_addr, true1); |
438 | |
439 | if (nbr) { |
440 | join_timer_remain_msec = |
441 | pim_time_timer_remain_msec(nbr->jp_timer); |
442 | } |
443 | } |
444 | |
445 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
446 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s %s: detected Join%s to RPF'(S,G)=%pPA: join_timer=%ld msec t_joinsuppress=%ld msec" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 449, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s %s: detected Join%s to RPF'(S,G)=%pPA: join_timer=%ld msec t_joinsuppress=%ld msec" ), .priority = (7), .ec = (0), .args = ("\"pimd/pim_upstream.c\", __func__, up->sg_str, &rpf, join_timer_remain_msec, t_joinsuppress_msec" ), }; static const struct xref * const xref_p_99 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s %s: detected Join%s to RPF'(S,G)=%pPA: join_timer=%ld msec t_joinsuppress=%ld msec" ), "pimd/pim_upstream.c", __func__, up->sg_str, &rpf, join_timer_remain_msec , t_joinsuppress_msec); } while (0) |
447 | "%s %s: detected Join%s to RPF'(S,G)=%pPA: join_timer=%ld msec t_joinsuppress=%ld msec",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s %s: detected Join%s to RPF'(S,G)=%pPA: join_timer=%ld msec t_joinsuppress=%ld msec" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 449, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s %s: detected Join%s to RPF'(S,G)=%pPA: join_timer=%ld msec t_joinsuppress=%ld msec" ), .priority = (7), .ec = (0), .args = ("\"pimd/pim_upstream.c\", __func__, up->sg_str, &rpf, join_timer_remain_msec, t_joinsuppress_msec" ), }; static const struct xref * const xref_p_99 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s %s: detected Join%s to RPF'(S,G)=%pPA: join_timer=%ld msec t_joinsuppress=%ld msec" ), "pimd/pim_upstream.c", __func__, up->sg_str, &rpf, join_timer_remain_msec , t_joinsuppress_msec); } while (0) |
448 | __FILE__, __func__, up->sg_str, &rpf,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s %s: detected Join%s to RPF'(S,G)=%pPA: join_timer=%ld msec t_joinsuppress=%ld msec" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 449, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s %s: detected Join%s to RPF'(S,G)=%pPA: join_timer=%ld msec t_joinsuppress=%ld msec" ), .priority = (7), .ec = (0), .args = ("\"pimd/pim_upstream.c\", __func__, up->sg_str, &rpf, join_timer_remain_msec, t_joinsuppress_msec" ), }; static const struct xref * const xref_p_99 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s %s: detected Join%s to RPF'(S,G)=%pPA: join_timer=%ld msec t_joinsuppress=%ld msec" ), "pimd/pim_upstream.c", __func__, up->sg_str, &rpf, join_timer_remain_msec , t_joinsuppress_msec); } while (0) |
449 | join_timer_remain_msec, t_joinsuppress_msec)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s %s: detected Join%s to RPF'(S,G)=%pPA: join_timer=%ld msec t_joinsuppress=%ld msec" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 449, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s %s: detected Join%s to RPF'(S,G)=%pPA: join_timer=%ld msec t_joinsuppress=%ld msec" ), .priority = (7), .ec = (0), .args = ("\"pimd/pim_upstream.c\", __func__, up->sg_str, &rpf, join_timer_remain_msec, t_joinsuppress_msec" ), }; static const struct xref * const xref_p_99 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s %s: detected Join%s to RPF'(S,G)=%pPA: join_timer=%ld msec t_joinsuppress=%ld msec" ), "pimd/pim_upstream.c", __func__, up->sg_str, &rpf, join_timer_remain_msec , t_joinsuppress_msec); } while (0); |
450 | |
451 | if (join_timer_remain_msec < t_joinsuppress_msec) { |
452 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) { |
453 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s %s: suppressing Join(S,G)=%s for %ld msec" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 456, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s %s: suppressing Join(S,G)=%s for %ld msec"), .priority = (7), .ec = (0), .args = ("\"pimd/pim_upstream.c\", __func__, up->sg_str, t_joinsuppress_msec" ), }; static const struct xref * const xref_p_100 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s %s: suppressing Join(S,G)=%s for %ld msec") , "pimd/pim_upstream.c", __func__, up->sg_str, t_joinsuppress_msec ); } while (0) |
454 | "%s %s: suppressing Join(S,G)=%s for %ld msec",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s %s: suppressing Join(S,G)=%s for %ld msec" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 456, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s %s: suppressing Join(S,G)=%s for %ld msec"), .priority = (7), .ec = (0), .args = ("\"pimd/pim_upstream.c\", __func__, up->sg_str, t_joinsuppress_msec" ), }; static const struct xref * const xref_p_100 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s %s: suppressing Join(S,G)=%s for %ld msec") , "pimd/pim_upstream.c", __func__, up->sg_str, t_joinsuppress_msec ); } while (0) |
455 | __FILE__, __func__, up->sg_str,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s %s: suppressing Join(S,G)=%s for %ld msec" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 456, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s %s: suppressing Join(S,G)=%s for %ld msec"), .priority = (7), .ec = (0), .args = ("\"pimd/pim_upstream.c\", __func__, up->sg_str, t_joinsuppress_msec" ), }; static const struct xref * const xref_p_100 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s %s: suppressing Join(S,G)=%s for %ld msec") , "pimd/pim_upstream.c", __func__, up->sg_str, t_joinsuppress_msec ); } while (0) |
456 | t_joinsuppress_msec)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s %s: suppressing Join(S,G)=%s for %ld msec" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 456, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s %s: suppressing Join(S,G)=%s for %ld msec"), .priority = (7), .ec = (0), .args = ("\"pimd/pim_upstream.c\", __func__, up->sg_str, t_joinsuppress_msec" ), }; static const struct xref * const xref_p_100 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s %s: suppressing Join(S,G)=%s for %ld msec") , "pimd/pim_upstream.c", __func__, up->sg_str, t_joinsuppress_msec ); } while (0); |
457 | } |
458 | |
459 | if (nbr) |
460 | pim_jp_agg_remove_group(nbr->upstream_jp_agg, up, nbr); |
461 | |
462 | pim_upstream_join_timer_restart_msec(up, t_joinsuppress_msec); |
463 | } |
464 | } |
465 | |
466 | void pim_upstream_join_timer_decrease_to_t_override(const char *debug_label, |
467 | struct pim_upstream *up) |
468 | { |
469 | long join_timer_remain_msec; |
470 | int t_override_msec; |
471 | |
472 | if (!up->rpf.source_nexthop.interface) { |
473 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
474 | zlog_debug("%s: up %s RPF is not present", __func__,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: up %s RPF is not present" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 475, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: up %s RPF is not present"), .priority = (7) , .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_101 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: up %s RPF is not present" ), __func__, up->sg_str); } while (0) |
475 | up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: up %s RPF is not present" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 475, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: up %s RPF is not present"), .priority = (7) , .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_101 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: up %s RPF is not present" ), __func__, up->sg_str); } while (0); |
476 | return; |
477 | } |
478 | |
479 | t_override_msec = |
480 | pim_if_t_override_msec(up->rpf.source_nexthop.interface); |
481 | |
482 | if (up->t_join_timer) { |
483 | join_timer_remain_msec = |
484 | pim_time_timer_remain_msec(up->t_join_timer); |
485 | } else { |
486 | /* upstream join tracked with neighbor jp timer */ |
487 | struct pim_neighbor *nbr; |
488 | |
489 | nbr = pim_neighbor_find(up->rpf.source_nexthop.interface, |
490 | up->rpf.rpf_addr, true1); |
491 | |
492 | if (nbr) |
493 | join_timer_remain_msec = |
494 | pim_time_timer_remain_msec(nbr->jp_timer); |
495 | else |
496 | /* Manipulate such that override takes place */ |
497 | join_timer_remain_msec = t_override_msec + 1; |
498 | } |
499 | |
500 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
501 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: to RPF'%s=%pPA: join_timer=%ld msec t_override=%d msec" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 504, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: to RPF'%s=%pPA: join_timer=%ld msec t_override=%d msec" ), .priority = (7), .ec = (0), .args = ("debug_label, up->sg_str, &up->rpf.rpf_addr, join_timer_remain_msec, t_override_msec" ), }; static const struct xref * const xref_p_102 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: to RPF'%s=%pPA: join_timer=%ld msec t_override=%d msec" ), debug_label, up->sg_str, &up->rpf.rpf_addr, join_timer_remain_msec , t_override_msec); } while (0) |
502 | "%s: to RPF'%s=%pPA: join_timer=%ld msec t_override=%d msec",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: to RPF'%s=%pPA: join_timer=%ld msec t_override=%d msec" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 504, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: to RPF'%s=%pPA: join_timer=%ld msec t_override=%d msec" ), .priority = (7), .ec = (0), .args = ("debug_label, up->sg_str, &up->rpf.rpf_addr, join_timer_remain_msec, t_override_msec" ), }; static const struct xref * const xref_p_102 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: to RPF'%s=%pPA: join_timer=%ld msec t_override=%d msec" ), debug_label, up->sg_str, &up->rpf.rpf_addr, join_timer_remain_msec , t_override_msec); } while (0) |
503 | debug_label, up->sg_str, &up->rpf.rpf_addr,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: to RPF'%s=%pPA: join_timer=%ld msec t_override=%d msec" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 504, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: to RPF'%s=%pPA: join_timer=%ld msec t_override=%d msec" ), .priority = (7), .ec = (0), .args = ("debug_label, up->sg_str, &up->rpf.rpf_addr, join_timer_remain_msec, t_override_msec" ), }; static const struct xref * const xref_p_102 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: to RPF'%s=%pPA: join_timer=%ld msec t_override=%d msec" ), debug_label, up->sg_str, &up->rpf.rpf_addr, join_timer_remain_msec , t_override_msec); } while (0) |
504 | join_timer_remain_msec, t_override_msec)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: to RPF'%s=%pPA: join_timer=%ld msec t_override=%d msec" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 504, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: to RPF'%s=%pPA: join_timer=%ld msec t_override=%d msec" ), .priority = (7), .ec = (0), .args = ("debug_label, up->sg_str, &up->rpf.rpf_addr, join_timer_remain_msec, t_override_msec" ), }; static const struct xref * const xref_p_102 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: to RPF'%s=%pPA: join_timer=%ld msec t_override=%d msec" ), debug_label, up->sg_str, &up->rpf.rpf_addr, join_timer_remain_msec , t_override_msec); } while (0); |
505 | |
506 | if (join_timer_remain_msec > t_override_msec) { |
507 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) { |
508 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: decreasing (S,G)=%s join timer to t_override=%d msec" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 510, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: decreasing (S,G)=%s join timer to t_override=%d msec" ), .priority = (7), .ec = (0), .args = ("debug_label, up->sg_str, t_override_msec" ), }; static const struct xref * const xref_p_103 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: decreasing (S,G)=%s join timer to t_override=%d msec" ), debug_label, up->sg_str, t_override_msec); } while (0) |
509 | "%s: decreasing (S,G)=%s join timer to t_override=%d msec",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: decreasing (S,G)=%s join timer to t_override=%d msec" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 510, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: decreasing (S,G)=%s join timer to t_override=%d msec" ), .priority = (7), .ec = (0), .args = ("debug_label, up->sg_str, t_override_msec" ), }; static const struct xref * const xref_p_103 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: decreasing (S,G)=%s join timer to t_override=%d msec" ), debug_label, up->sg_str, t_override_msec); } while (0) |
510 | debug_label, up->sg_str, t_override_msec)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: decreasing (S,G)=%s join timer to t_override=%d msec" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 510, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: decreasing (S,G)=%s join timer to t_override=%d msec" ), .priority = (7), .ec = (0), .args = ("debug_label, up->sg_str, t_override_msec" ), }; static const struct xref * const xref_p_103 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: decreasing (S,G)=%s join timer to t_override=%d msec" ), debug_label, up->sg_str, t_override_msec); } while (0); |
511 | } |
512 | |
513 | pim_upstream_join_timer_restart_msec(up, t_override_msec); |
514 | } |
515 | } |
516 | |
517 | static void forward_on(struct pim_upstream *up) |
518 | { |
519 | struct listnode *chnode; |
520 | struct listnode *chnextnode; |
521 | struct pim_ifchannel *ch = NULL((void*)0); |
522 | |
523 | /* scan (S,G) state */ |
524 | for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)(chnode) = ((up->ifchannels) ? ((up->ifchannels)->head ) : ((void*)0)), ((ch) = ((void*)0)); (chnode) != ((void*)0) && ((ch) = ((({ static const struct xref_assert _xref __attribute__ ( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 524, "pimd/pim_upstream.c" , __func__, }, .expr = "chnode", }; static const struct xref * const xref_p_104 __attribute__((used, section("xref_array")) ) = &(_xref.xref); if (__builtin_expect((chnode) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void*)0)); } while (chnode); }), ({ static const struct xref_assert _xref __attribute__ ( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 524, "pimd/pim_upstream.c" , __func__, }, .expr = "(chnode)->data != NULL", }; static const struct xref * const xref_p_105 __attribute__((used, section ("xref_array"))) = &(_xref.xref); if (__builtin_expect((( chnode)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed (&_xref, ((void*)0)); } while ((chnode)->data != ((void *)0)); }), (chnode)->data)), (chnextnode) = chnode->next , 1); (chnode) = (chnextnode), ((ch) = ((void*)0))) { |
525 | if (pim_macro_chisin_oiflist(ch)) |
526 | pim_forward_start(ch); |
527 | |
528 | } /* scan iface channel list */ |
529 | } |
530 | |
531 | static void forward_off(struct pim_upstream *up) |
532 | { |
533 | struct listnode *chnode; |
534 | struct listnode *chnextnode; |
535 | struct pim_ifchannel *ch; |
536 | |
537 | /* scan per-interface (S,G) state */ |
538 | for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)(chnode) = ((up->ifchannels) ? ((up->ifchannels)->head ) : ((void*)0)), ((ch) = ((void*)0)); (chnode) != ((void*)0) && ((ch) = ((({ static const struct xref_assert _xref __attribute__ ( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 538, "pimd/pim_upstream.c" , __func__, }, .expr = "chnode", }; static const struct xref * const xref_p_106 __attribute__((used, section("xref_array")) ) = &(_xref.xref); if (__builtin_expect((chnode) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void*)0)); } while (chnode); }), ({ static const struct xref_assert _xref __attribute__ ( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 538, "pimd/pim_upstream.c" , __func__, }, .expr = "(chnode)->data != NULL", }; static const struct xref * const xref_p_107 __attribute__((used, section ("xref_array"))) = &(_xref.xref); if (__builtin_expect((( chnode)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed (&_xref, ((void*)0)); } while ((chnode)->data != ((void *)0)); }), (chnode)->data)), (chnextnode) = chnode->next , 1); (chnode) = (chnextnode), ((ch) = ((void*)0))) { |
539 | |
540 | pim_forward_stop(ch); |
541 | |
542 | } /* scan iface channel list */ |
543 | } |
544 | |
545 | int pim_upstream_could_register(struct pim_upstream *up) |
546 | { |
547 | struct pim_interface *pim_ifp = NULL((void*)0); |
548 | |
549 | /* FORCE_PIMREG is a generic flag to let an app like VxLAN-AA register |
550 | * a source on an upstream entry even if the source is not directly |
551 | * connected on the IIF. |
552 | */ |
553 | if (PIM_UPSTREAM_FLAG_TEST_FORCE_PIMREG(up->flags)((up->flags) & (1 << 13))) |
554 | return 1; |
555 | |
556 | if (up->rpf.source_nexthop.interface) |
557 | pim_ifp = up->rpf.source_nexthop.interface->info; |
558 | else { |
559 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
560 | zlog_debug("%s: up %s RPF is not present", __func__,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: up %s RPF is not present" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 561, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: up %s RPF is not present"), .priority = (7) , .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_108 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: up %s RPF is not present" ), __func__, up->sg_str); } while (0) |
561 | up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: up %s RPF is not present" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 561, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: up %s RPF is not present"), .priority = (7) , .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_108 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: up %s RPF is not present" ), __func__, up->sg_str); } while (0); |
562 | } |
563 | |
564 | if (pim_ifp && PIM_I_am_DR(pim_ifp)!pim_addr_cmp((pim_ifp)->pim_dr_addr, (pim_ifp)->primary_address ) |
565 | && pim_if_connected_to_source(up->rpf.source_nexthop.interface, |
566 | up->sg.src)) |
567 | return 1; |
568 | |
569 | return 0; |
570 | } |
571 | |
572 | /* Source registration is suppressed for SSM groups. When the SSM range changes |
573 | * we re-revaluate register setup for existing upstream entries */ |
574 | void pim_upstream_register_reevaluate(struct pim_instance *pim) |
575 | { |
576 | struct pim_upstream *up; |
577 | |
578 | frr_each (rb_pim_upstream, &pim->upstream_head, up)for (up = rb_pim_upstream_first(&pim->upstream_head); up ; up = rb_pim_upstream_next(&pim->upstream_head, up)) { |
579 | /* If FHR is set CouldRegister is True. Also check if the flow |
580 | * is actually active; if it is not kat setup will trigger |
581 | * source |
582 | * registration whenever the flow becomes active. */ |
583 | if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)((up->flags) & (1 << 2)) || |
584 | !pim_upstream_is_kat_running(up)) |
585 | continue; |
586 | |
587 | if (pim_is_grp_ssm(pim, up->sg.grp)) { |
588 | /* clear the register state for SSM groups */ |
589 | if (up->reg_state != PIM_REG_NOINFO) { |
590 | if (PIM_DEBUG_PIM_EVENTS(router->debugs & (1 << 0))) |
591 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("Clear register for %s as G is now SSM" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 593, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("Clear register for %s as G is now SSM"), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_109 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("Clear register for %s as G is now SSM" ), up->sg_str); } while (0) |
592 | "Clear register for %s as G is now SSM",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("Clear register for %s as G is now SSM" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 593, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("Clear register for %s as G is now SSM"), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_109 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("Clear register for %s as G is now SSM" ), up->sg_str); } while (0) |
593 | up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("Clear register for %s as G is now SSM" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 593, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("Clear register for %s as G is now SSM"), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_109 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("Clear register for %s as G is now SSM" ), up->sg_str); } while (0); |
594 | /* remove regiface from the OIL if it is there*/ |
595 | pim_channel_del_oif(up->channel_oil, |
596 | pim->regiface, |
597 | PIM_OIF_FLAG_PROTO_PIM(1 << 1), |
598 | __func__); |
599 | up->reg_state = PIM_REG_NOINFO; |
600 | } |
601 | } else { |
602 | /* register ASM sources with the RP */ |
603 | if (up->reg_state == PIM_REG_NOINFO) { |
604 | if (PIM_DEBUG_PIM_EVENTS(router->debugs & (1 << 0))) |
605 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("Register %s as G is now ASM" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 607, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("Register %s as G is now ASM"), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_110 __attribute__((used, section("xref_array" ))) = &(_xref.xref); zlog_ref(&_xref, ("Register %s as G is now ASM" ), up->sg_str); } while (0) |
606 | "Register %s as G is now ASM",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("Register %s as G is now ASM" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 607, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("Register %s as G is now ASM"), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_110 __attribute__((used, section("xref_array" ))) = &(_xref.xref); zlog_ref(&_xref, ("Register %s as G is now ASM" ), up->sg_str); } while (0) |
607 | up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("Register %s as G is now ASM" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 607, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("Register %s as G is now ASM"), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_110 __attribute__((used, section("xref_array" ))) = &(_xref.xref); zlog_ref(&_xref, ("Register %s as G is now ASM" ), up->sg_str); } while (0); |
608 | pim_channel_add_oif(up->channel_oil, |
609 | pim->regiface, |
610 | PIM_OIF_FLAG_PROTO_PIM(1 << 1), |
611 | __func__); |
612 | up->reg_state = PIM_REG_JOIN; |
613 | } |
614 | } |
615 | } |
616 | } |
617 | |
618 | /* RFC7761, Section 4.2 “Data Packet Forwarding Rules” says we should |
619 | * forward a S - |
620 | * 1. along the SPT if SPTbit is set |
621 | * 2. and along the RPT if SPTbit is not set |
622 | * If forwarding is hw accelerated i.e. control and dataplane components |
623 | * are separate you may not be able to reliably set SPT bit on intermediate |
624 | * routers while still forwarding on the (S,G,rpt). |
625 | * |
626 | * This macro is a slight deviation on the RFC and uses "traffic-agnostic" |
627 | * criteria to decide between using the RPT vs. SPT for forwarding. |
628 | */ |
629 | void pim_upstream_update_use_rpt(struct pim_upstream *up, |
630 | bool_Bool update_mroute) |
631 | { |
632 | bool_Bool old_use_rpt; |
633 | bool_Bool new_use_rpt; |
634 | |
635 | if (pim_addr_is_any(up->sg.src)) |
636 | return; |
637 | |
638 | old_use_rpt = !!PIM_UPSTREAM_FLAG_TEST_USE_RPT(up->flags)((up->flags) & (1 << 20)); |
639 | |
640 | /* We will use the SPT (IIF=RPF_interface(S) if - |
641 | * 1. We have decided to join the SPT |
642 | * 2. We are FHR |
643 | * 3. Source is directly connected |
644 | * 4. We are RP (parent's IIF is lo or vrf-device) |
645 | * In all other cases the source will stay along the RPT and |
646 | * IIF=RPF_interface(RP). |
647 | */ |
648 | if (up->join_state == PIM_UPSTREAM_JOINED || |
649 | PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)((up->flags) & (1 << 2)) || |
650 | pim_if_connected_to_source( |
651 | up->rpf.source_nexthop.interface, |
652 | up->sg.src) || |
653 | /* XXX - need to switch this to a more efficient |
654 | * lookup API |
655 | */ |
656 | I_am_RP(up->pim, up->sg.grp)pim_rp_i_am_rp ((up->pim), (up->sg.grp))) |
657 | /* use SPT */ |
658 | PIM_UPSTREAM_FLAG_UNSET_USE_RPT(up->flags)((up->flags) &= ~(1 << 20)); |
659 | else |
660 | /* use RPT */ |
661 | PIM_UPSTREAM_FLAG_SET_USE_RPT(up->flags)((up->flags) |= (1 << 20)); |
662 | |
663 | new_use_rpt = !!PIM_UPSTREAM_FLAG_TEST_USE_RPT(up->flags)((up->flags) & (1 << 20)); |
664 | if (old_use_rpt != new_use_rpt) { |
665 | if (PIM_DEBUG_PIM_EVENTS(router->debugs & (1 << 0))) |
666 | zlog_debug("%s switched from %s to %s", up->sg_str,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s switched from %s to %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 668, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s switched from %s to %s"), .priority = (7), . ec = (0), .args = ("up->sg_str, old_use_rpt ? \"RPT\" : \"SPT\", new_use_rpt ? \"RPT\" : \"SPT\"" ), }; static const struct xref * const xref_p_111 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s switched from %s to %s"), up->sg_str, old_use_rpt ? "RPT" : "SPT", new_use_rpt ? "RPT" : "SPT"); } while (0) |
667 | old_use_rpt ? "RPT" : "SPT",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s switched from %s to %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 668, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s switched from %s to %s"), .priority = (7), . ec = (0), .args = ("up->sg_str, old_use_rpt ? \"RPT\" : \"SPT\", new_use_rpt ? \"RPT\" : \"SPT\"" ), }; static const struct xref * const xref_p_111 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s switched from %s to %s"), up->sg_str, old_use_rpt ? "RPT" : "SPT", new_use_rpt ? "RPT" : "SPT"); } while (0) |
668 | new_use_rpt ? "RPT" : "SPT")do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s switched from %s to %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 668, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s switched from %s to %s"), .priority = (7), . ec = (0), .args = ("up->sg_str, old_use_rpt ? \"RPT\" : \"SPT\", new_use_rpt ? \"RPT\" : \"SPT\"" ), }; static const struct xref * const xref_p_111 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s switched from %s to %s"), up->sg_str, old_use_rpt ? "RPT" : "SPT", new_use_rpt ? "RPT" : "SPT"); } while (0); |
669 | if (update_mroute) |
670 | pim_upstream_mroute_add(up->channel_oil, __func__); |
671 | } |
672 | } |
673 | |
674 | /* some events like RP change require re-evaluation of SGrpt across |
675 | * all groups |
676 | */ |
677 | void pim_upstream_reeval_use_rpt(struct pim_instance *pim) |
678 | { |
679 | struct pim_upstream *up; |
680 | |
681 | frr_each (rb_pim_upstream, &pim->upstream_head, up)for (up = rb_pim_upstream_first(&pim->upstream_head); up ; up = rb_pim_upstream_next(&pim->upstream_head, up)) { |
682 | if (pim_addr_is_any(up->sg.src)) |
683 | continue; |
684 | |
685 | pim_upstream_update_use_rpt(up, true1 /*update_mroute*/); |
686 | } |
687 | } |
688 | |
689 | void pim_upstream_switch(struct pim_instance *pim, struct pim_upstream *up, |
690 | enum pim_upstream_state new_state) |
691 | { |
692 | enum pim_upstream_state old_state = up->join_state; |
693 | |
694 | if (pim_addr_is_any(up->upstream_addr)) { |
695 | if (PIM_DEBUG_PIM_EVENTS(router->debugs & (1 << 0))) |
696 | zlog_debug("%s: RPF not configured for %s", __func__,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: RPF not configured for %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 697, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: RPF not configured for %s"), .priority = (7 ), .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_112 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: RPF not configured for %s" ), __func__, up->sg_str); } while (0) |
697 | up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: RPF not configured for %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 697, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: RPF not configured for %s"), .priority = (7 ), .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_112 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: RPF not configured for %s" ), __func__, up->sg_str); } while (0); |
698 | return; |
699 | } |
700 | |
701 | if (!up->rpf.source_nexthop.interface) { |
702 | if (PIM_DEBUG_PIM_EVENTS(router->debugs & (1 << 0))) |
703 | zlog_debug("%s: RP not reachable for %s", __func__,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: RP not reachable for %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 704, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: RP not reachable for %s"), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_113 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: RP not reachable for %s" ), __func__, up->sg_str); } while (0) |
704 | up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: RP not reachable for %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 704, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: RP not reachable for %s"), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_113 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: RP not reachable for %s" ), __func__, up->sg_str); } while (0); |
705 | return; |
706 | } |
707 | |
708 | if (PIM_DEBUG_PIM_EVENTS(router->debugs & (1 << 0))) { |
709 | zlog_debug("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 712, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s"), . priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim_upstream_state2str(up->join_state), pim_upstream_state2str(new_state)" ), }; static const struct xref * const xref_p_114 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s"), __func__ , up->sg_str, pim_upstream_state2str(up->join_state), pim_upstream_state2str (new_state)); } while (0) |
710 | __func__, up->sg_str,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 712, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s"), . priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim_upstream_state2str(up->join_state), pim_upstream_state2str(new_state)" ), }; static const struct xref * const xref_p_114 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s"), __func__ , up->sg_str, pim_upstream_state2str(up->join_state), pim_upstream_state2str (new_state)); } while (0) |
711 | pim_upstream_state2str(up->join_state),do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 712, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s"), . priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim_upstream_state2str(up->join_state), pim_upstream_state2str(new_state)" ), }; static const struct xref * const xref_p_114 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s"), __func__ , up->sg_str, pim_upstream_state2str(up->join_state), pim_upstream_state2str (new_state)); } while (0) |
712 | pim_upstream_state2str(new_state))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 712, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s"), . priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim_upstream_state2str(up->join_state), pim_upstream_state2str(new_state)" ), }; static const struct xref * const xref_p_114 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s"), __func__ , up->sg_str, pim_upstream_state2str(up->join_state), pim_upstream_state2str (new_state)); } while (0); |
713 | } |
714 | |
715 | up->join_state = new_state; |
716 | if (old_state != new_state) |
717 | up->state_transition = pim_time_monotonic_sec(); |
718 | |
719 | pim_upstream_update_assert_tracking_desired(up); |
720 | |
721 | if (new_state == PIM_UPSTREAM_JOINED) { |
722 | pim_upstream_inherited_olist_decide(pim, up); |
723 | if (old_state != PIM_UPSTREAM_JOINED) { |
724 | int old_fhr = PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)((up->flags) & (1 << 2)); |
725 | |
726 | pim_msdp_up_join_state_changed(pim, up); |
727 | if (pim_upstream_could_register(up)) { |
728 | PIM_UPSTREAM_FLAG_SET_FHR(up->flags)((up->flags) |= (1 << 2)); |
729 | if (!old_fhr |
730 | && PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(((up->flags) & (1 << 5)) |
731 | up->flags)((up->flags) & (1 << 5))) { |
732 | pim_upstream_keep_alive_timer_start( |
733 | up, pim->keep_alive_time); |
734 | pim_register_join(up); |
735 | } |
736 | } else { |
737 | pim_upstream_send_join(up); |
738 | join_timer_start(up); |
739 | } |
740 | } |
741 | if (old_state != new_state) |
742 | pim_upstream_update_use_rpt(up, true1 /*update_mroute*/); |
743 | } else { |
744 | bool_Bool old_use_rpt; |
745 | bool_Bool new_use_rpt; |
746 | bool_Bool send_xg_jp = false0; |
747 | |
748 | forward_off(up); |
749 | /* |
750 | * RFC 4601 Sec 4.5.7: |
751 | * JoinDesired(S,G) -> False, set SPTbit to false. |
752 | */ |
753 | if (!pim_addr_is_any(up->sg.src)) |
754 | up->sptbit = PIM_UPSTREAM_SPTBIT_FALSE; |
755 | |
756 | if (old_state == PIM_UPSTREAM_JOINED) |
757 | pim_msdp_up_join_state_changed(pim, up); |
758 | |
759 | if (old_state != new_state) { |
760 | old_use_rpt = |
761 | !!PIM_UPSTREAM_FLAG_TEST_USE_RPT(up->flags)((up->flags) & (1 << 20)); |
762 | pim_upstream_update_use_rpt(up, true1 /*update_mroute*/); |
763 | new_use_rpt = |
764 | !!PIM_UPSTREAM_FLAG_TEST_USE_RPT(up->flags)((up->flags) & (1 << 20)); |
765 | if (new_use_rpt && |
766 | (new_use_rpt != old_use_rpt) && |
767 | up->parent) |
768 | /* we have decided to switch from the SPT back |
769 | * to the RPT which means we need to cancel |
770 | * any previously sent SGrpt prunes immediately |
771 | */ |
772 | send_xg_jp = true1; |
773 | } |
774 | |
775 | /* IHR, Trigger SGRpt on *,G IIF to prune S,G from RPT towards |
776 | RP. |
777 | If I am RP for G then send S,G prune to its IIF. */ |
778 | if (pim_upstream_is_sg_rpt(up) && up->parent && |
779 | !I_am_RP(pim, up->sg.grp)pim_rp_i_am_rp ((pim), (up->sg.grp))) |
780 | send_xg_jp = true1; |
781 | |
782 | pim_jp_agg_single_upstream_send(&up->rpf, up, 0 /* prune */); |
783 | |
784 | if (send_xg_jp) { |
785 | if (PIM_DEBUG_PIM_TRACE_DETAIL(router->debugs & (1 << 6))) |
786 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("re-join RPT; *,G IIF %s S,G IIF %s " ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 793, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("re-join RPT; *,G IIF %s S,G IIF %s "), .priority = (7), .ec = (0), .args = ("up->parent->rpf.source_nexthop.interface ? up->parent->rpf.source_nexthop.interface->name : \"Unknown\", up->rpf.source_nexthop.interface ? up->rpf.source_nexthop.interface->name : \"Unknown\"" ), }; static const struct xref * const xref_p_115 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("re-join RPT; *,G IIF %s S,G IIF %s "), up-> parent->rpf.source_nexthop.interface ? up->parent->rpf .source_nexthop.interface->name : "Unknown", up->rpf.source_nexthop .interface ? up->rpf.source_nexthop.interface->name : "Unknown" ); } while (0) |
787 | "re-join RPT; *,G IIF %s S,G IIF %s ",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("re-join RPT; *,G IIF %s S,G IIF %s " ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 793, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("re-join RPT; *,G IIF %s S,G IIF %s "), .priority = (7), .ec = (0), .args = ("up->parent->rpf.source_nexthop.interface ? up->parent->rpf.source_nexthop.interface->name : \"Unknown\", up->rpf.source_nexthop.interface ? up->rpf.source_nexthop.interface->name : \"Unknown\"" ), }; static const struct xref * const xref_p_115 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("re-join RPT; *,G IIF %s S,G IIF %s "), up-> parent->rpf.source_nexthop.interface ? up->parent->rpf .source_nexthop.interface->name : "Unknown", up->rpf.source_nexthop .interface ? up->rpf.source_nexthop.interface->name : "Unknown" ); } while (0) |
788 | up->parent->rpf.source_nexthop.interface ?do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("re-join RPT; *,G IIF %s S,G IIF %s " ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 793, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("re-join RPT; *,G IIF %s S,G IIF %s "), .priority = (7), .ec = (0), .args = ("up->parent->rpf.source_nexthop.interface ? up->parent->rpf.source_nexthop.interface->name : \"Unknown\", up->rpf.source_nexthop.interface ? up->rpf.source_nexthop.interface->name : \"Unknown\"" ), }; static const struct xref * const xref_p_115 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("re-join RPT; *,G IIF %s S,G IIF %s "), up-> parent->rpf.source_nexthop.interface ? up->parent->rpf .source_nexthop.interface->name : "Unknown", up->rpf.source_nexthop .interface ? up->rpf.source_nexthop.interface->name : "Unknown" ); } while (0) |
789 | up->parent->rpf.source_nexthop.interface->namedo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("re-join RPT; *,G IIF %s S,G IIF %s " ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 793, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("re-join RPT; *,G IIF %s S,G IIF %s "), .priority = (7), .ec = (0), .args = ("up->parent->rpf.source_nexthop.interface ? up->parent->rpf.source_nexthop.interface->name : \"Unknown\", up->rpf.source_nexthop.interface ? up->rpf.source_nexthop.interface->name : \"Unknown\"" ), }; static const struct xref * const xref_p_115 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("re-join RPT; *,G IIF %s S,G IIF %s "), up-> parent->rpf.source_nexthop.interface ? up->parent->rpf .source_nexthop.interface->name : "Unknown", up->rpf.source_nexthop .interface ? up->rpf.source_nexthop.interface->name : "Unknown" ); } while (0) |
790 | : "Unknown",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("re-join RPT; *,G IIF %s S,G IIF %s " ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 793, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("re-join RPT; *,G IIF %s S,G IIF %s "), .priority = (7), .ec = (0), .args = ("up->parent->rpf.source_nexthop.interface ? up->parent->rpf.source_nexthop.interface->name : \"Unknown\", up->rpf.source_nexthop.interface ? up->rpf.source_nexthop.interface->name : \"Unknown\"" ), }; static const struct xref * const xref_p_115 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("re-join RPT; *,G IIF %s S,G IIF %s "), up-> parent->rpf.source_nexthop.interface ? up->parent->rpf .source_nexthop.interface->name : "Unknown", up->rpf.source_nexthop .interface ? up->rpf.source_nexthop.interface->name : "Unknown" ); } while (0) |
791 | up->rpf.source_nexthop.interface ?do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("re-join RPT; *,G IIF %s S,G IIF %s " ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 793, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("re-join RPT; *,G IIF %s S,G IIF %s "), .priority = (7), .ec = (0), .args = ("up->parent->rpf.source_nexthop.interface ? up->parent->rpf.source_nexthop.interface->name : \"Unknown\", up->rpf.source_nexthop.interface ? up->rpf.source_nexthop.interface->name : \"Unknown\"" ), }; static const struct xref * const xref_p_115 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("re-join RPT; *,G IIF %s S,G IIF %s "), up-> parent->rpf.source_nexthop.interface ? up->parent->rpf .source_nexthop.interface->name : "Unknown", up->rpf.source_nexthop .interface ? up->rpf.source_nexthop.interface->name : "Unknown" ); } while (0) |
792 | up->rpf.source_nexthop.interface->name :do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("re-join RPT; *,G IIF %s S,G IIF %s " ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 793, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("re-join RPT; *,G IIF %s S,G IIF %s "), .priority = (7), .ec = (0), .args = ("up->parent->rpf.source_nexthop.interface ? up->parent->rpf.source_nexthop.interface->name : \"Unknown\", up->rpf.source_nexthop.interface ? up->rpf.source_nexthop.interface->name : \"Unknown\"" ), }; static const struct xref * const xref_p_115 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("re-join RPT; *,G IIF %s S,G IIF %s "), up-> parent->rpf.source_nexthop.interface ? up->parent->rpf .source_nexthop.interface->name : "Unknown", up->rpf.source_nexthop .interface ? up->rpf.source_nexthop.interface->name : "Unknown" ); } while (0) |
793 | "Unknown")do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("re-join RPT; *,G IIF %s S,G IIF %s " ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 793, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("re-join RPT; *,G IIF %s S,G IIF %s "), .priority = (7), .ec = (0), .args = ("up->parent->rpf.source_nexthop.interface ? up->parent->rpf.source_nexthop.interface->name : \"Unknown\", up->rpf.source_nexthop.interface ? up->rpf.source_nexthop.interface->name : \"Unknown\"" ), }; static const struct xref * const xref_p_115 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("re-join RPT; *,G IIF %s S,G IIF %s "), up-> parent->rpf.source_nexthop.interface ? up->parent->rpf .source_nexthop.interface->name : "Unknown", up->rpf.source_nexthop .interface ? up->rpf.source_nexthop.interface->name : "Unknown" ); } while (0); |
794 | pim_jp_agg_single_upstream_send(&up->parent->rpf, |
795 | up->parent, |
796 | 1 /* (W,G) Join */); |
797 | } |
798 | join_timer_stop(up); |
799 | } |
800 | } |
801 | |
802 | int pim_upstream_compare(const struct pim_upstream *up1, |
803 | const struct pim_upstream *up2) |
804 | { |
805 | return pim_sgaddr_cmp(up1->sg, up2->sg); |
806 | } |
807 | |
808 | void pim_upstream_fill_static_iif(struct pim_upstream *up, |
809 | struct interface *incoming) |
810 | { |
811 | up->rpf.source_nexthop.interface = incoming; |
812 | |
813 | /* reset other parameters to matched a connected incoming interface */ |
814 | up->rpf.source_nexthop.mrib_nexthop_addr = PIMADDR_ANY(pim_addr){ }; |
815 | up->rpf.source_nexthop.mrib_metric_preference = |
816 | ZEBRA_CONNECT_DISTANCE_DEFAULT0; |
817 | up->rpf.source_nexthop.mrib_route_metric = 0; |
818 | up->rpf.rpf_addr = PIMADDR_ANY(pim_addr){ }; |
819 | } |
820 | |
821 | static struct pim_upstream *pim_upstream_new(struct pim_instance *pim, |
822 | pim_sgaddr *sg, |
823 | struct interface *incoming, |
824 | int flags, |
825 | struct pim_ifchannel *ch) |
826 | { |
827 | enum pim_rpf_result rpf_result; |
828 | struct pim_interface *pim_ifp; |
829 | struct pim_upstream *up; |
830 | |
831 | up = XCALLOC(MTYPE_PIM_UPSTREAM, sizeof(*up))qcalloc(MTYPE_PIM_UPSTREAM, sizeof(*up)); |
832 | |
833 | up->pim = pim; |
834 | up->sg = *sg; |
835 | snprintfrr(up->sg_str, sizeof(up->sg_str), "%pSG", sg); |
836 | if (ch) |
837 | ch->upstream = up; |
838 | |
839 | rb_pim_upstream_add(&pim->upstream_head, up); |
840 | /* Set up->upstream_addr as INADDR_ANY, if RP is not |
841 | * configured and retain the upstream data structure |
842 | */ |
843 | if (!pim_rp_set_upstream_addr(pim, &up->upstream_addr, sg->src, |
844 | sg->grp)) { |
845 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
846 | zlog_debug("%s: Received a (*,G) with no RP configured",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Received a (*,G) with no RP configured" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 847, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Received a (*,G) with no RP configured"), . priority = (7), .ec = (0), .args = ("__func__"), }; static const struct xref * const xref_p_116 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: Received a (*,G) with no RP configured" ), __func__); } while (0) |
847 | __func__)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Received a (*,G) with no RP configured" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 847, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Received a (*,G) with no RP configured"), . priority = (7), .ec = (0), .args = ("__func__"), }; static const struct xref * const xref_p_116 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: Received a (*,G) with no RP configured" ), __func__); } while (0); |
848 | } |
849 | |
850 | up->parent = pim_upstream_find_parent(pim, up); |
851 | if (pim_addr_is_any(up->sg.src)) { |
852 | up->sources = list_new(); |
853 | up->sources->cmp = |
854 | (int (*)(void *, void *))pim_upstream_compare; |
855 | } else |
856 | up->sources = NULL((void*)0); |
857 | |
858 | pim_upstream_find_new_children(pim, up); |
859 | up->flags = flags; |
860 | up->ref_count = 1; |
861 | up->t_join_timer = NULL((void*)0); |
862 | up->t_ka_timer = NULL((void*)0); |
863 | up->t_rs_timer = NULL((void*)0); |
864 | up->t_msdp_reg_timer = NULL((void*)0); |
865 | up->join_state = PIM_UPSTREAM_NOTJOINED; |
866 | up->reg_state = PIM_REG_NOINFO; |
867 | up->state_transition = pim_time_monotonic_sec(); |
868 | up->channel_oil = pim_channel_oil_add(pim, &up->sg, __func__); |
869 | up->sptbit = PIM_UPSTREAM_SPTBIT_FALSE; |
870 | |
871 | up->rpf.source_nexthop.interface = NULL((void*)0); |
872 | up->rpf.source_nexthop.mrib_nexthop_addr = PIMADDR_ANY(pim_addr){ }; |
873 | up->rpf.source_nexthop.mrib_metric_preference = |
874 | router->infinite_assert_metric.metric_preference; |
875 | up->rpf.source_nexthop.mrib_route_metric = |
876 | router->infinite_assert_metric.route_metric; |
877 | up->rpf.rpf_addr = PIMADDR_ANY(pim_addr){ }; |
878 | up->ifchannels = list_new(); |
879 | up->ifchannels->cmp = (int (*)(void *, void *))pim_ifchannel_compare; |
880 | |
881 | if (!pim_addr_is_any(up->sg.src)) { |
882 | wheel_add_item(pim->upstream_sg_wheel, up); |
883 | |
884 | /* Inherit the DF role from the parent (*, G) entry for |
885 | * VxLAN BUM groups |
886 | */ |
887 | if (up->parent |
888 | && PIM_UPSTREAM_FLAG_TEST_MLAG_VXLAN(up->parent->flags)((up->parent->flags) & (1 << 16)) |
889 | && PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->parent->flags)((up->parent->flags) & (1 << 17))) { |
890 | PIM_UPSTREAM_FLAG_SET_MLAG_NON_DF(up->flags)((up->flags) |= (1 << 17)); |
891 | if (PIM_DEBUG_VXLAN(router->debugs & (1 << 26))) |
892 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("upstream %s inherited mlag non-df flag from parent" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 894, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("upstream %s inherited mlag non-df flag from parent" ), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_117 __attribute__((used, section ("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("upstream %s inherited mlag non-df flag from parent" ), up->sg_str); } while (0) |
893 | "upstream %s inherited mlag non-df flag from parent",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("upstream %s inherited mlag non-df flag from parent" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 894, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("upstream %s inherited mlag non-df flag from parent" ), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_117 __attribute__((used, section ("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("upstream %s inherited mlag non-df flag from parent" ), up->sg_str); } while (0) |
894 | up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("upstream %s inherited mlag non-df flag from parent" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 894, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("upstream %s inherited mlag non-df flag from parent" ), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_117 __attribute__((used, section ("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("upstream %s inherited mlag non-df flag from parent" ), up->sg_str); } while (0); |
895 | } |
896 | } |
897 | |
898 | if (PIM_UPSTREAM_FLAG_TEST_STATIC_IIF(up->flags)((up->flags) & (1 << 10)) |
899 | || PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(up->flags)((up->flags) &(1 << 19))) { |
900 | pim_upstream_fill_static_iif(up, incoming); |
901 | pim_ifp = up->rpf.source_nexthop.interface->info; |
902 | assert(pim_ifp)({ static const struct xref_assert _xref __attribute__( (used )) = { .xref = { (((void*)0)), (XREFT_ASSERT), 902, "pimd/pim_upstream.c" , __func__, }, .expr = "pim_ifp", }; static const struct xref * const xref_p_118 __attribute__((used, section("xref_array" ))) = &(_xref.xref); if (__builtin_expect((pim_ifp) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void*)0)); } while (pim_ifp); }); |
903 | pim_upstream_update_use_rpt(up, |
904 | false0 /*update_mroute*/); |
905 | pim_upstream_mroute_iif_update(up->channel_oil, __func__); |
906 | |
907 | if (PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(up->flags)((up->flags) &(1 << 19))) { |
908 | /* |
909 | * Set the right RPF so that future changes will |
910 | * be right |
911 | */ |
912 | rpf_result = pim_rpf_update(pim, up, NULL((void*)0), __func__); |
Value stored to 'rpf_result' is never read | |
913 | pim_upstream_keep_alive_timer_start( |
914 | up, pim->keep_alive_time); |
915 | } |
916 | } else if (!pim_addr_is_any(up->upstream_addr)) { |
917 | pim_upstream_update_use_rpt(up, |
918 | false0 /*update_mroute*/); |
919 | rpf_result = pim_rpf_update(pim, up, NULL((void*)0), __func__); |
920 | if (rpf_result == PIM_RPF_FAILURE) { |
921 | up->channel_oil->oil_inherited_rescan = 1; |
922 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
923 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Attempting to create upstream(%s), Unable to RPF for source" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 925, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Attempting to create upstream(%s), Unable to RPF for source" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str" ), }; static const struct xref * const xref_p_119 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Attempting to create upstream(%s), Unable to RPF for source" ), __func__, up->sg_str); } while (0) |
924 | "%s: Attempting to create upstream(%s), Unable to RPF for source",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Attempting to create upstream(%s), Unable to RPF for source" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 925, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Attempting to create upstream(%s), Unable to RPF for source" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str" ), }; static const struct xref * const xref_p_119 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Attempting to create upstream(%s), Unable to RPF for source" ), __func__, up->sg_str); } while (0) |
925 | __func__, up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Attempting to create upstream(%s), Unable to RPF for source" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 925, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Attempting to create upstream(%s), Unable to RPF for source" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str" ), }; static const struct xref * const xref_p_119 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Attempting to create upstream(%s), Unable to RPF for source" ), __func__, up->sg_str); } while (0); |
926 | } |
927 | |
928 | /* Consider a case where (S,G,rpt) prune is received and this |
929 | * upstream is getting created due to that, then as per RFC |
930 | * until prune pending time we need to behave same as NOINFO |
931 | * state, therefore do not install if OIF is NULL until then |
932 | * This is for PIM Conformance PIM-SM 16.3 fix |
933 | * When the prune pending timer pop, this mroute will get |
934 | * installed with none as OIF */ |
935 | if (up->rpf.source_nexthop.interface && |
936 | !(pim_upstream_empty_inherited_olist(up) && (ch != NULL((void*)0)) && |
937 | PIM_IF_FLAG_TEST_S_G_RPT(ch->flags)((ch->flags) & (1 << 2)))) { |
938 | pim_upstream_mroute_iif_update(up->channel_oil, |
939 | __func__); |
940 | } |
941 | } |
942 | |
943 | /* send the entry to the MLAG peer */ |
944 | /* XXX - duplicate send is possible here if pim_rpf_update |
945 | * successfully resolved the nexthop |
946 | */ |
947 | if (pim_up_mlag_is_local(up) |
948 | || PIM_UPSTREAM_FLAG_TEST_MLAG_INTERFACE(up->flags)((up->flags)&(1 << 21))) |
949 | pim_mlag_up_local_add(pim, up); |
950 | |
951 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) { |
952 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Created Upstream %s upstream_addr %pPAs ref count %d increment" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 955, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Created Upstream %s upstream_addr %pPAs ref count %d increment" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, &up->upstream_addr, up->ref_count" ), }; static const struct xref * const xref_p_120 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Created Upstream %s upstream_addr %pPAs ref count %d increment" ), __func__, up->sg_str, &up->upstream_addr, up-> ref_count); } while (0) |
953 | "%s: Created Upstream %s upstream_addr %pPAs ref count %d increment",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Created Upstream %s upstream_addr %pPAs ref count %d increment" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 955, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Created Upstream %s upstream_addr %pPAs ref count %d increment" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, &up->upstream_addr, up->ref_count" ), }; static const struct xref * const xref_p_120 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Created Upstream %s upstream_addr %pPAs ref count %d increment" ), __func__, up->sg_str, &up->upstream_addr, up-> ref_count); } while (0) |
954 | __func__, up->sg_str, &up->upstream_addr,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Created Upstream %s upstream_addr %pPAs ref count %d increment" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 955, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Created Upstream %s upstream_addr %pPAs ref count %d increment" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, &up->upstream_addr, up->ref_count" ), }; static const struct xref * const xref_p_120 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Created Upstream %s upstream_addr %pPAs ref count %d increment" ), __func__, up->sg_str, &up->upstream_addr, up-> ref_count); } while (0) |
955 | up->ref_count)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Created Upstream %s upstream_addr %pPAs ref count %d increment" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 955, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Created Upstream %s upstream_addr %pPAs ref count %d increment" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, &up->upstream_addr, up->ref_count" ), }; static const struct xref * const xref_p_120 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Created Upstream %s upstream_addr %pPAs ref count %d increment" ), __func__, up->sg_str, &up->upstream_addr, up-> ref_count); } while (0); |
956 | } |
957 | |
958 | return up; |
959 | } |
960 | |
961 | uint32_t pim_up_mlag_local_cost(struct pim_upstream *up) |
962 | { |
963 | if (!(pim_up_mlag_is_local(up)) |
964 | && !(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE(1 << 21))) |
965 | return router->infinite_assert_metric.route_metric; |
966 | |
967 | if ((up->rpf.source_nexthop.interface == |
968 | up->pim->vxlan.peerlink_rif) && |
969 | (up->rpf.source_nexthop.mrib_route_metric < |
970 | (router->infinite_assert_metric.route_metric - |
971 | PIM_UPSTREAM_MLAG_PEERLINK_PLUS_METRIC10))) |
972 | return up->rpf.source_nexthop.mrib_route_metric + |
973 | PIM_UPSTREAM_MLAG_PEERLINK_PLUS_METRIC10; |
974 | |
975 | return up->rpf.source_nexthop.mrib_route_metric; |
976 | } |
977 | |
978 | uint32_t pim_up_mlag_peer_cost(struct pim_upstream *up) |
979 | { |
980 | if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_PEER(1 << 18))) |
981 | return router->infinite_assert_metric.route_metric; |
982 | |
983 | return up->mlag.peer_mrib_metric; |
984 | } |
985 | |
986 | struct pim_upstream *pim_upstream_find(struct pim_instance *pim, pim_sgaddr *sg) |
987 | { |
988 | struct pim_upstream lookup; |
989 | struct pim_upstream *up = NULL((void*)0); |
990 | |
991 | lookup.sg = *sg; |
992 | up = rb_pim_upstream_find(&pim->upstream_head, &lookup); |
993 | return up; |
994 | } |
995 | |
996 | struct pim_upstream *pim_upstream_find_or_add(pim_sgaddr *sg, |
997 | struct interface *incoming, |
998 | int flags, const char *name) |
999 | { |
1000 | struct pim_interface *pim_ifp = incoming->info; |
1001 | |
1002 | return (pim_upstream_add(pim_ifp->pim, sg, incoming, flags, name, |
1003 | NULL((void*)0))); |
1004 | } |
1005 | |
1006 | void pim_upstream_ref(struct pim_upstream *up, int flags, const char *name) |
1007 | { |
1008 | /* if a local MLAG reference is being created we need to send the mroute |
1009 | * to the peer |
1010 | */ |
1011 | if (!PIM_UPSTREAM_FLAG_TEST_MLAG_VXLAN(up->flags)((up->flags) & (1 << 16)) && |
1012 | PIM_UPSTREAM_FLAG_TEST_MLAG_VXLAN(flags)((flags) & (1 << 16))) { |
1013 | PIM_UPSTREAM_FLAG_SET_MLAG_VXLAN(up->flags)((up->flags) |= (1 << 16)); |
1014 | pim_mlag_up_local_add(up->pim, up); |
1015 | } |
1016 | |
1017 | /* when we go from non-FHR to FHR we need to re-eval traffic |
1018 | * forwarding path |
1019 | */ |
1020 | if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)((up->flags) & (1 << 2)) && |
1021 | PIM_UPSTREAM_FLAG_TEST_FHR(flags)((flags) & (1 << 2))) { |
1022 | PIM_UPSTREAM_FLAG_SET_FHR(up->flags)((up->flags) |= (1 << 2)); |
1023 | pim_upstream_update_use_rpt(up, true1 /*update_mroute*/); |
1024 | } |
1025 | |
1026 | /* re-eval joinDesired; clearing peer-msdp-sa flag can |
1027 | * cause JD to change |
1028 | */ |
1029 | if (!PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(up->flags)((up->flags) & (1 << 6)) && |
1030 | PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(flags)((flags) & (1 << 6))) { |
1031 | PIM_UPSTREAM_FLAG_SET_SRC_MSDP(up->flags)((up->flags) |= (1 << 6)); |
1032 | pim_upstream_update_join_desired(up->pim, up); |
1033 | } |
1034 | |
1035 | up->flags |= flags; |
1036 | ++up->ref_count; |
1037 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1038 | zlog_debug("%s(%s): upstream %s ref count %d increment",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s(%s): upstream %s ref count %d increment" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1039, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s(%s): upstream %s ref count %d increment"), . priority = (7), .ec = (0), .args = ("__func__, name, up->sg_str, up->ref_count" ), }; static const struct xref * const xref_p_121 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s(%s): upstream %s ref count %d increment"), __func__ , name, up->sg_str, up->ref_count); } while (0) |
1039 | __func__, name, up->sg_str, up->ref_count)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s(%s): upstream %s ref count %d increment" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1039, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s(%s): upstream %s ref count %d increment"), . priority = (7), .ec = (0), .args = ("__func__, name, up->sg_str, up->ref_count" ), }; static const struct xref * const xref_p_121 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s(%s): upstream %s ref count %d increment"), __func__ , name, up->sg_str, up->ref_count); } while (0); |
1040 | } |
1041 | |
1042 | struct pim_upstream *pim_upstream_add(struct pim_instance *pim, pim_sgaddr *sg, |
1043 | struct interface *incoming, int flags, |
1044 | const char *name, |
1045 | struct pim_ifchannel *ch) |
1046 | { |
1047 | struct pim_upstream *up = NULL((void*)0); |
1048 | int found = 0; |
1049 | |
1050 | up = pim_upstream_find(pim, sg); |
1051 | if (up) { |
1052 | pim_upstream_ref(up, flags, name); |
1053 | found = 1; |
1054 | } else { |
1055 | up = pim_upstream_new(pim, sg, incoming, flags, ch); |
1056 | } |
1057 | |
1058 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) { |
1059 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1065, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), .priority = (7), .ec = (0), .args = ("__func__, name, up->sg_str, &up->rpf.rpf_addr, up->rpf.source_nexthop.interface ? up->rpf.source_nexthop .interface->name : \"Unknown\", found, up->ref_count" ), }; static const struct xref * const xref_p_122 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), __func__, name, up->sg_str, &up->rpf.rpf_addr, up ->rpf.source_nexthop.interface ? up->rpf.source_nexthop .interface->name : "Unknown", found, up->ref_count); } while (0) |
1060 | "%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1065, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), .priority = (7), .ec = (0), .args = ("__func__, name, up->sg_str, &up->rpf.rpf_addr, up->rpf.source_nexthop.interface ? up->rpf.source_nexthop .interface->name : \"Unknown\", found, up->ref_count" ), }; static const struct xref * const xref_p_122 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), __func__, name, up->sg_str, &up->rpf.rpf_addr, up ->rpf.source_nexthop.interface ? up->rpf.source_nexthop .interface->name : "Unknown", found, up->ref_count); } while (0) |
1061 | __func__, name, up->sg_str, &up->rpf.rpf_addr,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1065, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), .priority = (7), .ec = (0), .args = ("__func__, name, up->sg_str, &up->rpf.rpf_addr, up->rpf.source_nexthop.interface ? up->rpf.source_nexthop .interface->name : \"Unknown\", found, up->ref_count" ), }; static const struct xref * const xref_p_122 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), __func__, name, up->sg_str, &up->rpf.rpf_addr, up ->rpf.source_nexthop.interface ? up->rpf.source_nexthop .interface->name : "Unknown", found, up->ref_count); } while (0) |
1062 | up->rpf.source_nexthop.interface ? up->rpf.source_nexthopdo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1065, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), .priority = (7), .ec = (0), .args = ("__func__, name, up->sg_str, &up->rpf.rpf_addr, up->rpf.source_nexthop.interface ? up->rpf.source_nexthop .interface->name : \"Unknown\", found, up->ref_count" ), }; static const struct xref * const xref_p_122 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), __func__, name, up->sg_str, &up->rpf.rpf_addr, up ->rpf.source_nexthop.interface ? up->rpf.source_nexthop .interface->name : "Unknown", found, up->ref_count); } while (0) |
1063 | .interface->namedo { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1065, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), .priority = (7), .ec = (0), .args = ("__func__, name, up->sg_str, &up->rpf.rpf_addr, up->rpf.source_nexthop.interface ? up->rpf.source_nexthop .interface->name : \"Unknown\", found, up->ref_count" ), }; static const struct xref * const xref_p_122 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), __func__, name, up->sg_str, &up->rpf.rpf_addr, up ->rpf.source_nexthop.interface ? up->rpf.source_nexthop .interface->name : "Unknown", found, up->ref_count); } while (0) |
1064 | : "Unknown",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1065, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), .priority = (7), .ec = (0), .args = ("__func__, name, up->sg_str, &up->rpf.rpf_addr, up->rpf.source_nexthop.interface ? up->rpf.source_nexthop .interface->name : \"Unknown\", found, up->ref_count" ), }; static const struct xref * const xref_p_122 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), __func__, name, up->sg_str, &up->rpf.rpf_addr, up ->rpf.source_nexthop.interface ? up->rpf.source_nexthop .interface->name : "Unknown", found, up->ref_count); } while (0) |
1065 | found, up->ref_count)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1065, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), .priority = (7), .ec = (0), .args = ("__func__, name, up->sg_str, &up->rpf.rpf_addr, up->rpf.source_nexthop.interface ? up->rpf.source_nexthop .interface->name : \"Unknown\", found, up->ref_count" ), }; static const struct xref * const xref_p_122 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d" ), __func__, name, up->sg_str, &up->rpf.rpf_addr, up ->rpf.source_nexthop.interface ? up->rpf.source_nexthop .interface->name : "Unknown", found, up->ref_count); } while (0); |
1066 | } |
1067 | |
1068 | return up; |
1069 | } |
1070 | |
1071 | /* |
1072 | * Passed in up must be the upstream for ch. starch is NULL if no |
1073 | * information |
1074 | * This function is copied over from |
1075 | * pim_upstream_evaluate_join_desired_interface but limited to |
1076 | * parent (*,G)'s includes/joins. |
1077 | */ |
1078 | int pim_upstream_eval_inherit_if(struct pim_upstream *up, |
1079 | struct pim_ifchannel *ch, |
1080 | struct pim_ifchannel *starch) |
1081 | { |
1082 | /* if there is an explicit prune for this interface we cannot |
1083 | * add it to the OIL |
1084 | */ |
1085 | if (ch) { |
1086 | if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags)((ch->flags) & (1 << 2))) |
1087 | return 0; |
1088 | } |
1089 | |
1090 | /* Check if the OIF can be inherited fron the (*,G) entry |
1091 | */ |
1092 | if (starch) { |
1093 | if (!pim_macro_ch_lost_assert(starch) |
1094 | && pim_macro_chisin_joins_or_include(starch)) |
1095 | return 1; |
1096 | } |
1097 | |
1098 | return 0; |
1099 | } |
1100 | |
1101 | /* |
1102 | * Passed in up must be the upstream for ch. starch is NULL if no |
1103 | * information |
1104 | */ |
1105 | int pim_upstream_evaluate_join_desired_interface(struct pim_upstream *up, |
1106 | struct pim_ifchannel *ch, |
1107 | struct pim_ifchannel *starch) |
1108 | { |
1109 | if (ch) { |
1110 | if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags)((ch->flags) & (1 << 2))) |
1111 | return 0; |
1112 | |
1113 | if (!pim_macro_ch_lost_assert(ch) |
1114 | && pim_macro_chisin_joins_or_include(ch)) |
1115 | return 1; |
1116 | } |
1117 | |
1118 | /* |
1119 | * joins (*,G) |
1120 | */ |
1121 | if (starch) { |
1122 | /* XXX: check on this with donald |
1123 | * we are looking for PIM_IF_FLAG_MASK_S_G_RPT in |
1124 | * upstream flags? |
1125 | */ |
1126 | #if 0 |
1127 | if (PIM_IF_FLAG_TEST_S_G_RPT(starch->upstream->flags)((starch->upstream->flags) & (1 << 2))) |
1128 | return 0; |
1129 | #endif |
1130 | |
1131 | if (!pim_macro_ch_lost_assert(starch) |
1132 | && pim_macro_chisin_joins_or_include(starch)) |
1133 | return 1; |
1134 | } |
1135 | |
1136 | return 0; |
1137 | } |
1138 | |
1139 | /* Returns true if immediate OIL is empty and is used to evaluate |
1140 | * JoinDesired. See pim_upstream_evaluate_join_desired. |
1141 | */ |
1142 | static bool_Bool pim_upstream_empty_immediate_olist(struct pim_instance *pim, |
1143 | struct pim_upstream *up) |
1144 | { |
1145 | struct interface *ifp; |
1146 | struct pim_ifchannel *ch; |
1147 | |
1148 | FOR_ALL_INTERFACES (pim->vrf, ifp)if (pim->vrf) for ((ifp) = if_name_head_RB_MIN((&pim-> vrf->ifaces_by_name)); (ifp) != ((void*)0); (ifp) = if_name_head_RB_NEXT ((ifp))) { |
1149 | if (!ifp->info) |
1150 | continue; |
1151 | |
1152 | ch = pim_ifchannel_find(ifp, &up->sg); |
1153 | if (!ch) |
1154 | continue; |
1155 | |
1156 | /* If we have even one immediate OIF we can return with |
1157 | * not-empty |
1158 | */ |
1159 | if (pim_upstream_evaluate_join_desired_interface(up, ch, |
1160 | NULL((void*)0) /* starch */)) |
1161 | return false0; |
1162 | } /* scan iface channel list */ |
1163 | |
1164 | /* immediate_oil is empty */ |
1165 | return true1; |
1166 | } |
1167 | |
1168 | |
1169 | static inline bool_Bool pim_upstream_is_msdp_peer_sa(struct pim_upstream *up) |
1170 | { |
1171 | return PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(up->flags)((up->flags) & (1 << 6)); |
1172 | } |
1173 | |
1174 | /* |
1175 | * bool JoinDesired(*,G) { |
1176 | * if (immediate_olist(*,G) != NULL) |
1177 | * return TRUE |
1178 | * else |
1179 | * return FALSE |
1180 | * } |
1181 | * |
1182 | * bool JoinDesired(S,G) { |
1183 | * return( immediate_olist(S,G) != NULL |
1184 | * OR ( KeepaliveTimer(S,G) is running |
1185 | * AND inherited_olist(S,G) != NULL ) ) |
1186 | * } |
1187 | */ |
1188 | bool_Bool pim_upstream_evaluate_join_desired(struct pim_instance *pim, |
1189 | struct pim_upstream *up) |
1190 | { |
1191 | bool_Bool empty_imm_oil; |
1192 | bool_Bool empty_inh_oil; |
1193 | |
1194 | empty_imm_oil = pim_upstream_empty_immediate_olist(pim, up); |
1195 | |
1196 | /* (*,G) */ |
1197 | if (pim_addr_is_any(up->sg.src)) |
1198 | return !empty_imm_oil; |
1199 | |
1200 | /* (S,G) */ |
1201 | if (!empty_imm_oil) |
1202 | return true1; |
1203 | empty_inh_oil = pim_upstream_empty_inherited_olist(up); |
1204 | if (!empty_inh_oil && |
1205 | (pim_upstream_is_kat_running(up) || |
1206 | pim_upstream_is_msdp_peer_sa(up))) |
1207 | return true1; |
1208 | |
1209 | return false0; |
1210 | } |
1211 | |
1212 | /* |
1213 | See also pim_upstream_evaluate_join_desired() above. |
1214 | */ |
1215 | void pim_upstream_update_join_desired(struct pim_instance *pim, |
1216 | struct pim_upstream *up) |
1217 | { |
1218 | int was_join_desired; /* boolean */ |
1219 | int is_join_desired; /* boolean */ |
1220 | |
1221 | was_join_desired = PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags)((up->flags) & (1 << 0)); |
1222 | |
1223 | is_join_desired = pim_upstream_evaluate_join_desired(pim, up); |
1224 | if (is_join_desired) |
1225 | PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED(up->flags)((up->flags) |= (1 << 0)); |
1226 | else |
1227 | PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED(up->flags)((up->flags) &= ~(1 << 0)); |
1228 | |
1229 | /* switched from false to true */ |
1230 | if (is_join_desired && (up->join_state == PIM_UPSTREAM_NOTJOINED)) { |
1231 | pim_upstream_switch(pim, up, PIM_UPSTREAM_JOINED); |
1232 | return; |
1233 | } |
1234 | |
1235 | /* switched from true to false */ |
1236 | if (!is_join_desired && was_join_desired) { |
1237 | pim_upstream_switch(pim, up, PIM_UPSTREAM_NOTJOINED); |
1238 | return; |
1239 | } |
1240 | } |
1241 | |
1242 | /* |
1243 | RFC 4601 4.5.7. Sending (S,G) Join/Prune Messages |
1244 | Transitions from Joined State |
1245 | RPF'(S,G) GenID changes |
1246 | |
1247 | The upstream (S,G) state machine remains in Joined state. If the |
1248 | Join Timer is set to expire in more than t_override seconds, reset |
1249 | it so that it expires after t_override seconds. |
1250 | */ |
1251 | void pim_upstream_rpf_genid_changed(struct pim_instance *pim, |
1252 | pim_addr neigh_addr) |
1253 | { |
1254 | struct pim_upstream *up; |
1255 | |
1256 | /* |
1257 | * Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr |
1258 | */ |
1259 | frr_each (rb_pim_upstream, &pim->upstream_head, up)for (up = rb_pim_upstream_first(&pim->upstream_head); up ; up = rb_pim_upstream_next(&pim->upstream_head, up)) { |
1260 | pim_addr rpf_addr; |
1261 | |
1262 | rpf_addr = up->rpf.rpf_addr; |
1263 | |
1264 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1265 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1270, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), .priority = (7), .ec = (0), .args = ("__func__, &neigh_addr, up->sg_str, pim->vrf->name, up->join_state == PIM_UPSTREAM_JOINED, &rpf_addr" ), }; static const struct xref * const xref_p_123 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), __func__, &neigh_addr, up->sg_str, pim->vrf-> name, up->join_state == PIM_UPSTREAM_JOINED, &rpf_addr ); } while (0) |
1266 | "%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1270, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), .priority = (7), .ec = (0), .args = ("__func__, &neigh_addr, up->sg_str, pim->vrf->name, up->join_state == PIM_UPSTREAM_JOINED, &rpf_addr" ), }; static const struct xref * const xref_p_123 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), __func__, &neigh_addr, up->sg_str, pim->vrf-> name, up->join_state == PIM_UPSTREAM_JOINED, &rpf_addr ); } while (0) |
1267 | __func__, &neigh_addr, up->sg_str,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1270, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), .priority = (7), .ec = (0), .args = ("__func__, &neigh_addr, up->sg_str, pim->vrf->name, up->join_state == PIM_UPSTREAM_JOINED, &rpf_addr" ), }; static const struct xref * const xref_p_123 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), __func__, &neigh_addr, up->sg_str, pim->vrf-> name, up->join_state == PIM_UPSTREAM_JOINED, &rpf_addr ); } while (0) |
1268 | pim->vrf->name,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1270, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), .priority = (7), .ec = (0), .args = ("__func__, &neigh_addr, up->sg_str, pim->vrf->name, up->join_state == PIM_UPSTREAM_JOINED, &rpf_addr" ), }; static const struct xref * const xref_p_123 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), __func__, &neigh_addr, up->sg_str, pim->vrf-> name, up->join_state == PIM_UPSTREAM_JOINED, &rpf_addr ); } while (0) |
1269 | up->join_state == PIM_UPSTREAM_JOINED,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1270, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), .priority = (7), .ec = (0), .args = ("__func__, &neigh_addr, up->sg_str, pim->vrf->name, up->join_state == PIM_UPSTREAM_JOINED, &rpf_addr" ), }; static const struct xref * const xref_p_123 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), __func__, &neigh_addr, up->sg_str, pim->vrf-> name, up->join_state == PIM_UPSTREAM_JOINED, &rpf_addr ); } while (0) |
1270 | &rpf_addr)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1270, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), .priority = (7), .ec = (0), .args = ("__func__, &neigh_addr, up->sg_str, pim->vrf->name, up->join_state == PIM_UPSTREAM_JOINED, &rpf_addr" ), }; static const struct xref * const xref_p_123 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: matching neigh=%pPA against upstream (S,G)=%s[%s] joined=%d rpf_addr=%pPA" ), __func__, &neigh_addr, up->sg_str, pim->vrf-> name, up->join_state == PIM_UPSTREAM_JOINED, &rpf_addr ); } while (0); |
1271 | |
1272 | /* consider only (S,G) upstream in Joined state */ |
1273 | if (up->join_state != PIM_UPSTREAM_JOINED) |
1274 | continue; |
1275 | |
1276 | /* match RPF'(S,G)=neigh_addr */ |
1277 | if (pim_addr_cmp(rpf_addr, neigh_addr)) |
1278 | continue; |
1279 | |
1280 | pim_upstream_join_timer_decrease_to_t_override( |
1281 | "RPF'(S,G) GenID change", up); |
1282 | } |
1283 | } |
1284 | |
1285 | |
1286 | void pim_upstream_rpf_interface_changed(struct pim_upstream *up, |
1287 | struct interface *old_rpf_ifp) |
1288 | { |
1289 | struct listnode *chnode; |
1290 | struct listnode *chnextnode; |
1291 | struct pim_ifchannel *ch; |
1292 | |
1293 | /* search all ifchannels */ |
1294 | for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)(chnode) = ((up->ifchannels) ? ((up->ifchannels)->head ) : ((void*)0)), ((ch) = ((void*)0)); (chnode) != ((void*)0) && ((ch) = ((({ static const struct xref_assert _xref __attribute__ ( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 1294, "pimd/pim_upstream.c" , __func__, }, .expr = "chnode", }; static const struct xref * const xref_p_124 __attribute__((used, section("xref_array")) ) = &(_xref.xref); if (__builtin_expect((chnode) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void*)0)); } while (chnode); }), ({ static const struct xref_assert _xref __attribute__ ( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 1294, "pimd/pim_upstream.c" , __func__, }, .expr = "(chnode)->data != NULL", }; static const struct xref * const xref_p_125 __attribute__((used, section ("xref_array"))) = &(_xref.xref); if (__builtin_expect((( chnode)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed (&_xref, ((void*)0)); } while ((chnode)->data != ((void *)0)); }), (chnode)->data)), (chnextnode) = chnode->next , 1); (chnode) = (chnextnode), ((ch) = ((void*)0))) { |
1295 | if (ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) { |
1296 | if ( |
1297 | /* RPF_interface(S) was NOT I */ |
1298 | (old_rpf_ifp == ch->interface) && |
1299 | /* RPF_interface(S) stopped being I */ |
1300 | (ch->upstream->rpf.source_nexthop |
1301 | .interface) && |
1302 | (ch->upstream->rpf.source_nexthop |
1303 | .interface != ch->interface)) { |
1304 | assert_action_a5(ch); |
1305 | } |
1306 | } /* PIM_IFASSERT_I_AM_LOSER */ |
1307 | |
1308 | pim_ifchannel_update_assert_tracking_desired(ch); |
1309 | } |
1310 | } |
1311 | |
1312 | void pim_upstream_update_could_assert(struct pim_upstream *up) |
1313 | { |
1314 | struct listnode *chnode; |
1315 | struct listnode *chnextnode; |
1316 | struct pim_ifchannel *ch; |
1317 | |
1318 | /* scan per-interface (S,G) state */ |
1319 | for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)(chnode) = ((up->ifchannels) ? ((up->ifchannels)->head ) : ((void*)0)), ((ch) = ((void*)0)); (chnode) != ((void*)0) && ((ch) = ((({ static const struct xref_assert _xref __attribute__ ( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 1319, "pimd/pim_upstream.c" , __func__, }, .expr = "chnode", }; static const struct xref * const xref_p_126 __attribute__((used, section("xref_array")) ) = &(_xref.xref); if (__builtin_expect((chnode) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void*)0)); } while (chnode); }), ({ static const struct xref_assert _xref __attribute__ ( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 1319, "pimd/pim_upstream.c" , __func__, }, .expr = "(chnode)->data != NULL", }; static const struct xref * const xref_p_127 __attribute__((used, section ("xref_array"))) = &(_xref.xref); if (__builtin_expect((( chnode)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed (&_xref, ((void*)0)); } while ((chnode)->data != ((void *)0)); }), (chnode)->data)), (chnextnode) = chnode->next , 1); (chnode) = (chnextnode), ((ch) = ((void*)0))) { |
1320 | pim_ifchannel_update_could_assert(ch); |
1321 | } /* scan iface channel list */ |
1322 | } |
1323 | |
1324 | void pim_upstream_update_my_assert_metric(struct pim_upstream *up) |
1325 | { |
1326 | struct listnode *chnode; |
1327 | struct listnode *chnextnode; |
1328 | struct pim_ifchannel *ch; |
1329 | |
1330 | /* scan per-interface (S,G) state */ |
1331 | for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)(chnode) = ((up->ifchannels) ? ((up->ifchannels)->head ) : ((void*)0)), ((ch) = ((void*)0)); (chnode) != ((void*)0) && ((ch) = ((({ static const struct xref_assert _xref __attribute__ ( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 1331, "pimd/pim_upstream.c" , __func__, }, .expr = "chnode", }; static const struct xref * const xref_p_128 __attribute__((used, section("xref_array")) ) = &(_xref.xref); if (__builtin_expect((chnode) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void*)0)); } while (chnode); }), ({ static const struct xref_assert _xref __attribute__ ( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 1331, "pimd/pim_upstream.c" , __func__, }, .expr = "(chnode)->data != NULL", }; static const struct xref * const xref_p_129 __attribute__((used, section ("xref_array"))) = &(_xref.xref); if (__builtin_expect((( chnode)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed (&_xref, ((void*)0)); } while ((chnode)->data != ((void *)0)); }), (chnode)->data)), (chnextnode) = chnode->next , 1); (chnode) = (chnextnode), ((ch) = ((void*)0))) { |
1332 | pim_ifchannel_update_my_assert_metric(ch); |
1333 | |
1334 | } /* scan iface channel list */ |
1335 | } |
1336 | |
1337 | static void pim_upstream_update_assert_tracking_desired(struct pim_upstream *up) |
1338 | { |
1339 | struct listnode *chnode; |
1340 | struct listnode *chnextnode; |
1341 | struct pim_interface *pim_ifp; |
1342 | struct pim_ifchannel *ch; |
1343 | |
1344 | /* scan per-interface (S,G) state */ |
1345 | for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)(chnode) = ((up->ifchannels) ? ((up->ifchannels)->head ) : ((void*)0)), ((ch) = ((void*)0)); (chnode) != ((void*)0) && ((ch) = ((({ static const struct xref_assert _xref __attribute__ ( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 1345, "pimd/pim_upstream.c" , __func__, }, .expr = "chnode", }; static const struct xref * const xref_p_130 __attribute__((used, section("xref_array")) ) = &(_xref.xref); if (__builtin_expect((chnode) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void*)0)); } while (chnode); }), ({ static const struct xref_assert _xref __attribute__ ( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 1345, "pimd/pim_upstream.c" , __func__, }, .expr = "(chnode)->data != NULL", }; static const struct xref * const xref_p_131 __attribute__((used, section ("xref_array"))) = &(_xref.xref); if (__builtin_expect((( chnode)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed (&_xref, ((void*)0)); } while ((chnode)->data != ((void *)0)); }), (chnode)->data)), (chnextnode) = chnode->next , 1); (chnode) = (chnextnode), ((ch) = ((void*)0))) { |
1346 | if (!ch->interface) |
1347 | continue; |
1348 | pim_ifp = ch->interface->info; |
1349 | if (!pim_ifp) |
1350 | continue; |
1351 | |
1352 | pim_ifchannel_update_assert_tracking_desired(ch); |
1353 | |
1354 | } /* scan iface channel list */ |
1355 | } |
1356 | |
1357 | /* When kat is stopped CouldRegister goes to false so we need to |
1358 | * transition the (S, G) on FHR to NI state and remove reg tunnel |
1359 | * from the OIL */ |
1360 | static void pim_upstream_fhr_kat_expiry(struct pim_instance *pim, |
1361 | struct pim_upstream *up) |
1362 | { |
1363 | if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)((up->flags) & (1 << 2))) |
1364 | return; |
1365 | |
1366 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1367 | zlog_debug("kat expired on %s; clear fhr reg state",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("kat expired on %s; clear fhr reg state" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1368, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("kat expired on %s; clear fhr reg state"), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_132 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("kat expired on %s; clear fhr reg state" ), up->sg_str); } while (0) |
1368 | up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("kat expired on %s; clear fhr reg state" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1368, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("kat expired on %s; clear fhr reg state"), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_132 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("kat expired on %s; clear fhr reg state" ), up->sg_str); } while (0); |
1369 | |
1370 | /* stop reg-stop timer */ |
1371 | EVENT_OFF(up->t_rs_timer)do { if ((up->t_rs_timer)) event_cancel(&(up->t_rs_timer )); } while (0); |
1372 | /* remove regiface from the OIL if it is there*/ |
1373 | pim_channel_del_oif(up->channel_oil, pim->regiface, |
1374 | PIM_OIF_FLAG_PROTO_PIM(1 << 1), __func__); |
1375 | /* clear the register state */ |
1376 | up->reg_state = PIM_REG_NOINFO; |
1377 | PIM_UPSTREAM_FLAG_UNSET_FHR(up->flags)((up->flags) &= ~(1 << 2)); |
1378 | } |
1379 | |
1380 | /* When kat is started CouldRegister can go to true. And if it does we |
1381 | * need to transition the (S, G) on FHR to JOINED state and add reg tunnel |
1382 | * to the OIL */ |
1383 | static void pim_upstream_fhr_kat_start(struct pim_upstream *up) |
1384 | { |
1385 | if (pim_upstream_could_register(up)) { |
1386 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1387 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("kat started on %s; set fhr reg state to joined" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1389, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("kat started on %s; set fhr reg state to joined" ), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_133 __attribute__((used, section ("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("kat started on %s; set fhr reg state to joined" ), up->sg_str); } while (0) |
1388 | "kat started on %s; set fhr reg state to joined",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("kat started on %s; set fhr reg state to joined" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1389, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("kat started on %s; set fhr reg state to joined" ), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_133 __attribute__((used, section ("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("kat started on %s; set fhr reg state to joined" ), up->sg_str); } while (0) |
1389 | up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("kat started on %s; set fhr reg state to joined" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1389, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("kat started on %s; set fhr reg state to joined" ), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_133 __attribute__((used, section ("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("kat started on %s; set fhr reg state to joined" ), up->sg_str); } while (0); |
1390 | |
1391 | PIM_UPSTREAM_FLAG_SET_FHR(up->flags)((up->flags) |= (1 << 2)); |
1392 | if (up->reg_state == PIM_REG_NOINFO) |
1393 | pim_register_join(up); |
1394 | pim_upstream_update_use_rpt(up, true1 /*update_mroute*/); |
1395 | } |
1396 | } |
1397 | |
1398 | /* |
1399 | * On an RP, the PMBR value must be cleared when the |
1400 | * Keepalive Timer expires |
1401 | * KAT expiry indicates that flow is inactive. If the flow was created or |
1402 | * maintained by activity now is the time to deref it. |
1403 | */ |
1404 | struct pim_upstream *pim_upstream_keep_alive_timer_proc( |
1405 | struct pim_upstream *up) |
1406 | { |
1407 | struct pim_instance *pim; |
1408 | |
1409 | pim = up->channel_oil->pim; |
1410 | |
1411 | if (PIM_UPSTREAM_FLAG_TEST_DISABLE_KAT_EXPIRY(up->flags)((up->flags) & (1 << 9))) { |
1412 | /* if the router is a PIM vxlan encapsulator we prevent expiry |
1413 | * of KAT as the mroute is pre-setup without any traffic |
1414 | */ |
1415 | pim_upstream_keep_alive_timer_start(up, pim->keep_alive_time); |
1416 | return up; |
1417 | } |
1418 | |
1419 | if (I_am_RP(pim, up->sg.grp)pim_rp_i_am_rp ((pim), (up->sg.grp))) { |
1420 | /* |
1421 | * Handle Border Router |
1422 | * We need to do more here :) |
1423 | * But this is the start. |
1424 | */ |
1425 | } |
1426 | |
1427 | /* source is no longer active - pull the SA from MSDP's cache */ |
1428 | pim_msdp_sa_local_del(pim, &up->sg); |
1429 | |
1430 | /* JoinDesired can change when KAT is started or stopped */ |
1431 | pim_upstream_update_join_desired(pim, up); |
1432 | |
1433 | /* if entry was created because of activity we need to deref it */ |
1434 | if (PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags)((up->flags) & (1 << 5))) { |
1435 | pim_upstream_fhr_kat_expiry(pim, up); |
1436 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1437 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("kat expired on %s[%s]; remove stream reference" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1439, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("kat expired on %s[%s]; remove stream reference" ), .priority = (7), .ec = (0), .args = ("up->sg_str, pim->vrf->name" ), }; static const struct xref * const xref_p_134 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("kat expired on %s[%s]; remove stream reference" ), up->sg_str, pim->vrf->name); } while (0) |
1438 | "kat expired on %s[%s]; remove stream reference",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("kat expired on %s[%s]; remove stream reference" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1439, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("kat expired on %s[%s]; remove stream reference" ), .priority = (7), .ec = (0), .args = ("up->sg_str, pim->vrf->name" ), }; static const struct xref * const xref_p_134 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("kat expired on %s[%s]; remove stream reference" ), up->sg_str, pim->vrf->name); } while (0) |
1439 | up->sg_str, pim->vrf->name)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("kat expired on %s[%s]; remove stream reference" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1439, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("kat expired on %s[%s]; remove stream reference" ), .priority = (7), .ec = (0), .args = ("up->sg_str, pim->vrf->name" ), }; static const struct xref * const xref_p_134 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("kat expired on %s[%s]; remove stream reference" ), up->sg_str, pim->vrf->name); } while (0); |
1440 | PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(up->flags)((up->flags) &= ~(1 << 5)); |
1441 | |
1442 | /* Return if upstream entry got deleted.*/ |
1443 | if (!pim_upstream_del(pim, up, __func__)) |
1444 | return NULL((void*)0); |
1445 | } |
1446 | if (PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(up->flags)((up->flags) &(1 << 19))) { |
1447 | PIM_UPSTREAM_FLAG_UNSET_SRC_NOCACHE(up->flags)((up->flags) &= ~(1 << 19)); |
1448 | |
1449 | if (!pim_upstream_del(pim, up, __func__)) |
1450 | return NULL((void*)0); |
1451 | } |
1452 | |
1453 | /* upstream reference would have been added to track the local |
1454 | * membership if it is LHR. We have to clear it when KAT expires. |
1455 | * Otherwise would result in stale entry with uncleared ref count. |
1456 | */ |
1457 | if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(up->flags)((up->flags) & (1 << 8))) { |
1458 | struct pim_upstream *parent = up->parent; |
1459 | |
1460 | PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(up->flags)((up->flags) &= ~(1 << 8)); |
1461 | up = pim_upstream_del(pim, up, __func__); |
1462 | |
1463 | if (parent) { |
1464 | pim_jp_agg_single_upstream_send(&parent->rpf, parent, |
1465 | true1); |
1466 | } |
1467 | } |
1468 | |
1469 | return up; |
1470 | } |
1471 | static void pim_upstream_keep_alive_timer(struct event *t) |
1472 | { |
1473 | struct pim_upstream *up; |
1474 | |
1475 | up = EVENT_ARG(t)((t)->arg); |
1476 | |
1477 | /* pull the stats and re-check */ |
1478 | if (pim_upstream_sg_running_proc(up)) |
1479 | /* kat was restarted because of new activity */ |
1480 | return; |
1481 | |
1482 | pim_upstream_keep_alive_timer_proc(up); |
1483 | } |
1484 | |
1485 | void pim_upstream_keep_alive_timer_start(struct pim_upstream *up, uint32_t time) |
1486 | { |
1487 | if (!PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags)((up->flags) & (1 << 5))) { |
1488 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1489 | zlog_debug("kat start on %s with no stream reference",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("kat start on %s with no stream reference" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1490, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("kat start on %s with no stream reference"), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_135 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("kat start on %s with no stream reference" ), up->sg_str); } while (0) |
1490 | up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("kat start on %s with no stream reference" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1490, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("kat start on %s with no stream reference"), .priority = (7), .ec = (0), .args = ("up->sg_str"), }; static const struct xref * const xref_p_135 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("kat start on %s with no stream reference" ), up->sg_str); } while (0); |
1491 | } |
1492 | EVENT_OFF(up->t_ka_timer)do { if ((up->t_ka_timer)) event_cancel(&(up->t_ka_timer )); } while (0); |
1493 | event_add_timer(router->master, pim_upstream_keep_alive_timer, up, time,({ static const struct xref_eventsched _xref __attribute__( ( used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 1494, "pimd/pim_upstream.c" , __func__, }, .funcname = "pim_upstream_keep_alive_timer", . dest = "&up->t_ka_timer", .event_type = EVENT_TIMER, } ; static const struct xref * const xref_p_136 __attribute__(( used, section("xref_array"))) = &(_xref.xref); _event_add_timer (&_xref, router->master, pim_upstream_keep_alive_timer , up, time, &up->t_ka_timer); }) |
1494 | &up->t_ka_timer)({ static const struct xref_eventsched _xref __attribute__( ( used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 1494, "pimd/pim_upstream.c" , __func__, }, .funcname = "pim_upstream_keep_alive_timer", . dest = "&up->t_ka_timer", .event_type = EVENT_TIMER, } ; static const struct xref * const xref_p_136 __attribute__(( used, section("xref_array"))) = &(_xref.xref); _event_add_timer (&_xref, router->master, pim_upstream_keep_alive_timer , up, time, &up->t_ka_timer); }); |
1495 | |
1496 | /* any time keepalive is started against a SG we will have to |
1497 | * re-evaluate our active source database */ |
1498 | pim_msdp_sa_local_update(up); |
1499 | /* JoinDesired can change when KAT is started or stopped */ |
1500 | pim_upstream_update_join_desired(up->pim, up); |
1501 | } |
1502 | |
1503 | /* MSDP on RP needs to know if a source is registerable to this RP */ |
1504 | static void pim_upstream_msdp_reg_timer(struct event *t) |
1505 | { |
1506 | struct pim_upstream *up = EVENT_ARG(t)((t)->arg); |
1507 | struct pim_instance *pim = up->channel_oil->pim; |
1508 | |
1509 | /* source is no longer active - pull the SA from MSDP's cache */ |
1510 | pim_msdp_sa_local_del(pim, &up->sg); |
1511 | } |
1512 | |
1513 | void pim_upstream_msdp_reg_timer_start(struct pim_upstream *up) |
1514 | { |
1515 | EVENT_OFF(up->t_msdp_reg_timer)do { if ((up->t_msdp_reg_timer)) event_cancel(&(up-> t_msdp_reg_timer)); } while (0); |
1516 | event_add_timer(router->master, pim_upstream_msdp_reg_timer, up,({ static const struct xref_eventsched _xref __attribute__( ( used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 1517, "pimd/pim_upstream.c" , __func__, }, .funcname = "pim_upstream_msdp_reg_timer", .dest = "&up->t_msdp_reg_timer", .event_type = EVENT_TIMER, }; static const struct xref * const xref_p_137 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); _event_add_timer (&_xref, router->master, pim_upstream_msdp_reg_timer, up , (3 * (1.5 * router->register_suppress_time)), &up-> t_msdp_reg_timer); }) |
1517 | PIM_MSDP_REG_RXED_PERIOD, &up->t_msdp_reg_timer)({ static const struct xref_eventsched _xref __attribute__( ( used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 1517, "pimd/pim_upstream.c" , __func__, }, .funcname = "pim_upstream_msdp_reg_timer", .dest = "&up->t_msdp_reg_timer", .event_type = EVENT_TIMER, }; static const struct xref * const xref_p_137 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); _event_add_timer (&_xref, router->master, pim_upstream_msdp_reg_timer, up , (3 * (1.5 * router->register_suppress_time)), &up-> t_msdp_reg_timer); }); |
1518 | |
1519 | pim_msdp_sa_local_update(up); |
1520 | } |
1521 | |
1522 | /* |
1523 | * 4.2.1 Last-Hop Switchover to the SPT |
1524 | * |
1525 | * In Sparse-Mode PIM, last-hop routers join the shared tree towards the |
1526 | * RP. Once traffic from sources to joined groups arrives at a last-hop |
1527 | * router, it has the option of switching to receive the traffic on a |
1528 | * shortest path tree (SPT). |
1529 | * |
1530 | * The decision for a router to switch to the SPT is controlled as |
1531 | * follows: |
1532 | * |
1533 | * void |
1534 | * CheckSwitchToSpt(S,G) { |
1535 | * if ( ( pim_include(*,G) (-) pim_exclude(S,G) |
1536 | * (+) pim_include(S,G) != NULL ) |
1537 | * AND SwitchToSptDesired(S,G) ) { |
1538 | * # Note: Restarting the KAT will result in the SPT switch |
1539 | * set KeepaliveTimer(S,G) to Keepalive_Period |
1540 | * } |
1541 | * } |
1542 | * |
1543 | * SwitchToSptDesired(S,G) is a policy function that is implementation |
1544 | * defined. An "infinite threshold" policy can be implemented by making |
1545 | * SwitchToSptDesired(S,G) return false all the time. A "switch on |
1546 | * first packet" policy can be implemented by making |
1547 | * SwitchToSptDesired(S,G) return true once a single packet has been |
1548 | * received for the source and group. |
1549 | */ |
1550 | int pim_upstream_switch_to_spt_desired_on_rp(struct pim_instance *pim, |
1551 | pim_sgaddr *sg) |
1552 | { |
1553 | if (I_am_RP(pim, sg->grp)pim_rp_i_am_rp ((pim), (sg->grp))) |
1554 | return 1; |
1555 | |
1556 | return 0; |
1557 | } |
1558 | |
1559 | int pim_upstream_is_sg_rpt(struct pim_upstream *up) |
1560 | { |
1561 | struct listnode *chnode; |
1562 | struct pim_ifchannel *ch; |
1563 | |
1564 | for (ALL_LIST_ELEMENTS_RO(up->ifchannels, chnode, ch)(chnode) = ((up->ifchannels) ? ((up->ifchannels)->head ) : ((void*)0)), ((ch) = ((void*)0)); (chnode) != ((void*)0) && ((ch) = ((({ static const struct xref_assert _xref __attribute__ ( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 1564, "pimd/pim_upstream.c" , __func__, }, .expr = "chnode", }; static const struct xref * const xref_p_138 __attribute__((used, section("xref_array")) ) = &(_xref.xref); if (__builtin_expect((chnode) ? 0 : 1, 0)) do { _zlog_assert_failed(&_xref, ((void*)0)); } while (chnode); }), ({ static const struct xref_assert _xref __attribute__ ( (used)) = { .xref = { (((void*)0)), (XREFT_ASSERT), 1564, "pimd/pim_upstream.c" , __func__, }, .expr = "(chnode)->data != NULL", }; static const struct xref * const xref_p_139 __attribute__((used, section ("xref_array"))) = &(_xref.xref); if (__builtin_expect((( chnode)->data != ((void*)0)) ? 0 : 1, 0)) do { _zlog_assert_failed (&_xref, ((void*)0)); } while ((chnode)->data != ((void *)0)); }), (chnode)->data)), 1); (chnode) = ((chnode) ? (( chnode)->next) : ((void*)0)), ((ch) = ((void*)0))) { |
1565 | if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags)((ch->flags) & (1 << 2))) |
1566 | return 1; |
1567 | } |
1568 | |
1569 | return 0; |
1570 | } |
1571 | /* |
1572 | * After receiving a packet set SPTbit: |
1573 | * void |
1574 | * Update_SPTbit(S,G,iif) { |
1575 | * if ( iif == RPF_interface(S) |
1576 | * AND JoinDesired(S,G) == true |
1577 | * AND ( DirectlyConnected(S) == true |
1578 | * OR RPF_interface(S) != RPF_interface(RP(G)) |
1579 | * OR inherited_olist(S,G,rpt) == NULL |
1580 | * OR ( ( RPF'(S,G) == RPF'(*,G) ) AND |
1581 | * ( RPF'(S,G) != NULL ) ) |
1582 | * OR ( I_Am_Assert_Loser(S,G,iif) ) { |
1583 | * Set SPTbit(S,G) to true |
1584 | * } |
1585 | * } |
1586 | */ |
1587 | void pim_upstream_set_sptbit(struct pim_upstream *up, |
1588 | struct interface *incoming) |
1589 | { |
1590 | struct pim_upstream *starup = up->parent; |
1591 | |
1592 | // iif == RPF_interfvace(S) |
1593 | if (up->rpf.source_nexthop.interface != incoming) { |
1594 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1595 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Incoming Interface: %s is different than RPF_interface(S) %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1598, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Incoming Interface: %s is different than RPF_interface(S) %s" ), .priority = (7), .ec = (0), .args = ("__func__, incoming->name, up->rpf.source_nexthop.interface->name" ), }; static const struct xref * const xref_p_140 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Incoming Interface: %s is different than RPF_interface(S) %s" ), __func__, incoming->name, up->rpf.source_nexthop.interface ->name); } while (0) |
1596 | "%s: Incoming Interface: %s is different than RPF_interface(S) %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Incoming Interface: %s is different than RPF_interface(S) %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1598, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Incoming Interface: %s is different than RPF_interface(S) %s" ), .priority = (7), .ec = (0), .args = ("__func__, incoming->name, up->rpf.source_nexthop.interface->name" ), }; static const struct xref * const xref_p_140 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Incoming Interface: %s is different than RPF_interface(S) %s" ), __func__, incoming->name, up->rpf.source_nexthop.interface ->name); } while (0) |
1597 | __func__, incoming->name,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Incoming Interface: %s is different than RPF_interface(S) %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1598, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Incoming Interface: %s is different than RPF_interface(S) %s" ), .priority = (7), .ec = (0), .args = ("__func__, incoming->name, up->rpf.source_nexthop.interface->name" ), }; static const struct xref * const xref_p_140 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Incoming Interface: %s is different than RPF_interface(S) %s" ), __func__, incoming->name, up->rpf.source_nexthop.interface ->name); } while (0) |
1598 | up->rpf.source_nexthop.interface->name)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Incoming Interface: %s is different than RPF_interface(S) %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1598, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Incoming Interface: %s is different than RPF_interface(S) %s" ), .priority = (7), .ec = (0), .args = ("__func__, incoming->name, up->rpf.source_nexthop.interface->name" ), }; static const struct xref * const xref_p_140 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Incoming Interface: %s is different than RPF_interface(S) %s" ), __func__, incoming->name, up->rpf.source_nexthop.interface ->name); } while (0); |
1599 | return; |
1600 | } |
1601 | |
1602 | // AND JoinDesired(S,G) == true |
1603 | if (!pim_upstream_evaluate_join_desired(up->channel_oil->pim, up)) { |
1604 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1605 | zlog_debug("%s: %s Join is not Desired", __func__,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: %s Join is not Desired" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1606, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: %s Join is not Desired"), .priority = (7), . ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_141 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: %s Join is not Desired" ), __func__, up->sg_str); } while (0) |
1606 | up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: %s Join is not Desired" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1606, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: %s Join is not Desired"), .priority = (7), . ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_141 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: %s Join is not Desired" ), __func__, up->sg_str); } while (0); |
1607 | return; |
1608 | } |
1609 | |
1610 | // DirectlyConnected(S) == true |
1611 | if (pim_if_connected_to_source(up->rpf.source_nexthop.interface, |
1612 | up->sg.src)) { |
1613 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1614 | zlog_debug("%s: %s is directly connected to the source",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: %s is directly connected to the source" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1615, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: %s is directly connected to the source"), . priority = (7), .ec = (0), .args = ("__func__, up->sg_str" ), }; static const struct xref * const xref_p_142 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: %s is directly connected to the source"), __func__ , up->sg_str); } while (0) |
1615 | __func__, up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: %s is directly connected to the source" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1615, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: %s is directly connected to the source"), . priority = (7), .ec = (0), .args = ("__func__, up->sg_str" ), }; static const struct xref * const xref_p_142 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: %s is directly connected to the source"), __func__ , up->sg_str); } while (0); |
1616 | up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE; |
1617 | return; |
1618 | } |
1619 | |
1620 | // OR RPF_interface(S) != RPF_interface(RP(G)) |
1621 | if (!starup |
1622 | || up->rpf.source_nexthop |
1623 | .interface != starup->rpf.source_nexthop.interface) { |
1624 | struct pim_upstream *starup = up->parent; |
1625 | |
1626 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1627 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: %s RPF_interface(S) != RPF_interface(RP(G))" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1629, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: %s RPF_interface(S) != RPF_interface(RP(G))" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str" ), }; static const struct xref * const xref_p_143 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: %s RPF_interface(S) != RPF_interface(RP(G))" ), __func__, up->sg_str); } while (0) |
1628 | "%s: %s RPF_interface(S) != RPF_interface(RP(G))",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: %s RPF_interface(S) != RPF_interface(RP(G))" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1629, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: %s RPF_interface(S) != RPF_interface(RP(G))" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str" ), }; static const struct xref * const xref_p_143 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: %s RPF_interface(S) != RPF_interface(RP(G))" ), __func__, up->sg_str); } while (0) |
1629 | __func__, up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: %s RPF_interface(S) != RPF_interface(RP(G))" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1629, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: %s RPF_interface(S) != RPF_interface(RP(G))" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str" ), }; static const struct xref * const xref_p_143 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: %s RPF_interface(S) != RPF_interface(RP(G))" ), __func__, up->sg_str); } while (0); |
1630 | up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE; |
1631 | |
1632 | pim_jp_agg_single_upstream_send(&starup->rpf, starup, true1); |
1633 | return; |
1634 | } |
1635 | |
1636 | // OR inherited_olist(S,G,rpt) == NULL |
1637 | if (pim_upstream_is_sg_rpt(up) |
1638 | && pim_upstream_empty_inherited_olist(up)) { |
1639 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1640 | zlog_debug("%s: %s OR inherited_olist(S,G,rpt) == NULL",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: %s OR inherited_olist(S,G,rpt) == NULL" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1641, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: %s OR inherited_olist(S,G,rpt) == NULL"), . priority = (7), .ec = (0), .args = ("__func__, up->sg_str" ), }; static const struct xref * const xref_p_144 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: %s OR inherited_olist(S,G,rpt) == NULL"), __func__ , up->sg_str); } while (0) |
1641 | __func__, up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: %s OR inherited_olist(S,G,rpt) == NULL" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1641, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: %s OR inherited_olist(S,G,rpt) == NULL"), . priority = (7), .ec = (0), .args = ("__func__, up->sg_str" ), }; static const struct xref * const xref_p_144 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: %s OR inherited_olist(S,G,rpt) == NULL"), __func__ , up->sg_str); } while (0); |
1642 | up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE; |
1643 | return; |
1644 | } |
1645 | |
1646 | // OR ( ( RPF'(S,G) == RPF'(*,G) ) AND |
1647 | // ( RPF'(S,G) != NULL ) ) |
1648 | if (up->parent && pim_rpf_is_same(&up->rpf, &up->parent->rpf)) { |
1649 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1650 | zlog_debug("%s: %s RPF'(S,G) is the same as RPF'(*,G)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: %s RPF'(S,G) is the same as RPF'(*,G)" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1651, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: %s RPF'(S,G) is the same as RPF'(*,G)"), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_145 __attribute__((used, section ("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: %s RPF'(S,G) is the same as RPF'(*,G)" ), __func__, up->sg_str); } while (0) |
1651 | __func__, up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: %s RPF'(S,G) is the same as RPF'(*,G)" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1651, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: %s RPF'(S,G) is the same as RPF'(*,G)"), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_145 __attribute__((used, section ("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: %s RPF'(S,G) is the same as RPF'(*,G)" ), __func__, up->sg_str); } while (0); |
1652 | up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE; |
1653 | return; |
1654 | } |
1655 | |
1656 | return; |
1657 | } |
1658 | |
1659 | const char *pim_upstream_state2str(enum pim_upstream_state join_state) |
1660 | { |
1661 | switch (join_state) { |
1662 | case PIM_UPSTREAM_NOTJOINED: |
1663 | return "NotJoined"; |
1664 | case PIM_UPSTREAM_JOINED: |
1665 | return "Joined"; |
1666 | } |
1667 | return "Unknown"; |
1668 | } |
1669 | |
1670 | const char *pim_reg_state2str(enum pim_reg_state reg_state, char *state_str, |
1671 | size_t state_str_len) |
1672 | { |
1673 | switch (reg_state) { |
1674 | case PIM_REG_NOINFO: |
1675 | strlcpy(state_str, "RegNoInfo", state_str_len); |
1676 | break; |
1677 | case PIM_REG_JOIN: |
1678 | strlcpy(state_str, "RegJoined", state_str_len); |
1679 | break; |
1680 | case PIM_REG_JOIN_PENDING: |
1681 | strlcpy(state_str, "RegJoinPend", state_str_len); |
1682 | break; |
1683 | case PIM_REG_PRUNE: |
1684 | strlcpy(state_str, "RegPrune", state_str_len); |
1685 | break; |
1686 | } |
1687 | return state_str; |
1688 | } |
1689 | |
1690 | static void pim_upstream_register_stop_timer(struct event *t) |
1691 | { |
1692 | struct pim_interface *pim_ifp; |
1693 | struct pim_instance *pim; |
1694 | struct pim_upstream *up; |
1695 | up = EVENT_ARG(t)((t)->arg); |
1696 | pim = up->channel_oil->pim; |
1697 | |
1698 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) { |
1699 | char state_str[PIM_REG_STATE_STR_LEN12]; |
1700 | zlog_debug("%s: (S,G)=%s[%s] upstream register stop timer %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: (S,G)=%s[%s] upstream register stop timer %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1703, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: (S,G)=%s[%s] upstream register stop timer %s" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim->vrf->name, pim_reg_state2str(up->reg_state, state_str, sizeof(state_str))" ), }; static const struct xref * const xref_p_146 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: (S,G)=%s[%s] upstream register stop timer %s" ), __func__, up->sg_str, pim->vrf->name, pim_reg_state2str (up->reg_state, state_str, sizeof(state_str))); } while (0 ) |
1701 | __func__, up->sg_str, pim->vrf->name,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: (S,G)=%s[%s] upstream register stop timer %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1703, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: (S,G)=%s[%s] upstream register stop timer %s" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim->vrf->name, pim_reg_state2str(up->reg_state, state_str, sizeof(state_str))" ), }; static const struct xref * const xref_p_146 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: (S,G)=%s[%s] upstream register stop timer %s" ), __func__, up->sg_str, pim->vrf->name, pim_reg_state2str (up->reg_state, state_str, sizeof(state_str))); } while (0 ) |
1702 | pim_reg_state2str(up->reg_state, state_str,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: (S,G)=%s[%s] upstream register stop timer %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1703, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: (S,G)=%s[%s] upstream register stop timer %s" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim->vrf->name, pim_reg_state2str(up->reg_state, state_str, sizeof(state_str))" ), }; static const struct xref * const xref_p_146 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: (S,G)=%s[%s] upstream register stop timer %s" ), __func__, up->sg_str, pim->vrf->name, pim_reg_state2str (up->reg_state, state_str, sizeof(state_str))); } while (0 ) |
1703 | sizeof(state_str)))do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: (S,G)=%s[%s] upstream register stop timer %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1703, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: (S,G)=%s[%s] upstream register stop timer %s" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim->vrf->name, pim_reg_state2str(up->reg_state, state_str, sizeof(state_str))" ), }; static const struct xref * const xref_p_146 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: (S,G)=%s[%s] upstream register stop timer %s" ), __func__, up->sg_str, pim->vrf->name, pim_reg_state2str (up->reg_state, state_str, sizeof(state_str))); } while (0 ); |
1704 | } |
1705 | |
1706 | switch (up->reg_state) { |
1707 | case PIM_REG_JOIN_PENDING: |
1708 | up->reg_state = PIM_REG_JOIN; |
1709 | pim_channel_add_oif(up->channel_oil, pim->regiface, |
1710 | PIM_OIF_FLAG_PROTO_PIM(1 << 1), |
1711 | __func__); |
1712 | pim_vxlan_update_sg_reg_state(pim, up, true1 /*reg_join*/); |
1713 | break; |
1714 | case PIM_REG_JOIN: |
1715 | break; |
1716 | case PIM_REG_PRUNE: |
1717 | /* This is equalent to Couldreg -> False */ |
1718 | if (!up->rpf.source_nexthop.interface) { |
1719 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1720 | zlog_debug("%s: up %s RPF is not present",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: up %s RPF is not present" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1721, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: up %s RPF is not present"), .priority = (7) , .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_147 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: up %s RPF is not present" ), __func__, up->sg_str); } while (0) |
1721 | __func__, up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: up %s RPF is not present" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1721, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: up %s RPF is not present"), .priority = (7) , .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_147 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: up %s RPF is not present" ), __func__, up->sg_str); } while (0); |
1722 | up->reg_state = PIM_REG_NOINFO; |
1723 | PIM_UPSTREAM_FLAG_UNSET_FHR(up->flags)((up->flags) &= ~(1 << 2)); |
1724 | return; |
1725 | } |
1726 | |
1727 | pim_ifp = up->rpf.source_nexthop.interface->info; |
1728 | if (!pim_ifp) { |
1729 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1730 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Interface: %s is not configured for pim" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1733, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Interface: %s is not configured for pim"), . priority = (7), .ec = (0), .args = ("__func__, up->rpf.source_nexthop.interface->name" ), }; static const struct xref * const xref_p_148 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Interface: %s is not configured for pim"), __func__, up->rpf.source_nexthop.interface->name); } while (0) |
1731 | "%s: Interface: %s is not configured for pim",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Interface: %s is not configured for pim" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1733, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Interface: %s is not configured for pim"), . priority = (7), .ec = (0), .args = ("__func__, up->rpf.source_nexthop.interface->name" ), }; static const struct xref * const xref_p_148 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Interface: %s is not configured for pim"), __func__, up->rpf.source_nexthop.interface->name); } while (0) |
1732 | __func__,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Interface: %s is not configured for pim" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1733, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Interface: %s is not configured for pim"), . priority = (7), .ec = (0), .args = ("__func__, up->rpf.source_nexthop.interface->name" ), }; static const struct xref * const xref_p_148 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Interface: %s is not configured for pim"), __func__, up->rpf.source_nexthop.interface->name); } while (0) |
1733 | up->rpf.source_nexthop.interface->name)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Interface: %s is not configured for pim" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1733, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Interface: %s is not configured for pim"), . priority = (7), .ec = (0), .args = ("__func__, up->rpf.source_nexthop.interface->name" ), }; static const struct xref * const xref_p_148 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Interface: %s is not configured for pim"), __func__, up->rpf.source_nexthop.interface->name); } while (0); |
1734 | return; |
1735 | } |
1736 | up->reg_state = PIM_REG_JOIN_PENDING; |
1737 | pim_upstream_start_register_stop_timer(up, 1); |
1738 | |
1739 | if (((up->channel_oil->cc.lastused / 100) |
1740 | > pim->keep_alive_time) |
1741 | && (I_am_RP(pim_ifp->pim, up->sg.grp)pim_rp_i_am_rp ((pim_ifp->pim), (up->sg.grp)))) { |
1742 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1743 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Stop sending the register, because I am the RP and we haven't seen a packet in a while" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1745, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Stop sending the register, because I am the RP and we haven't seen a packet in a while" ), .priority = (7), .ec = (0), .args = ("__func__"), }; static const struct xref * const xref_p_149 __attribute__((used, section ("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: Stop sending the register, because I am the RP and we haven't seen a packet in a while" ), __func__); } while (0) |
1744 | "%s: Stop sending the register, because I am the RP and we haven't seen a packet in a while",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Stop sending the register, because I am the RP and we haven't seen a packet in a while" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1745, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Stop sending the register, because I am the RP and we haven't seen a packet in a while" ), .priority = (7), .ec = (0), .args = ("__func__"), }; static const struct xref * const xref_p_149 __attribute__((used, section ("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: Stop sending the register, because I am the RP and we haven't seen a packet in a while" ), __func__); } while (0) |
1745 | __func__)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Stop sending the register, because I am the RP and we haven't seen a packet in a while" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1745, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Stop sending the register, because I am the RP and we haven't seen a packet in a while" ), .priority = (7), .ec = (0), .args = ("__func__"), }; static const struct xref * const xref_p_149 __attribute__((used, section ("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: Stop sending the register, because I am the RP and we haven't seen a packet in a while" ), __func__); } while (0); |
1746 | return; |
1747 | } |
1748 | pim_null_register_send(up); |
1749 | break; |
1750 | case PIM_REG_NOINFO: |
1751 | break; |
1752 | } |
1753 | } |
1754 | |
1755 | void pim_upstream_start_register_stop_timer(struct pim_upstream *up, |
1756 | int null_register) |
1757 | { |
1758 | uint32_t time; |
1759 | |
1760 | EVENT_OFF(up->t_rs_timer)do { if ((up->t_rs_timer)) event_cancel(&(up->t_rs_timer )); } while (0); |
1761 | |
1762 | if (!null_register) { |
1763 | uint32_t lower = (0.5 * router->register_suppress_time); |
1764 | uint32_t upper = (1.5 * router->register_suppress_time); |
1765 | time = lower + (frr_weak_random() % (upper - lower + 1)); |
1766 | /* Make sure we don't wrap around */ |
1767 | if (time >= router->register_probe_time) |
1768 | time -= router->register_probe_time; |
1769 | else |
1770 | time = 0; |
1771 | } else |
1772 | time = router->register_probe_time; |
1773 | |
1774 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) { |
1775 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: (S,G)=%s Starting upstream register stop timer %d" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1777, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: (S,G)=%s Starting upstream register stop timer %d" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, time" ), }; static const struct xref * const xref_p_150 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: (S,G)=%s Starting upstream register stop timer %d" ), __func__, up->sg_str, time); } while (0) |
1776 | "%s: (S,G)=%s Starting upstream register stop timer %d",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: (S,G)=%s Starting upstream register stop timer %d" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1777, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: (S,G)=%s Starting upstream register stop timer %d" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, time" ), }; static const struct xref * const xref_p_150 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: (S,G)=%s Starting upstream register stop timer %d" ), __func__, up->sg_str, time); } while (0) |
1777 | __func__, up->sg_str, time)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: (S,G)=%s Starting upstream register stop timer %d" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1777, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: (S,G)=%s Starting upstream register stop timer %d" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, time" ), }; static const struct xref * const xref_p_150 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: (S,G)=%s Starting upstream register stop timer %d" ), __func__, up->sg_str, time); } while (0); |
1778 | } |
1779 | event_add_timer(router->master, pim_upstream_register_stop_timer, up,({ static const struct xref_eventsched _xref __attribute__( ( used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 1780, "pimd/pim_upstream.c" , __func__, }, .funcname = "pim_upstream_register_stop_timer" , .dest = "&up->t_rs_timer", .event_type = EVENT_TIMER , }; static const struct xref * const xref_p_151 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); _event_add_timer (&_xref, router->master, pim_upstream_register_stop_timer , up, time, &up->t_rs_timer); }) |
1780 | time, &up->t_rs_timer)({ static const struct xref_eventsched _xref __attribute__( ( used)) = { .xref = { (((void*)0)), (XREFT_EVENTSCHED), 1780, "pimd/pim_upstream.c" , __func__, }, .funcname = "pim_upstream_register_stop_timer" , .dest = "&up->t_rs_timer", .event_type = EVENT_TIMER , }; static const struct xref * const xref_p_151 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); _event_add_timer (&_xref, router->master, pim_upstream_register_stop_timer , up, time, &up->t_rs_timer); }); |
1781 | } |
1782 | |
1783 | int pim_upstream_inherited_olist_decide(struct pim_instance *pim, |
1784 | struct pim_upstream *up) |
1785 | { |
1786 | struct interface *ifp; |
1787 | struct pim_ifchannel *ch, *starch; |
1788 | struct pim_upstream *starup = up->parent; |
1789 | int output_intf = 0; |
1790 | |
1791 | if (!up->rpf.source_nexthop.interface) |
1792 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1793 | zlog_debug("%s: up %s RPF is not present", __func__,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: up %s RPF is not present" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1794, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: up %s RPF is not present"), .priority = (7) , .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_152 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: up %s RPF is not present" ), __func__, up->sg_str); } while (0) |
1794 | up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: up %s RPF is not present" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1794, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: up %s RPF is not present"), .priority = (7) , .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_152 __attribute__((used, section( "xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: up %s RPF is not present" ), __func__, up->sg_str); } while (0); |
1795 | |
1796 | FOR_ALL_INTERFACES (pim->vrf, ifp)if (pim->vrf) for ((ifp) = if_name_head_RB_MIN((&pim-> vrf->ifaces_by_name)); (ifp) != ((void*)0); (ifp) = if_name_head_RB_NEXT ((ifp))) { |
1797 | struct pim_interface *pim_ifp; |
1798 | if (!ifp->info) |
1799 | continue; |
1800 | |
1801 | ch = pim_ifchannel_find(ifp, &up->sg); |
1802 | |
1803 | if (starup) |
1804 | starch = pim_ifchannel_find(ifp, &starup->sg); |
1805 | else |
1806 | starch = NULL((void*)0); |
1807 | |
1808 | if (!ch && !starch) |
1809 | continue; |
1810 | |
1811 | pim_ifp = ifp->info; |
1812 | if (PIM_I_am_DualActive(pim_ifp)(pim_ifp)->activeactive == 1 |
1813 | && PIM_UPSTREAM_FLAG_TEST_MLAG_INTERFACE(up->flags)((up->flags)&(1 << 21)) |
1814 | && (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags)((up->flags) & (1 << 17)) |
1815 | || !PIM_UPSTREAM_FLAG_TEST_MLAG_PEER(up->flags)((up->flags) & (1 << 18)))) |
1816 | continue; |
1817 | if (pim_upstream_evaluate_join_desired_interface(up, ch, |
1818 | starch)) { |
1819 | int flag = 0; |
1820 | |
1821 | if (!ch) |
1822 | flag = PIM_OIF_FLAG_PROTO_STAR(1 << 2); |
1823 | else { |
1824 | if (PIM_IF_FLAG_TEST_PROTO_IGMP(ch->flags)((ch->flags)&(1 << 4))) |
1825 | flag = PIM_OIF_FLAG_PROTO_GM(1 << 0); |
1826 | if (PIM_IF_FLAG_TEST_PROTO_PIM(ch->flags)((ch->flags)&(1 << 3))) |
1827 | flag |= PIM_OIF_FLAG_PROTO_PIM(1 << 1); |
1828 | if (starch) |
1829 | flag |= PIM_OIF_FLAG_PROTO_STAR(1 << 2); |
1830 | } |
1831 | |
1832 | pim_channel_add_oif(up->channel_oil, ifp, flag, |
1833 | __func__); |
1834 | output_intf++; |
1835 | } |
1836 | } |
1837 | |
1838 | return output_intf; |
1839 | } |
1840 | |
1841 | /* |
1842 | * For a given upstream, determine the inherited_olist |
1843 | * and apply it. |
1844 | * |
1845 | * inherited_olist(S,G,rpt) = |
1846 | * ( joins(*,*,RP(G)) (+) joins(*,G) (-) prunes(S,G,rpt) ) |
1847 | * (+) ( pim_include(*,G) (-) pim_exclude(S,G)) |
1848 | * (-) ( lost_assert(*,G) (+) lost_assert(S,G,rpt) ) |
1849 | * |
1850 | * inherited_olist(S,G) = |
1851 | * inherited_olist(S,G,rpt) (+) |
1852 | * joins(S,G) (+) pim_include(S,G) (-) lost_assert(S,G) |
1853 | * |
1854 | * return 1 if there are any output interfaces |
1855 | * return 0 if there are not any output interfaces |
1856 | */ |
1857 | int pim_upstream_inherited_olist(struct pim_instance *pim, |
1858 | struct pim_upstream *up) |
1859 | { |
1860 | int output_intf = pim_upstream_inherited_olist_decide(pim, up); |
1861 | |
1862 | /* |
1863 | * If we have output_intf switch state to Join and work like normal |
1864 | * If we don't have an output_intf that means we are probably a |
1865 | * switch on a stick so turn on forwarding to just accept the |
1866 | * incoming packets so we don't bother the other stuff! |
1867 | */ |
1868 | pim_upstream_update_join_desired(pim, up); |
1869 | |
1870 | if (!output_intf) |
1871 | forward_on(up); |
1872 | |
1873 | return output_intf; |
1874 | } |
1875 | |
1876 | int pim_upstream_empty_inherited_olist(struct pim_upstream *up) |
1877 | { |
1878 | return pim_channel_oil_empty(up->channel_oil); |
1879 | } |
1880 | |
1881 | /* |
1882 | * When we have a new neighbor, |
1883 | * find upstreams that don't have their rpf_addr |
1884 | * set and see if the new neighbor allows |
1885 | * the join to be sent |
1886 | */ |
1887 | void pim_upstream_find_new_rpf(struct pim_instance *pim) |
1888 | { |
1889 | struct pim_upstream *up; |
1890 | struct pim_rpf old; |
1891 | enum pim_rpf_result rpf_result; |
1892 | |
1893 | /* |
1894 | * Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr |
1895 | */ |
1896 | frr_each (rb_pim_upstream, &pim->upstream_head, up)for (up = rb_pim_upstream_first(&pim->upstream_head); up ; up = rb_pim_upstream_next(&pim->upstream_head, up)) { |
1897 | if (pim_addr_is_any(up->upstream_addr)) { |
1898 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1899 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: RP not configured for Upstream %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1901, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: RP not configured for Upstream %s"), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_153 __attribute__((used, section ("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: RP not configured for Upstream %s" ), __func__, up->sg_str); } while (0) |
1900 | "%s: RP not configured for Upstream %s",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: RP not configured for Upstream %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1901, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: RP not configured for Upstream %s"), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_153 __attribute__((used, section ("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: RP not configured for Upstream %s" ), __func__, up->sg_str); } while (0) |
1901 | __func__, up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: RP not configured for Upstream %s" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1901, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: RP not configured for Upstream %s"), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str"), }; static const struct xref * const xref_p_153 __attribute__((used, section ("xref_array"))) = &(_xref.xref); zlog_ref(&_xref, ("%s: RP not configured for Upstream %s" ), __func__, up->sg_str); } while (0); |
1902 | continue; |
1903 | } |
1904 | |
1905 | if (pim_rpf_addr_is_inaddr_any(&up->rpf)) { |
1906 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
1907 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Upstream %s without a path to send join, checking" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1909, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Upstream %s without a path to send join, checking" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str" ), }; static const struct xref * const xref_p_154 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Upstream %s without a path to send join, checking" ), __func__, up->sg_str); } while (0) |
1908 | "%s: Upstream %s without a path to send join, checking",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Upstream %s without a path to send join, checking" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1909, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Upstream %s without a path to send join, checking" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str" ), }; static const struct xref * const xref_p_154 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Upstream %s without a path to send join, checking" ), __func__, up->sg_str); } while (0) |
1909 | __func__, up->sg_str)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Upstream %s without a path to send join, checking" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 1909, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Upstream %s without a path to send join, checking" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str" ), }; static const struct xref * const xref_p_154 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Upstream %s without a path to send join, checking" ), __func__, up->sg_str); } while (0); |
1910 | old.source_nexthop.interface = |
1911 | up->rpf.source_nexthop.interface; |
1912 | rpf_result = pim_rpf_update(pim, up, &old, __func__); |
1913 | if (rpf_result == PIM_RPF_CHANGED || |
1914 | (rpf_result == PIM_RPF_FAILURE && |
1915 | old.source_nexthop.interface)) |
1916 | pim_zebra_upstream_rpf_changed(pim, up, &old); |
1917 | /* update kernel multicast forwarding cache (MFC) */ |
1918 | pim_upstream_mroute_iif_update(up->channel_oil, |
1919 | __func__); |
1920 | } |
1921 | } |
1922 | pim_zebra_update_all_interfaces(pim); |
1923 | } |
1924 | |
1925 | unsigned int pim_upstream_hash_key(const void *arg) |
1926 | { |
1927 | const struct pim_upstream *up = arg; |
1928 | |
1929 | return pim_sgaddr_hash(up->sg, 0); |
1930 | } |
1931 | |
1932 | void pim_upstream_terminate(struct pim_instance *pim) |
1933 | { |
1934 | struct pim_upstream *up; |
1935 | |
1936 | while ((up = rb_pim_upstream_first(&pim->upstream_head))) { |
1937 | if (pim_upstream_del(pim, up, __func__)) |
1938 | pim_upstream_timers_stop(up); |
1939 | } |
1940 | |
1941 | rb_pim_upstream_fini(&pim->upstream_head); |
1942 | |
1943 | if (pim->upstream_sg_wheel) |
1944 | wheel_delete(pim->upstream_sg_wheel); |
1945 | pim->upstream_sg_wheel = NULL((void*)0); |
1946 | } |
1947 | |
1948 | bool_Bool pim_upstream_equal(const void *arg1, const void *arg2) |
1949 | { |
1950 | const struct pim_upstream *up1 = (const struct pim_upstream *)arg1; |
1951 | const struct pim_upstream *up2 = (const struct pim_upstream *)arg2; |
1952 | |
1953 | return !pim_sgaddr_cmp(up1->sg, up2->sg); |
1954 | } |
1955 | |
1956 | /* rfc4601:section-4.2:"Data Packet Forwarding Rules" defines |
1957 | * the cases where kat has to be restarted on rxing traffic - |
1958 | * |
1959 | * if( DirectlyConnected(S) == true AND iif == RPF_interface(S) ) { |
1960 | * set KeepaliveTimer(S,G) to Keepalive_Period |
1961 | * # Note: a register state transition or UpstreamJPState(S,G) |
1962 | * # transition may happen as a result of restarting |
1963 | * # KeepaliveTimer, and must be dealt with here. |
1964 | * } |
1965 | * if( iif == RPF_interface(S) AND UpstreamJPState(S,G) == Joined AND |
1966 | * inherited_olist(S,G) != NULL ) { |
1967 | * set KeepaliveTimer(S,G) to Keepalive_Period |
1968 | * } |
1969 | */ |
1970 | static bool_Bool pim_upstream_kat_start_ok(struct pim_upstream *up) |
1971 | { |
1972 | struct channel_oil *c_oil = up->channel_oil; |
1973 | struct interface *ifp = up->rpf.source_nexthop.interface; |
1974 | struct pim_interface *pim_ifp; |
1975 | struct pim_instance *pim = up->channel_oil->pim; |
1976 | |
1977 | /* "iif == RPF_interface(S)" check is not easy to do as the info |
1978 | * we get from the kernel/ASIC is really a "lookup/key hit". |
1979 | * So we will do an approximate check here to avoid starting KAT |
1980 | * because of (S,G,rpt) forwarding on a non-LHR. |
1981 | */ |
1982 | if (!ifp) |
1983 | return false0; |
1984 | |
1985 | pim_ifp = ifp->info; |
1986 | if (pim_ifp->mroute_vif_index != *oil_incoming_vif(c_oil)) |
1987 | return false0; |
1988 | |
1989 | if (pim_if_connected_to_source(up->rpf.source_nexthop.interface, |
1990 | up->sg.src)) { |
1991 | return true1; |
1992 | } |
1993 | |
1994 | if ((up->join_state == PIM_UPSTREAM_JOINED) |
1995 | && !pim_upstream_empty_inherited_olist(up)) { |
1996 | if (I_am_RP(pim, up->sg.grp)pim_rp_i_am_rp ((pim), (up->sg.grp))) |
1997 | return true1; |
1998 | } |
1999 | |
2000 | return false0; |
2001 | } |
2002 | |
2003 | static bool_Bool pim_upstream_sg_running_proc(struct pim_upstream *up) |
2004 | { |
2005 | bool_Bool rv = false0; |
2006 | struct pim_instance *pim = up->pim; |
2007 | |
2008 | if (!up->channel_oil->installed) |
2009 | return rv; |
2010 | |
2011 | pim_mroute_update_counters(up->channel_oil); |
2012 | |
2013 | // Have we seen packets? |
2014 | if ((up->channel_oil->cc.oldpktcnt >= up->channel_oil->cc.pktcnt) |
2015 | && (up->channel_oil->cc.lastused / 100 > 30)) { |
2016 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) { |
2017 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 2022, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim->vrf->name, up->channel_oil->cc.oldpktcnt, up->channel_oil->cc.pktcnt, up->channel_oil->cc.lastused / 100" ), }; static const struct xref * const xref_p_155 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), __func__, up->sg_str, pim->vrf->name, up->channel_oil ->cc.oldpktcnt, up->channel_oil->cc.pktcnt, up->channel_oil ->cc.lastused / 100); } while (0) |
2018 | "%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 2022, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim->vrf->name, up->channel_oil->cc.oldpktcnt, up->channel_oil->cc.pktcnt, up->channel_oil->cc.lastused / 100" ), }; static const struct xref * const xref_p_155 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), __func__, up->sg_str, pim->vrf->name, up->channel_oil ->cc.oldpktcnt, up->channel_oil->cc.pktcnt, up->channel_oil ->cc.lastused / 100); } while (0) |
2019 | __func__, up->sg_str, pim->vrf->name,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 2022, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim->vrf->name, up->channel_oil->cc.oldpktcnt, up->channel_oil->cc.pktcnt, up->channel_oil->cc.lastused / 100" ), }; static const struct xref * const xref_p_155 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), __func__, up->sg_str, pim->vrf->name, up->channel_oil ->cc.oldpktcnt, up->channel_oil->cc.pktcnt, up->channel_oil ->cc.lastused / 100); } while (0) |
2020 | up->channel_oil->cc.oldpktcnt,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 2022, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim->vrf->name, up->channel_oil->cc.oldpktcnt, up->channel_oil->cc.pktcnt, up->channel_oil->cc.lastused / 100" ), }; static const struct xref * const xref_p_155 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), __func__, up->sg_str, pim->vrf->name, up->channel_oil ->cc.oldpktcnt, up->channel_oil->cc.pktcnt, up->channel_oil ->cc.lastused / 100); } while (0) |
2021 | up->channel_oil->cc.pktcnt,do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 2022, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim->vrf->name, up->channel_oil->cc.oldpktcnt, up->channel_oil->cc.pktcnt, up->channel_oil->cc.lastused / 100" ), }; static const struct xref * const xref_p_155 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), __func__, up->sg_str, pim->vrf->name, up->channel_oil ->cc.oldpktcnt, up->channel_oil->cc.pktcnt, up->channel_oil ->cc.lastused / 100); } while (0) |
2022 | up->channel_oil->cc.lastused / 100)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 2022, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim->vrf->name, up->channel_oil->cc.oldpktcnt, up->channel_oil->cc.pktcnt, up->channel_oil->cc.lastused / 100" ), }; static const struct xref * const xref_p_155 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s[%s]: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)" ), __func__, up->sg_str, pim->vrf->name, up->channel_oil ->cc.oldpktcnt, up->channel_oil->cc.pktcnt, up->channel_oil ->cc.lastused / 100); } while (0); |
2023 | } |
2024 | return rv; |
2025 | } |
2026 | |
2027 | if (pim_upstream_kat_start_ok(up)) { |
2028 | /* Add a source reference to the stream if |
2029 | * one doesn't already exist */ |
2030 | if (!PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags)((up->flags) & (1 << 5))) { |
2031 | if (PIM_DEBUG_PIM_TRACE(router->debugs & ((1 << 5) | (1 << 6)))) |
2032 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("source reference created on kat restart %s[%s]" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 2034, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("source reference created on kat restart %s[%s]" ), .priority = (7), .ec = (0), .args = ("up->sg_str, pim->vrf->name" ), }; static const struct xref * const xref_p_156 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("source reference created on kat restart %s[%s]" ), up->sg_str, pim->vrf->name); } while (0) |
2033 | "source reference created on kat restart %s[%s]",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("source reference created on kat restart %s[%s]" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 2034, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("source reference created on kat restart %s[%s]" ), .priority = (7), .ec = (0), .args = ("up->sg_str, pim->vrf->name" ), }; static const struct xref * const xref_p_156 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("source reference created on kat restart %s[%s]" ), up->sg_str, pim->vrf->name); } while (0) |
2034 | up->sg_str, pim->vrf->name)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("source reference created on kat restart %s[%s]" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 2034, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("source reference created on kat restart %s[%s]" ), .priority = (7), .ec = (0), .args = ("up->sg_str, pim->vrf->name" ), }; static const struct xref * const xref_p_156 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("source reference created on kat restart %s[%s]" ), up->sg_str, pim->vrf->name); } while (0); |
2035 | |
2036 | pim_upstream_ref(up, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM(1 << 5), |
2037 | __func__); |
2038 | PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags)((up->flags) |= (1 << 5)); |
2039 | pim_upstream_fhr_kat_start(up); |
2040 | } |
2041 | pim_upstream_keep_alive_timer_start(up, pim->keep_alive_time); |
2042 | rv = true1; |
2043 | } else if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(up->flags)((up->flags) & (1 << 8))) { |
2044 | pim_upstream_keep_alive_timer_start(up, pim->keep_alive_time); |
2045 | rv = true1; |
2046 | } |
2047 | |
2048 | if ((up->sptbit != PIM_UPSTREAM_SPTBIT_TRUE) && |
2049 | (up->rpf.source_nexthop.interface)) { |
2050 | pim_upstream_set_sptbit(up, up->rpf.source_nexthop.interface); |
2051 | pim_upstream_update_could_assert(up); |
2052 | } |
2053 | |
2054 | return rv; |
2055 | } |
2056 | |
2057 | /* |
2058 | * Code to check and see if we've received packets on a S,G mroute |
2059 | * and if so to set the SPT bit appropriately |
2060 | */ |
2061 | static void pim_upstream_sg_running(void *arg) |
2062 | { |
2063 | struct pim_upstream *up = (struct pim_upstream *)arg; |
2064 | struct pim_instance *pim = up->channel_oil->pim; |
2065 | |
2066 | // No packet can have arrived here if this is the case |
2067 | if (!up->channel_oil->installed) { |
2068 | if (PIM_DEBUG_TRACE(router->debugs & ((1 << 5) | (1 << 9)))) |
2069 | zlog_debug("%s: %s[%s] is not installed in mroute",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: %s[%s] is not installed in mroute" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 2070, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: %s[%s] is not installed in mroute"), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim->vrf->name" ), }; static const struct xref * const xref_p_157 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: %s[%s] is not installed in mroute"), __func__ , up->sg_str, pim->vrf->name); } while (0) |
2070 | __func__, up->sg_str, pim->vrf->name)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: %s[%s] is not installed in mroute" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 2070, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: %s[%s] is not installed in mroute"), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim->vrf->name" ), }; static const struct xref * const xref_p_157 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: %s[%s] is not installed in mroute"), __func__ , up->sg_str, pim->vrf->name); } while (0); |
2071 | return; |
2072 | } |
2073 | |
2074 | /* |
2075 | * This is a bit of a hack |
2076 | * We've noted that we should rescan but |
2077 | * we've missed the window for doing so in |
2078 | * pim_zebra.c for some reason. I am |
2079 | * only doing this at this point in time |
2080 | * to get us up and working for the moment |
2081 | */ |
2082 | if (up->channel_oil->oil_inherited_rescan) { |
2083 | if (PIM_DEBUG_TRACE(router->debugs & ((1 << 5) | (1 << 9)))) |
2084 | zlog_debug(do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Handling unscanned inherited_olist for %s[%s]" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 2086, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Handling unscanned inherited_olist for %s[%s]" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim->vrf->name" ), }; static const struct xref * const xref_p_158 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Handling unscanned inherited_olist for %s[%s]" ), __func__, up->sg_str, pim->vrf->name); } while (0 ) |
2085 | "%s: Handling unscanned inherited_olist for %s[%s]",do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Handling unscanned inherited_olist for %s[%s]" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 2086, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Handling unscanned inherited_olist for %s[%s]" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim->vrf->name" ), }; static const struct xref * const xref_p_158 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Handling unscanned inherited_olist for %s[%s]" ), __func__, up->sg_str, pim->vrf->name); } while (0 ) |
2086 | __func__, up->sg_str, pim->vrf->name)do { static struct xrefdata_logmsg _xrefdata = { .xrefdata = { .xref = ((void*)0), .uid = {}, .hashstr = ("%s: Handling unscanned inherited_olist for %s[%s]" ), .hashu32 = {(7), (0)}, }, }; static const struct xref_logmsg _xref __attribute__( (used)) = { .xref = { (&_xrefdata.xrefdata ), (XREFT_LOGMSG), 2086, "pimd/pim_upstream.c", __func__, }, . fmtstring = ("%s: Handling unscanned inherited_olist for %s[%s]" ), .priority = (7), .ec = (0), .args = ("__func__, up->sg_str, pim->vrf->name" ), }; static const struct xref * const xref_p_158 __attribute__ ((used, section("xref_array"))) = &(_xref.xref); zlog_ref (&_xref, ("%s: Handling unscanned inherited_olist for %s[%s]" ), __func__, up->sg_str, pim->vrf->name); } while (0 ); |
2087 | pim_upstream_inherited_olist_decide(pim, up); |
2088 | up->channel_oil->oil_inherited_rescan = 0; |
2089 | } |
2090 | |
2091 | pim_upstream_sg_running_proc(up); |
2092 | } |
2093 | |
2094 | void pim_upstream_add_lhr_star_pimreg(struct pim_instance *pim) |
2095 | { |
2096 | struct pim_upstream *up; |
2097 | |
2098 | frr_each (rb_pim_upstream, &pim->upstream_head, up)for (up = rb_pim_upstream_first(&pim->upstream_head); up ; up = rb_pim_upstream_next(&pim->upstream_head, up)) { |
2099 | if (!pim_addr_is_any(up->sg.src)) |
2100 | continue; |
2101 | |
2102 | if (!PIM_UPSTREAM_FLAG_TEST_CAN_BE_LHR(up->flags)((up->flags) & ((1 << 3) | (1 << 15)))) |
2103 | continue; |
2104 | |
2105 | pim_channel_add_oif(up->channel_oil, pim->regiface, |
2106 | PIM_OIF_FLAG_PROTO_GM(1 << 0), __func__); |
2107 | } |
2108 | } |
2109 | |
2110 | void pim_upstream_spt_prefix_list_update(struct pim_instance *pim, |
2111 | struct prefix_list *pl) |
2112 | { |
2113 | const char *pname = prefix_list_name(pl); |
2114 | |
2115 | if (pim->spt.plist && strcmp(pim->spt.plist, pname) == 0) { |
2116 | pim_upstream_remove_lhr_star_pimreg(pim, pname); |
2117 | } |
2118 | } |
2119 | |
2120 | /* |
2121 | * nlist -> The new prefix list |
2122 | * |
2123 | * Per Group Application of pimreg to the OIL |
2124 | * If the prefix list tells us DENY then |
2125 | * we need to Switchover to SPT immediate |
2126 | * so add the pimreg. |
2127 | * If the prefix list tells us to ACCEPT than |
2128 | * we need to Never do the SPT so remove |
2129 | * the interface |
2130 | * |
2131 | */ |
2132 | void pim_upstream_remove_lhr_star_pimreg(struct pim_instance *pim, |
2133 | const char *nlist) |
2134 | { |
2135 | struct pim_upstream *up; |
2136 | struct prefix_list *np; |
2137 | struct prefix g; |
2138 | enum prefix_list_type apply_new; |
2139 | |
2140 | np = prefix_list_lookup(PIM_AFIAFI_IP, nlist); |
2141 | |
2142 | frr_each (rb_pim_upstream, &pim->upstream_head, up)for (up = rb_pim_upstream_first(&pim->upstream_head); up ; up = rb_pim_upstream_next(&pim->upstream_head, up)) { |
2143 | if (!pim_addr_is_any(up->sg.src)) |
2144 | continue; |
2145 | |
2146 | if (!PIM_UPSTREAM_FLAG_TEST_CAN_BE_LHR(up->flags)((up->flags) & ((1 << 3) | (1 << 15)))) |
2147 | continue; |
2148 | |
2149 | if (!nlist) { |
2150 | pim_channel_del_oif(up->channel_oil, pim->regiface, |
2151 | PIM_OIF_FLAG_PROTO_GM(1 << 0), __func__); |
2152 | continue; |
2153 | } |
2154 | pim_addr_to_prefix(&g, up->sg.grp); |
2155 | apply_new = prefix_list_apply_ext(np, NULL((void*)0), &g, true1); |
2156 | if (apply_new == PREFIX_DENY) |
2157 | pim_channel_add_oif(up->channel_oil, pim->regiface, |
2158 | PIM_OIF_FLAG_PROTO_GM(1 << 0), __func__); |
2159 | else |
2160 | pim_channel_del_oif(up->channel_oil, pim->regiface, |
2161 | PIM_OIF_FLAG_PROTO_GM(1 << 0), __func__); |
2162 | } |
2163 | } |
2164 | |
2165 | void pim_upstream_init(struct pim_instance *pim) |
2166 | { |
2167 | char name[64]; |
2168 | |
2169 | snprintf(name, sizeof(name), "PIM %s Timer Wheel", pim->vrf->name); |
2170 | pim->upstream_sg_wheel = |
2171 | wheel_init(router->master, 31000, 100, pim_upstream_hash_key, |
2172 | pim_upstream_sg_running, name); |
2173 | |
2174 | rb_pim_upstream_init(&pim->upstream_head); |
2175 | } |