]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_zebra.c
ospf6d: Add missing vrf lookup
[mirror_frr.git] / pimd / pim_zebra.c
CommitLineData
12e41d03 1/*
896014f4
DL
2 * PIM for Quagga
3 * Copyright (C) 2008 Everton da Silva Marques
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
12e41d03
DL
19
20#include <zebra.h>
21
22#include "zebra/rib.h"
23
24#include "if.h"
25#include "log.h"
26#include "prefix.h"
27#include "zclient.h"
28#include "stream.h"
29#include "network.h"
dfe43e25
DW
30#include "vty.h"
31#include "plist.h"
ba4eb1bc 32#include "lib/bfd.h"
12e41d03
DL
33
34#include "pimd.h"
35#include "pim_pim.h"
36#include "pim_zebra.h"
37#include "pim_iface.h"
38#include "pim_str.h"
39#include "pim_oil.h"
40#include "pim_rpf.h"
41#include "pim_time.h"
42#include "pim_join.h"
43#include "pim_zlookup.h"
44#include "pim_ifchannel.h"
8f5f5e91 45#include "pim_rp.h"
2560106c 46#include "pim_igmpv3.h"
982bff89 47#include "pim_jp_agg.h"
1bc98276 48#include "pim_nht.h"
15a5dafe 49#include "pim_ssm.h"
12e41d03
DL
50
51#undef PIM_DEBUG_IFADDR_DUMP
52#define PIM_DEBUG_IFADDR_DUMP
53
38f4935a
DS
54static struct zclient *zclient = NULL;
55
12e41d03 56
12e41d03
DL
57/* Router-id update message from zebra. */
58static int pim_router_id_update_zebra(int command, struct zclient *zclient,
469351b3 59 zebra_size_t length, vrf_id_t vrf_id)
12e41d03 60{
d62a17ae 61 struct prefix router_id;
12e41d03 62
d62a17ae 63 zebra_router_id_update_read(zclient->ibuf, &router_id);
12e41d03 64
d62a17ae 65 return 0;
12e41d03
DL
66}
67
68static int pim_zebra_if_add(int command, struct zclient *zclient,
469351b3 69 zebra_size_t length, vrf_id_t vrf_id)
12e41d03 70{
d62a17ae 71 struct interface *ifp;
72
73 /*
74 zebra api adds/dels interfaces using the same call
75 interface_add_read below, see comments in lib/zclient.c
76 */
77 ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
78 if (!ifp)
79 return 0;
80
81 if (PIM_DEBUG_ZEBRA) {
82 zlog_debug(
e0ae31b8
DS
83 "%s: %s index %d(%d) flags %ld metric %d mtu %d operative %d",
84 __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
d62a17ae 85 (long)ifp->flags, ifp->metric, ifp->mtu,
86 if_is_operative(ifp));
87 }
88
89 if (if_is_operative(ifp))
90 pim_if_addr_add_all(ifp);
91
90133de6
DS
92 /*
93 * If we are a vrf device that is up, open up the pim_socket for
94 * listening
95 * to incoming pim messages irrelevant if the user has configured us
96 * for pim or not.
97 */
98 if (pim_if_is_vrf_device(ifp)) {
99 struct pim_interface *pim_ifp;
100
101 if (!ifp->info) {
102 pim_ifp = pim_if_new(ifp, 0, 0);
103 ifp->info = pim_ifp;
104 }
105
106 pim_sock_add(ifp);
107 }
108
d62a17ae 109 return 0;
12e41d03
DL
110}
111
112static int pim_zebra_if_del(int command, struct zclient *zclient,
469351b3 113 zebra_size_t length, vrf_id_t vrf_id)
12e41d03 114{
d62a17ae 115 struct interface *ifp;
116
117 /*
118 zebra api adds/dels interfaces using the same call
119 interface_add_read below, see comments in lib/zclient.c
120
121 comments in lib/zclient.c seem to indicate that calling
122 zebra_interface_add_read is the correct call, but that
123 results in an attemted out of bounds read which causes
124 pimd to assert. Other clients use zebra_interface_state_read
125 and it appears to work just fine.
126 */
127 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
128 if (!ifp)
129 return 0;
130
131 if (PIM_DEBUG_ZEBRA) {
132 zlog_debug(
e0ae31b8
DS
133 "%s: %s index %d(%d) flags %ld metric %d mtu %d operative %d",
134 __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
d62a17ae 135 (long)ifp->flags, ifp->metric, ifp->mtu,
136 if_is_operative(ifp));
137 }
138
139 if (!if_is_operative(ifp))
140 pim_if_addr_del_all(ifp);
141
142 return 0;
12e41d03
DL
143}
144
145static int pim_zebra_if_state_up(int command, struct zclient *zclient,
469351b3 146 zebra_size_t length, vrf_id_t vrf_id)
12e41d03 147{
d62a17ae 148 struct interface *ifp;
e0ae31b8 149 uint32_t table_id;
d62a17ae 150
151 /*
152 zebra api notifies interface up/down events by using the same call
153 zebra_interface_state_read below, see comments in lib/zclient.c
154 */
155 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
156 if (!ifp)
157 return 0;
158
159 if (PIM_DEBUG_ZEBRA) {
160 zlog_debug(
e0ae31b8
DS
161 "%s: %s index %d(%d) flags %ld metric %d mtu %d operative %d",
162 __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
d62a17ae 163 (long)ifp->flags, ifp->metric, ifp->mtu,
164 if_is_operative(ifp));
165 }
166
167 if (if_is_operative(ifp)) {
168 /*
169 pim_if_addr_add_all() suffices for bringing up both IGMP and
170 PIM
171 */
172 pim_if_addr_add_all(ifp);
173 }
174
e0ae31b8
DS
175 /*
176 * If we have a pimreg device callback and it's for a specific
177 * table set the master appropriately
178 */
179 if (sscanf(ifp->name, "pimreg%d", &table_id) == 1) {
180 struct vrf *vrf;
a2addae8 181 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
e0ae31b8
DS
182 if ((table_id == vrf->data.l.table_id)
183 && (ifp->vrf_id != vrf->vrf_id)) {
184 struct interface *master = if_lookup_by_name(
185 vrf->name, vrf->vrf_id);
e691f179
DS
186
187 if (!master) {
188 zlog_debug("%s: Unable to find Master interface for %s",
189 __PRETTY_FUNCTION__,
190 vrf->name);
191 return 0;
192 }
e0ae31b8
DS
193 zclient_interface_set_master(zclient, master,
194 ifp);
195 }
196 }
197 }
d62a17ae 198 return 0;
12e41d03
DL
199}
200
201static int pim_zebra_if_state_down(int command, struct zclient *zclient,
469351b3 202 zebra_size_t length, vrf_id_t vrf_id)
12e41d03 203{
d62a17ae 204 struct interface *ifp;
205
206 /*
207 zebra api notifies interface up/down events by using the same call
208 zebra_interface_state_read below, see comments in lib/zclient.c
209 */
210 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
211 if (!ifp)
212 return 0;
213
214 if (PIM_DEBUG_ZEBRA) {
215 zlog_debug(
e0ae31b8
DS
216 "%s: %s index %d(%d) flags %ld metric %d mtu %d operative %d",
217 __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
d62a17ae 218 (long)ifp->flags, ifp->metric, ifp->mtu,
219 if_is_operative(ifp));
220 }
221
222 if (!if_is_operative(ifp)) {
223 pim_ifchannel_delete_all(ifp);
224 /*
225 pim_if_addr_del_all() suffices for shutting down IGMP,
226 but not for shutting down PIM
227 */
228 pim_if_addr_del_all(ifp);
229
230 /*
231 pim_sock_delete() closes the socket, stops read and timer
232 threads,
233 and kills all neighbors.
234 */
235 if (ifp->info) {
236 pim_sock_delete(ifp, "link down");
237 }
238 }
239
240 if (ifp->info)
241 pim_if_del_vif(ifp);
242
243 return 0;
12e41d03
DL
244}
245
246#ifdef PIM_DEBUG_IFADDR_DUMP
247static void dump_if_address(struct interface *ifp)
248{
d62a17ae 249 struct connected *ifc;
250 struct listnode *node;
251
252 zlog_debug("%s %s: interface %s addresses:", __FILE__,
253 __PRETTY_FUNCTION__, ifp->name);
254
255 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
256 struct prefix *p = ifc->address;
257
258 if (p->family != AF_INET)
259 continue;
260
261 zlog_debug("%s %s: interface %s address %s %s", __FILE__,
262 __PRETTY_FUNCTION__, ifp->name,
263 inet_ntoa(p->u.prefix4),
264 CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)
265 ? "secondary"
266 : "primary");
267 }
12e41d03
DL
268}
269#endif
270
271static int pim_zebra_if_address_add(int command, struct zclient *zclient,
469351b3 272 zebra_size_t length, vrf_id_t vrf_id)
12e41d03 273{
d62a17ae 274 struct connected *c;
275 struct prefix *p;
276 struct pim_interface *pim_ifp;
277
278 /*
279 zebra api notifies address adds/dels events by using the same call
280 interface_add_read below, see comments in lib/zclient.c
281
282 zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...)
283 will add address to interface list by calling
284 connected_add_by_prefix()
285 */
286 c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
287 if (!c)
288 return 0;
289
290 pim_ifp = c->ifp->info;
291 p = c->address;
292
293 if (PIM_DEBUG_ZEBRA) {
294 char buf[BUFSIZ];
295 prefix2str(p, buf, BUFSIZ);
e0ae31b8
DS
296 zlog_debug("%s: %s(%d) connected IP address %s flags %u %s",
297 __PRETTY_FUNCTION__, c->ifp->name, vrf_id, buf,
298 c->flags, CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
299 ? "secondary"
300 : "primary");
d62a17ae 301
12e41d03 302#ifdef PIM_DEBUG_IFADDR_DUMP
d62a17ae 303 dump_if_address(c->ifp);
12e41d03 304#endif
d62a17ae 305 }
12e41d03 306
d62a17ae 307 if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) {
308 /* trying to add primary address */
12e41d03 309
d62a17ae 310 struct in_addr primary_addr = pim_find_primary_addr(c->ifp);
311 if (p->family != AF_INET
312 || primary_addr.s_addr != p->u.prefix4.s_addr) {
313 if (PIM_DEBUG_ZEBRA) {
314 /* but we had a primary address already */
12e41d03 315
d62a17ae 316 char buf[BUFSIZ];
12e41d03 317
d62a17ae 318 prefix2str(p, buf, BUFSIZ);
12e41d03 319
d62a17ae 320 zlog_warn(
321 "%s: %s : forcing secondary flag on %s",
322 __PRETTY_FUNCTION__, c->ifp->name, buf);
323 }
324 SET_FLAG(c->flags, ZEBRA_IFA_SECONDARY);
325 }
326 }
12e41d03 327
d62a17ae 328 pim_if_addr_add(c);
329 if (pim_ifp)
330 pim_rp_check_on_if_add(pim_ifp);
12e41d03 331
d62a17ae 332 if (if_is_loopback(c->ifp)) {
f4e14fdb 333 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
d62a17ae 334 struct interface *ifp;
d8424057 335
f4e14fdb 336 RB_FOREACH (ifp, if_name_head, &vrf->ifaces_by_name) {
d62a17ae 337 if (!if_is_loopback(ifp) && if_is_operative(ifp))
338 pim_if_addr_add_all(ifp);
339 }
340 }
d8424057 341
d62a17ae 342 return 0;
12e41d03
DL
343}
344
345static int pim_zebra_if_address_del(int command, struct zclient *client,
469351b3 346 zebra_size_t length, vrf_id_t vrf_id)
12e41d03 347{
d62a17ae 348 struct connected *c;
349 struct prefix *p;
fec883d9
DS
350 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
351 struct pim_instance *pim = vrf->info;
d62a17ae 352
353 /*
354 zebra api notifies address adds/dels events by using the same call
355 interface_add_read below, see comments in lib/zclient.c
356
357 zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...)
358 will remove address from interface list by calling
359 connected_delete_by_prefix()
360 */
361 c = zebra_interface_address_read(command, client->ibuf, vrf_id);
362 if (!c)
363 return 0;
364
365 p = c->address;
366 if (p->family == AF_INET) {
367 if (PIM_DEBUG_ZEBRA) {
368 char buf[BUFSIZ];
369 prefix2str(p, buf, BUFSIZ);
370 zlog_debug(
e0ae31b8
DS
371 "%s: %s(%d) disconnected IP address %s flags %u %s",
372 __PRETTY_FUNCTION__, c->ifp->name, vrf_id, buf,
d62a17ae 373 c->flags,
374 CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
375 ? "secondary"
376 : "primary");
6233f087 377
12e41d03 378#ifdef PIM_DEBUG_IFADDR_DUMP
d62a17ae 379 dump_if_address(c->ifp);
12e41d03 380#endif
d62a17ae 381 }
12e41d03 382
d62a17ae 383 pim_if_addr_del(c, 0);
fec883d9
DS
384 pim_rp_setup(pim);
385 pim_i_am_rp_re_evaluate(pim);
d62a17ae 386 }
6233f087 387
d62a17ae 388 connected_free(c);
389 return 0;
12e41d03
DL
390}
391
392static void scan_upstream_rpf_cache()
393{
d62a17ae 394 struct listnode *up_node;
d62a17ae 395 struct listnode *up_nextnode;
396 struct listnode *node;
397 struct pim_upstream *up;
398 struct interface *ifp;
9b29ea95
DS
399 struct vrf *vrf;
400 struct pim_instance *pim;
d62a17ae 401
a2addae8 402 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
9b29ea95
DS
403 pim = vrf->info;
404 if (!pim)
405 continue;
d62a17ae 406
9b29ea95
DS
407 for (ALL_LIST_ELEMENTS(pim->upstream_list, up_node, up_nextnode,
408 up)) {
409 enum pim_rpf_result rpf_result;
410 struct pim_rpf old;
411 struct prefix nht_p;
d62a17ae 412
9b29ea95
DS
413 nht_p.family = AF_INET;
414 nht_p.prefixlen = IPV4_MAX_BITLEN;
415 nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr;
416 pim_resolve_upstream_nh(pim, &nht_p);
d62a17ae 417
9b29ea95
DS
418 old.source_nexthop.interface =
419 up->rpf.source_nexthop.interface;
420 old.source_nexthop.nbr = up->rpf.source_nexthop.nbr;
2002dcdb 421 rpf_result = pim_rpf_update(pim, up, &old, 0);
d62a17ae 422
9b29ea95
DS
423 if (rpf_result == PIM_RPF_FAILURE)
424 continue;
d62a17ae 425
9b29ea95
DS
426 if (rpf_result == PIM_RPF_CHANGED) {
427 struct pim_neighbor *nbr;
d62a17ae 428
9b29ea95
DS
429 nbr = pim_neighbor_find(
430 old.source_nexthop.interface,
431 old.rpf_addr.u.prefix4);
432 if (nbr)
433 pim_jp_agg_remove_group(
434 nbr->upstream_jp_agg, up);
d62a17ae 435
436 /*
9b29ea95
DS
437 * We have detected a case where we might need
438 * to rescan
439 * the inherited o_list so do it.
d62a17ae 440 */
9b29ea95
DS
441 if (up->channel_oil->oil_inherited_rescan) {
442 pim_upstream_inherited_olist_decide(pim,
443 up);
444 up->channel_oil->oil_inherited_rescan =
445 0;
446 }
447
448 if (up->join_state == PIM_UPSTREAM_JOINED) {
449 /*
450 * If we come up real fast we can be
451 * here
452 * where the mroute has not been
453 * installed
454 * so install it.
455 */
456 if (!up->channel_oil->installed)
457 pim_mroute_add(
458 up->channel_oil,
459 __PRETTY_FUNCTION__);
460
461 /*
462 * RFC 4601: 4.5.7. Sending (S,G)
463 * Join/Prune Messages
464 *
465 * Transitions from Joined State
466 *
467 * RPF'(S,G) changes not due to an
468 * Assert
469 *
470 * The upstream (S,G) state machine
471 * remains in Joined
472 * state. Send Join(S,G) to the new
473 * upstream neighbor, which is
474 * the new value of RPF'(S,G). Send
475 * Prune(S,G) to the old
476 * upstream neighbor, which is the old
477 * value of RPF'(S,G). Set
478 * the Join Timer (JT) to expire after
479 * t_periodic seconds.
480 */
481 pim_jp_agg_switch_interface(
482 &old, &up->rpf, up);
483
484 pim_upstream_join_timer_restart(up,
485 &old);
486 } /* up->join_state == PIM_UPSTREAM_JOINED */
487
488 /* FIXME can join_desired actually be changed by
489 pim_rpf_update()
490 returning PIM_RPF_CHANGED ? */
491 pim_upstream_update_join_desired(pim, up);
492
493 } /* PIM_RPF_CHANGED */
494
495 } /* for (qpim_upstream_list) */
496 }
d62a17ae 497
a2addae8 498 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
9b29ea95
DS
499 pim = vrf->info;
500 if (!pim)
501 continue;
d62a17ae 502
f4e14fdb 503 RB_FOREACH (ifp, if_name_head, &pim->vrf->ifaces_by_name)
9b29ea95
DS
504 if (ifp->info) {
505 struct pim_interface *pim_ifp = ifp->info;
506 struct pim_iface_upstream_switch *us;
d62a17ae 507
9b29ea95
DS
508 for (ALL_LIST_ELEMENTS_RO(
509 pim_ifp->upstream_switch_list,
510 node, us)) {
511 struct pim_rpf rpf;
512 rpf.source_nexthop.interface = ifp;
513 rpf.rpf_addr.u.prefix4 = us->address;
514 pim_joinprune_send(&rpf, us->us);
515 pim_jp_agg_clear_group(us->us);
516 }
d62a17ae 517 }
9b29ea95 518 }
12e41d03
DL
519}
520
d62a17ae 521void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index)
12e41d03 522{
d62a17ae 523 struct in_addr vif_source;
524 int input_iface_vif_index;
525 int old_vif_index;
526
d9c9a9ee
DS
527 if (!pim_rp_set_upstream_addr(c_oil->pim, &vif_source,
528 c_oil->oil.mfcc_origin,
d62a17ae 529 c_oil->oil.mfcc_mcastgrp))
530 return;
531
532 if (in_vif_index)
533 input_iface_vif_index = in_vif_index;
534 else {
535 struct prefix src, grp;
536
537 src.family = AF_INET;
538 src.prefixlen = IPV4_MAX_BITLEN;
539 src.u.prefix4 = vif_source;
540 grp.family = AF_INET;
541 grp.prefixlen = IPV4_MAX_BITLEN;
542 grp.u.prefix4 = c_oil->oil.mfcc_mcastgrp;
543
544 if (PIM_DEBUG_ZEBRA) {
545 char source_str[INET_ADDRSTRLEN];
546 char group_str[INET_ADDRSTRLEN];
547 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
548 source_str, sizeof(source_str));
549 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
550 group_str, sizeof(group_str));
551 zlog_debug(
a895ac30 552 "%s: channel_oil (%s,%s) upstream info is not present.",
d62a17ae 553 __PRETTY_FUNCTION__, source_str, group_str);
554 }
555 input_iface_vif_index = pim_ecmp_fib_lookup_if_vif_index(
25b787a2 556 c_oil->pim, vif_source, &src, &grp);
d62a17ae 557 }
558
559 if (input_iface_vif_index < 1) {
560 if (PIM_DEBUG_ZEBRA) {
561 char source_str[INET_ADDRSTRLEN];
562 char group_str[INET_ADDRSTRLEN];
563 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
564 source_str, sizeof(source_str));
565 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
566 group_str, sizeof(group_str));
567 zlog_debug(
568 "%s %s: could not find input interface(%d) for (S,G)=(%s,%s)",
569 __FILE__, __PRETTY_FUNCTION__,
570 c_oil->oil.mfcc_parent, source_str, group_str);
571 }
572 pim_mroute_del(c_oil, __PRETTY_FUNCTION__);
573 return;
574 }
575
576 if (input_iface_vif_index == c_oil->oil.mfcc_parent) {
577 if (!c_oil->installed)
578 pim_mroute_add(c_oil, __PRETTY_FUNCTION__);
579
580 /* RPF unchanged */
581 return;
582 }
583
584 if (PIM_DEBUG_ZEBRA) {
7cfc7bcf
DS
585 struct interface *old_iif = pim_if_find_by_vif_index(
586 c_oil->pim, c_oil->oil.mfcc_parent);
587 struct interface *new_iif = pim_if_find_by_vif_index(
588 c_oil->pim, input_iface_vif_index);
d62a17ae 589 char source_str[INET_ADDRSTRLEN];
590 char group_str[INET_ADDRSTRLEN];
591 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str,
592 sizeof(source_str));
593 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str,
594 sizeof(group_str));
595 zlog_debug(
596 "%s %s: (S,G)=(%s,%s) input interface changed from %s vif_index=%d to %s vif_index=%d",
597 __FILE__, __PRETTY_FUNCTION__, source_str, group_str,
598 old_iif->name, c_oil->oil.mfcc_parent, new_iif->name,
599 input_iface_vif_index);
600 }
601
602 /* new iif loops to existing oif ? */
603 if (c_oil->oil.mfcc_ttls[input_iface_vif_index]) {
7cfc7bcf
DS
604 struct interface *new_iif = pim_if_find_by_vif_index(
605 c_oil->pim, input_iface_vif_index);
d62a17ae 606
607 if (PIM_DEBUG_ZEBRA) {
608 char source_str[INET_ADDRSTRLEN];
609 char group_str[INET_ADDRSTRLEN];
610 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
611 source_str, sizeof(source_str));
612 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
613 group_str, sizeof(group_str));
614 zlog_debug(
615 "%s %s: (S,G)=(%s,%s) new iif loops to existing oif: %s vif_index=%d",
616 __FILE__, __PRETTY_FUNCTION__, source_str,
617 group_str, new_iif->name,
618 input_iface_vif_index);
619 }
620 }
621
622 /* update iif vif_index */
623 old_vif_index = c_oil->oil.mfcc_parent;
624 c_oil->oil.mfcc_parent = input_iface_vif_index;
625
626 /* update kernel multicast forwarding cache (MFC) */
627 if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) {
628 if (PIM_DEBUG_MROUTE) {
629 /* just log warning */
7cfc7bcf
DS
630 struct interface *old_iif = pim_if_find_by_vif_index(
631 c_oil->pim, old_vif_index);
632 struct interface *new_iif = pim_if_find_by_vif_index(
633 c_oil->pim, input_iface_vif_index);
d62a17ae 634 char source_str[INET_ADDRSTRLEN];
635 char group_str[INET_ADDRSTRLEN];
636 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
637 source_str, sizeof(source_str));
638 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
639 group_str, sizeof(group_str));
640 zlog_debug(
641 "%s %s: (S,G)=(%s,%s) failure updating input interface from %s vif_index=%d to %s vif_index=%d",
642 __FILE__, __PRETTY_FUNCTION__, source_str,
643 group_str,
644 old_iif ? old_iif->name : "<old_iif?>",
645 c_oil->oil.mfcc_parent,
646 new_iif ? new_iif->name : "<new_iif?>",
647 input_iface_vif_index);
648 }
649 }
8a67a996
DS
650}
651
c68ba0d7 652void pim_scan_oil(struct pim_instance *pim_matcher)
8a67a996 653{
d62a17ae 654 struct listnode *node;
655 struct listnode *nextnode;
656 struct channel_oil *c_oil;
657 ifindex_t ifindex;
658 int vif_index = 0;
611925dc
DS
659 struct vrf *vrf;
660 struct pim_instance *pim;
d62a17ae 661
662 qpim_scan_oil_last = pim_time_monotonic_sec();
663 ++qpim_scan_oil_events;
664
a2addae8 665 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
611925dc
DS
666 pim = vrf->info;
667 if (!pim)
668 continue;
669
c68ba0d7
DS
670 if (pim_matcher && pim != pim_matcher)
671 continue;
672
611925dc
DS
673 for (ALL_LIST_ELEMENTS(pim->channel_oil_list, node, nextnode,
674 c_oil)) {
675 if (c_oil->up
676 && c_oil->up->rpf.source_nexthop.interface) {
677 ifindex = c_oil->up->rpf.source_nexthop
678 .interface->ifindex;
679 vif_index = pim_if_find_vifindex_by_ifindex(
680 pim, ifindex);
681 /* Pass Current selected NH vif index to mroute
682 * download */
683 if (vif_index)
684 pim_scan_individual_oil(c_oil,
685 vif_index);
686 } else
687 pim_scan_individual_oil(c_oil, 0);
688 }
d62a17ae 689 }
12e41d03
DL
690}
691
692static int on_rpf_cache_refresh(struct thread *t)
693{
d62a17ae 694 /* update PIM protocol state */
695 scan_upstream_rpf_cache();
12e41d03 696
d62a17ae 697 /* update kernel multicast forwarding cache (MFC) */
c68ba0d7 698 pim_scan_oil(NULL);
12e41d03 699
d62a17ae 700 qpim_rpf_cache_refresh_last = pim_time_monotonic_sec();
701 ++qpim_rpf_cache_refresh_events;
12e41d03 702
d62a17ae 703 // It is called as part of pim_neighbor_add
704 // pim_rp_setup ();
705 return 0;
12e41d03
DL
706}
707
da72c9fd 708void sched_rpf_cache_refresh(void)
12e41d03 709{
d62a17ae 710 ++qpim_rpf_cache_refresh_requests;
12e41d03 711
d62a17ae 712 pim_rpf_set_refresh_time();
e71bf8f7 713
d62a17ae 714 if (qpim_rpf_cache_refresher) {
715 /* Refresh timer is already running */
716 return;
717 }
12e41d03 718
d62a17ae 719 /* Start refresh timer */
12e41d03 720
d62a17ae 721 if (PIM_DEBUG_ZEBRA) {
722 zlog_debug("%s: triggering %ld msec timer", __PRETTY_FUNCTION__,
723 qpim_rpf_cache_refresh_delay_msec);
724 }
12e41d03 725
d62a17ae 726 thread_add_timer_msec(master, on_rpf_cache_refresh, 0,
727 qpim_rpf_cache_refresh_delay_msec,
728 &qpim_rpf_cache_refresher);
12e41d03
DL
729}
730
d62a17ae 731static void pim_zebra_connected(struct zclient *zclient)
48e8451b 732{
d62a17ae 733 /* Send the client registration */
734 bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
ba4eb1bc 735
0708beb1 736 zclient_send_reg_requests(zclient, pimg->vrf_id);
48e8451b 737}
8711a53d 738
eb05883f 739void pim_zebra_init(void)
12e41d03 740{
d62a17ae 741 int i;
12e41d03 742
d62a17ae 743 /* Socket for receiving updates from Zebra daemon */
744 zclient = zclient_new(master);
745
746 zclient->zebra_connected = pim_zebra_connected;
747 zclient->router_id_update = pim_router_id_update_zebra;
748 zclient->interface_add = pim_zebra_if_add;
749 zclient->interface_delete = pim_zebra_if_del;
750 zclient->interface_up = pim_zebra_if_state_up;
751 zclient->interface_down = pim_zebra_if_state_down;
752 zclient->interface_address_add = pim_zebra_if_address_add;
753 zclient->interface_address_delete = pim_zebra_if_address_del;
754 zclient->nexthop_update = pim_parse_nexthop_update;
755
756 zclient_init(zclient, ZEBRA_ROUTE_PIM, 0);
757 if (PIM_DEBUG_PIM_TRACE) {
758 zlog_info("zclient_init cleared redistribution request");
759 }
760
761 zassert(zclient->redist_default == ZEBRA_ROUTE_PIM);
762
763 /* Request all redistribution */
764 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
765 if (i == zclient->redist_default)
766 continue;
0708beb1 767 vrf_bitmap_set(zclient->redist[AFI_IP][i], pimg->vrf_id);
d62a17ae 768 ;
769 if (PIM_DEBUG_PIM_TRACE) {
770 zlog_debug("%s: requesting redistribution for %s (%i)",
771 __PRETTY_FUNCTION__, zebra_route_string(i),
772 i);
773 }
774 }
775
776 /* Request default information */
777 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient,
0708beb1 778 pimg->vrf_id);
d62a17ae 779
780 if (PIM_DEBUG_PIM_TRACE) {
781 zlog_info("%s: requesting default information redistribution",
782 __PRETTY_FUNCTION__);
783
784 zlog_notice("%s: zclient update socket initialized",
785 __PRETTY_FUNCTION__);
786 }
787
788 zclient_lookup_new();
12e41d03
DL
789}
790
6f932b0c
DS
791void igmp_anysource_forward_start(struct pim_instance *pim,
792 struct igmp_group *group)
12e41d03 793{
d62a17ae 794 struct igmp_source *source;
795 struct in_addr src_addr = {.s_addr = 0};
796 /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */
797 zassert(group->group_filtermode_isexcl);
798 zassert(listcount(group->group_source_list) < 1);
799
800 source = source_new(group, src_addr);
801 if (!source) {
802 zlog_warn("%s: Failure to create * source",
803 __PRETTY_FUNCTION__);
804 return;
805 }
806
6f932b0c 807 igmp_source_forward_start(pim, source);
12e41d03
DL
808}
809
810void igmp_anysource_forward_stop(struct igmp_group *group)
811{
d62a17ae 812 struct igmp_source *source;
813 struct in_addr star = {.s_addr = 0};
12e41d03 814
d62a17ae 815 source = igmp_find_source_by_addr(group, star);
816 if (source)
817 igmp_source_forward_stop(source);
12e41d03
DL
818}
819
6f439a70
DS
820static void igmp_source_forward_reevaluate_one(struct pim_instance *pim,
821 struct igmp_source *source)
15a5dafe 822{
d62a17ae 823 struct prefix_sg sg;
824 struct igmp_group *group = source->source_group;
825 struct pim_ifchannel *ch;
826
827 if ((source->source_addr.s_addr != INADDR_ANY)
828 || !IGMP_SOURCE_TEST_FORWARDING(source->source_flags))
829 return;
830
831 memset(&sg, 0, sizeof(struct prefix_sg));
832 sg.src = source->source_addr;
833 sg.grp = group->group_addr;
834
835 ch = pim_ifchannel_find(group->group_igmp_sock->interface, &sg);
6f439a70 836 if (pim_is_grp_ssm(pim, group->group_addr)) {
d62a17ae 837 /* If SSM group withdraw local membership */
838 if (ch
839 && (ch->local_ifmembership == PIM_IFMEMBERSHIP_INCLUDE)) {
840 if (PIM_DEBUG_PIM_EVENTS)
841 zlog_debug(
842 "local membership del for %s as G is now SSM",
843 pim_str_sg_dump(&sg));
844 pim_ifchannel_local_membership_del(
845 group->group_igmp_sock->interface, &sg);
846 }
847 } else {
848 /* If ASM group add local membership */
849 if (!ch
850 || (ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO)) {
851 if (PIM_DEBUG_PIM_EVENTS)
852 zlog_debug(
853 "local membership add for %s as G is now ASM",
854 pim_str_sg_dump(&sg));
855 pim_ifchannel_local_membership_add(
856 group->group_igmp_sock->interface, &sg);
857 }
858 }
15a5dafe 859}
860
d62a17ae 861void igmp_source_forward_reevaluate_all(void)
15a5dafe 862{
d62a17ae 863 struct interface *ifp;
6f932b0c
DS
864 struct vrf *vrf;
865 struct pim_instance *pim;
d62a17ae 866
a2addae8 867 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
6f932b0c
DS
868 pim = vrf->info;
869 if (!pim)
d62a17ae 870 continue;
871
f4e14fdb 872 RB_FOREACH (ifp, if_name_head, &pim->vrf->ifaces_by_name) {
6f932b0c
DS
873 struct pim_interface *pim_ifp = ifp->info;
874 struct listnode *sock_node;
875 struct igmp_sock *igmp;
d62a17ae 876
6f932b0c
DS
877 if (!pim_ifp)
878 continue;
d62a17ae 879
6f932b0c
DS
880 /* scan igmp sockets */
881 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list,
882 sock_node, igmp)) {
883 struct listnode *grpnode;
884 struct igmp_group *grp;
885
886 /* scan igmp groups */
887 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
888 grpnode, grp)) {
889 struct listnode *srcnode;
890 struct igmp_source *src;
891
892 /* scan group sources */
893 for (ALL_LIST_ELEMENTS_RO(
894 grp->group_source_list,
895 srcnode, src)) {
896 igmp_source_forward_reevaluate_one(
6f439a70 897 pim, src);
6f932b0c
DS
898 } /* scan group sources */
899 } /* scan igmp groups */
900 } /* scan igmp sockets */
901 } /* scan interfaces */
902 }
15a5dafe 903}
904
6f932b0c
DS
905void igmp_source_forward_start(struct pim_instance *pim,
906 struct igmp_source *source)
12e41d03 907{
d62a17ae 908 struct igmp_group *group;
909 struct prefix_sg sg;
910 int result;
911 int input_iface_vif_index = 0;
912
913 memset(&sg, 0, sizeof(struct prefix_sg));
914 sg.src = source->source_addr;
915 sg.grp = source->source_group->group_addr;
916
917 if (PIM_DEBUG_IGMP_TRACE) {
918 zlog_debug(
919 "%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d",
920 __PRETTY_FUNCTION__, pim_str_sg_dump(&sg),
921 source->source_group->group_igmp_sock->fd,
922 source->source_group->group_igmp_sock->interface->name,
923 IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
924 }
925
926 /* Prevent IGMP interface from installing multicast route multiple
927 times */
928 if (IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
929 return;
8711a53d 930 }
d62a17ae 931
932 group = source->source_group;
933
934 if (!source->source_channel_oil) {
935 struct in_addr vif_source;
936 struct pim_interface *pim_oif;
937 struct prefix nht_p, src, grp;
d62a17ae 938 struct pim_nexthop_cache out_pnc;
939 struct pim_nexthop nexthop;
940 struct pim_upstream *up = NULL;
941
6f932b0c 942 if (!pim_rp_set_upstream_addr(pim, &vif_source,
d9c9a9ee 943 source->source_addr, sg.grp))
d62a17ae 944 return;
945
946 /* Register addr with Zebra NHT */
947 nht_p.family = AF_INET;
948 nht_p.prefixlen = IPV4_MAX_BITLEN;
949 nht_p.u.prefix4 = vif_source;
950 memset(&out_pnc, 0, sizeof(struct pim_nexthop_cache));
951
952 src.family = AF_INET;
953 src.prefixlen = IPV4_MAX_BITLEN;
954 src.u.prefix4 = vif_source; // RP or Src address
955 grp.family = AF_INET;
956 grp.prefixlen = IPV4_MAX_BITLEN;
957 grp.u.prefix4 = sg.grp;
958
6f932b0c 959 if (pim_find_or_track_nexthop(pim, &nht_p, NULL, NULL,
25bdac42 960 &out_pnc)) {
d62a17ae 961 if (out_pnc.nexthop_num) {
6f932b0c 962 up = pim_upstream_find(pim, &sg);
cb9c7c50 963 memset(&nexthop, 0, sizeof(nexthop));
d62a17ae 964 if (up)
965 memcpy(&nexthop,
966 &up->rpf.source_nexthop,
967 sizeof(struct pim_nexthop));
6f932b0c
DS
968 pim_ecmp_nexthop_search(pim, &out_pnc, &nexthop,
969 &src, &grp, 0);
d62a17ae 970 if (nexthop.interface)
971 input_iface_vif_index =
972 pim_if_find_vifindex_by_ifindex(
6f932b0c 973 pim,
d62a17ae 974 nexthop.interface->ifindex);
975 } else {
976 if (PIM_DEBUG_ZEBRA) {
977 char buf1[INET_ADDRSTRLEN];
978 char buf2[INET_ADDRSTRLEN];
979 pim_inet4_dump("<source?>",
980 nht_p.u.prefix4, buf1,
981 sizeof(buf1));
982 pim_inet4_dump("<source?>",
983 grp.u.prefix4, buf2,
984 sizeof(buf2));
985 zlog_debug(
986 "%s: NHT Nexthop not found for addr %s grp %s",
987 __PRETTY_FUNCTION__, buf1,
988 buf2);
989 }
990 }
991 } else
992 input_iface_vif_index =
25b787a2 993 pim_ecmp_fib_lookup_if_vif_index(
6f932b0c 994 pim, vif_source, &src, &grp);
d62a17ae 995
996 if (PIM_DEBUG_ZEBRA) {
997 char buf2[INET_ADDRSTRLEN];
998 pim_inet4_dump("<source?>", vif_source, buf2,
999 sizeof(buf2));
1000 zlog_debug("%s: NHT %s vif_source %s vif_index:%d ",
1001 __PRETTY_FUNCTION__, pim_str_sg_dump(&sg),
1002 buf2, input_iface_vif_index);
1003 }
1004
1005 if (input_iface_vif_index < 1) {
1006 if (PIM_DEBUG_IGMP_TRACE) {
1007 char source_str[INET_ADDRSTRLEN];
1008 pim_inet4_dump("<source?>", source->source_addr,
1009 source_str, sizeof(source_str));
1010 zlog_debug(
1011 "%s %s: could not find input interface for source %s",
1012 __FILE__, __PRETTY_FUNCTION__,
1013 source_str);
1014 }
1015 return;
1016 }
1017
1018 /*
1019 Protect IGMP against adding looped MFC entries created by both
1020 source and receiver attached to the same interface. See TODO
1021 T22.
1022 */
1023 pim_oif =
1024 source->source_group->group_igmp_sock->interface->info;
1025 if (!pim_oif) {
1026 if (PIM_DEBUG_IGMP_TRACE) {
1027 zlog_debug(
1028 "%s: multicast not enabled on oif=%s ?",
1029 __PRETTY_FUNCTION__,
1030 source->source_group->group_igmp_sock
1031 ->interface->name);
1032 }
1033 return;
1034 }
1035
1036 if (input_iface_vif_index == pim_oif->mroute_vif_index) {
1037 /* ignore request for looped MFC entry */
1038 if (PIM_DEBUG_IGMP_TRACE) {
1039 zlog_debug(
1040 "%s: ignoring request for looped MFC entry (S,G)=%s: igmp_sock=%d oif=%s vif_index=%d",
1041 __PRETTY_FUNCTION__,
1042 pim_str_sg_dump(&sg),
1043 source->source_group->group_igmp_sock
1044 ->fd,
1045 source->source_group->group_igmp_sock
1046 ->interface->name,
1047 input_iface_vif_index);
1048 }
1049 return;
1050 }
1051
1052 source->source_channel_oil =
6f932b0c 1053 pim_channel_oil_add(pim, &sg, input_iface_vif_index);
d62a17ae 1054 if (!source->source_channel_oil) {
1055 if (PIM_DEBUG_IGMP_TRACE) {
1056 zlog_debug(
1057 "%s %s: could not create OIL for channel (S,G)=%s",
1058 __FILE__, __PRETTY_FUNCTION__,
1059 pim_str_sg_dump(&sg));
1060 }
1061 return;
1062 }
8711a53d 1063 }
d62a17ae 1064
1065 result = pim_channel_add_oif(source->source_channel_oil,
1066 group->group_igmp_sock->interface,
1067 PIM_OIF_FLAG_PROTO_IGMP);
1068 if (result) {
1069 if (PIM_DEBUG_MROUTE) {
1070 zlog_warn("%s: add_oif() failed with return=%d",
1071 __func__, result);
1072 }
1073 return;
8711a53d 1074 }
d62a17ae 1075
1076 /*
1077 Feed IGMPv3-gathered local membership information into PIM
1078 per-interface (S,G) state.
1079 */
1080 if (!pim_ifchannel_local_membership_add(
1081 group->group_igmp_sock->interface, &sg)) {
1082 if (PIM_DEBUG_MROUTE)
1083 zlog_warn("%s: Failure to add local membership for %s",
1084 __PRETTY_FUNCTION__, pim_str_sg_dump(&sg));
1085 return;
1086 }
1087
1088 IGMP_SOURCE_DO_FORWARDING(source->source_flags);
12e41d03
DL
1089}
1090
1091/*
1092 igmp_source_forward_stop: stop fowarding, but keep the source
1093 igmp_source_delete: stop fowarding, and delete the source
1094 */
1095void igmp_source_forward_stop(struct igmp_source *source)
1096{
d62a17ae 1097 struct igmp_group *group;
1098 struct prefix_sg sg;
1099 int result;
1100
1101 memset(&sg, 0, sizeof(struct prefix_sg));
1102 sg.src = source->source_addr;
1103 sg.grp = source->source_group->group_addr;
1104
1105 if (PIM_DEBUG_IGMP_TRACE) {
1106 zlog_debug(
1107 "%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d",
1108 __PRETTY_FUNCTION__, pim_str_sg_dump(&sg),
1109 source->source_group->group_igmp_sock->fd,
1110 source->source_group->group_igmp_sock->interface->name,
1111 IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
1112 }
1113
1114 /* Prevent IGMP interface from removing multicast route multiple
1115 times */
1116 if (!IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
1117 return;
1118 }
1119
1120 group = source->source_group;
1121
1122 /*
1123 It appears that in certain circumstances that
1124 igmp_source_forward_stop is called when IGMP forwarding
1125 was not enabled in oif_flags for this outgoing interface.
1126 Possibly because of multiple calls. When that happens, we
1127 enter the below if statement and this function returns early
1128 which in turn triggers the calling function to assert.
1129 Making the call to pim_channel_del_oif and ignoring the return code
1130 fixes the issue without ill effect, similar to
1131 pim_forward_stop below.
1132 */
1133 result = pim_channel_del_oif(source->source_channel_oil,
1134 group->group_igmp_sock->interface,
1135 PIM_OIF_FLAG_PROTO_IGMP);
1136 if (result) {
1137 if (PIM_DEBUG_IGMP_TRACE)
1138 zlog_debug(
1139 "%s: pim_channel_del_oif() failed with return=%d",
1140 __func__, result);
1141 return;
1142 }
1143
1144 /*
1145 Feed IGMPv3-gathered local membership information into PIM
1146 per-interface (S,G) state.
1147 */
1148 pim_ifchannel_local_membership_del(group->group_igmp_sock->interface,
1149 &sg);
1150
1151 IGMP_SOURCE_DONT_FORWARDING(source->source_flags);
12e41d03
DL
1152}
1153
1154void pim_forward_start(struct pim_ifchannel *ch)
1155{
d62a17ae 1156 struct pim_upstream *up = ch->upstream;
1157 uint32_t mask = PIM_OIF_FLAG_PROTO_PIM;
1158 int input_iface_vif_index = 0;
6f932b0c
DS
1159 struct pim_instance *pim;
1160 struct pim_interface *pim_ifp;
1161
1162 pim_ifp = ch->interface->info;
1163 pim = pim_ifp->pim;
d62a17ae 1164
1165 if (PIM_DEBUG_PIM_TRACE) {
1166 char source_str[INET_ADDRSTRLEN];
1167 char group_str[INET_ADDRSTRLEN];
1168 char upstream_str[INET_ADDRSTRLEN];
1169
1170 pim_inet4_dump("<source?>", ch->sg.src, source_str,
1171 sizeof(source_str));
1172 pim_inet4_dump("<group?>", ch->sg.grp, group_str,
1173 sizeof(group_str));
1174 pim_inet4_dump("<upstream?>", up->upstream_addr, upstream_str,
1175 sizeof(upstream_str));
1176 zlog_debug("%s: (S,G)=(%s,%s) oif=%s (%s)", __PRETTY_FUNCTION__,
1177 source_str, group_str, ch->interface->name,
1178 upstream_str);
1179 }
1180
1181 /* Resolve IIF for upstream as mroute_del sets mfcc_parent to MAXVIFS,
1182 as part of mroute_del called by pim_forward_stop.
1183 */
1184 if (!up->channel_oil
1185 || (up->channel_oil
1186 && up->channel_oil->oil.mfcc_parent >= MAXVIFS)) {
1187 struct prefix nht_p, src, grp;
d62a17ae 1188 struct pim_nexthop_cache out_pnc;
1189
1190 /* Register addr with Zebra NHT */
1191 nht_p.family = AF_INET;
1192 nht_p.prefixlen = IPV4_MAX_BITLEN;
1193 nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr;
1194 grp.family = AF_INET;
1195 grp.prefixlen = IPV4_MAX_BITLEN;
1196 grp.u.prefix4 = up->sg.grp;
1197 memset(&out_pnc, 0, sizeof(struct pim_nexthop_cache));
1198
6f932b0c 1199 if (pim_find_or_track_nexthop(pim, &nht_p, NULL, NULL,
25bdac42 1200 &out_pnc)) {
d62a17ae 1201 if (out_pnc.nexthop_num) {
1202 src.family = AF_INET;
1203 src.prefixlen = IPV4_MAX_BITLEN;
1204 src.u.prefix4 =
1205 up->upstream_addr; // RP or Src address
1206 grp.family = AF_INET;
1207 grp.prefixlen = IPV4_MAX_BITLEN;
1208 grp.u.prefix4 = up->sg.grp;
1209 // Compute PIM RPF using Cached nexthop
1210 if (pim_ecmp_nexthop_search(
6f932b0c 1211 pim, &out_pnc,
25b787a2
DS
1212 &up->rpf.source_nexthop, &src, &grp,
1213 0))
d62a17ae 1214 input_iface_vif_index =
1215 pim_if_find_vifindex_by_ifindex(
6f932b0c 1216 pim,
d62a17ae 1217 up->rpf.source_nexthop
1218 .interface->ifindex);
1219 else {
1220 if (PIM_DEBUG_TRACE)
1221 zlog_debug(
1222 "%s: Nexthop selection failed for %s ",
1223 __PRETTY_FUNCTION__,
1224 up->sg_str);
1225 }
1226 } else {
1227 if (PIM_DEBUG_ZEBRA) {
1228 char buf1[INET_ADDRSTRLEN];
1229 char buf2[INET_ADDRSTRLEN];
1230 pim_inet4_dump("<source?>",
1231 nht_p.u.prefix4, buf1,
1232 sizeof(buf1));
1233 pim_inet4_dump("<source?>",
1234 grp.u.prefix4, buf2,
1235 sizeof(buf2));
1236 zlog_debug(
1237 "%s: NHT pnc is NULL for addr %s grp %s",
1238 __PRETTY_FUNCTION__, buf1,
1239 buf2);
1240 }
1241 }
1242 } else
1243 input_iface_vif_index =
1244 pim_ecmp_fib_lookup_if_vif_index(
6f932b0c 1245 pim, up->upstream_addr, &src, &grp);
d62a17ae 1246
1247 if (input_iface_vif_index < 1) {
1248 if (PIM_DEBUG_PIM_TRACE) {
1249 char source_str[INET_ADDRSTRLEN];
1250 pim_inet4_dump("<source?>", up->sg.src,
1251 source_str, sizeof(source_str));
1252 zlog_debug(
1253 "%s %s: could not find input interface for source %s",
1254 __FILE__, __PRETTY_FUNCTION__,
1255 source_str);
1256 }
1257 return;
1258 }
1259 if (PIM_DEBUG_TRACE) {
7cfc7bcf 1260 struct interface *in_intf = pim_if_find_by_vif_index(
6f932b0c 1261 pim, input_iface_vif_index);
d62a17ae 1262 zlog_debug(
1263 "%s: Update channel_oil IIF %s VIFI %d entry %s ",
1264 __PRETTY_FUNCTION__,
1265 in_intf ? in_intf->name : "NIL",
1266 input_iface_vif_index, up->sg_str);
1267 }
6f932b0c 1268 up->channel_oil = pim_channel_oil_add(pim, &up->sg,
611925dc 1269 input_iface_vif_index);
d62a17ae 1270 if (!up->channel_oil) {
1271 if (PIM_DEBUG_PIM_TRACE)
1272 zlog_debug(
1273 "%s %s: could not create OIL for channel (S,G)=%s",
1274 __FILE__, __PRETTY_FUNCTION__,
1275 up->sg_str);
1276 return;
1277 }
1278 }
1279
1280 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
1281 mask = PIM_OIF_FLAG_PROTO_IGMP;
1282
1283 pim_channel_add_oif(up->channel_oil, ch->interface, mask);
12e41d03
DL
1284}
1285
aabb9a2f 1286void pim_forward_stop(struct pim_ifchannel *ch, bool install_it)
12e41d03 1287{
d62a17ae 1288 struct pim_upstream *up = ch->upstream;
12e41d03 1289
d62a17ae 1290 if (PIM_DEBUG_PIM_TRACE) {
aabb9a2f
DS
1291 zlog_debug("%s: (S,G)=%s oif=%s install_it: %d installed: %d",
1292 __PRETTY_FUNCTION__, ch->sg_str, ch->interface->name,
1293 install_it, up->channel_oil->installed);
d62a17ae 1294 }
12e41d03 1295
d62a17ae 1296 pim_channel_del_oif(up->channel_oil, ch->interface,
1297 PIM_OIF_FLAG_PROTO_PIM);
aabb9a2f
DS
1298
1299 if (install_it && !up->channel_oil->installed)
1300 pim_mroute_add(up->channel_oil, __PRETTY_FUNCTION__);
12e41d03 1301}
8799b66b 1302
d62a17ae 1303void pim_zebra_zclient_update(struct vty *vty)
8799b66b 1304{
d62a17ae 1305 vty_out(vty, "Zclient update socket: ");
1306
1307 if (zclient) {
1308 vty_out(vty, "%d failures=%d\n", zclient->sock, zclient->fail);
1309 } else {
1310 vty_out(vty, "<null zclient>\n");
1311 }
8799b66b 1312}
1bc98276 1313
d62a17ae 1314struct zclient *pim_zebra_zclient_get(void)
1bc98276 1315{
d62a17ae 1316 if (zclient)
1317 return zclient;
1318 else
1319 return NULL;
1bc98276 1320}