]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_zebra.c
Merge pull request #5918 from ton31337/fix/__func__everywhere
[mirror_frr.git] / pimd / pim_zebra.c
1 /*
2 * PIM for Quagga
3 * Copyright (C) 2008 Everton da Silva Marques
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include <zebra.h>
21
22 #include "if.h"
23 #include "log.h"
24 #include "prefix.h"
25 #include "zclient.h"
26 #include "stream.h"
27 #include "network.h"
28 #include "vty.h"
29 #include "plist.h"
30 #include "lib/bfd.h"
31
32 #include "pimd.h"
33 #include "pim_pim.h"
34 #include "pim_zebra.h"
35 #include "pim_iface.h"
36 #include "pim_str.h"
37 #include "pim_oil.h"
38 #include "pim_rpf.h"
39 #include "pim_time.h"
40 #include "pim_join.h"
41 #include "pim_zlookup.h"
42 #include "pim_ifchannel.h"
43 #include "pim_rp.h"
44 #include "pim_igmpv3.h"
45 #include "pim_jp_agg.h"
46 #include "pim_nht.h"
47 #include "pim_ssm.h"
48 #include "pim_vxlan.h"
49 #include "pim_mlag.h"
50
51 #undef PIM_DEBUG_IFADDR_DUMP
52 #define PIM_DEBUG_IFADDR_DUMP
53
54 struct zclient *zclient;
55
56
57 /* Router-id update message from zebra. */
58 static int pim_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
59 {
60 struct prefix router_id;
61
62 zebra_router_id_update_read(zclient->ibuf, &router_id);
63
64 return 0;
65 }
66
67 static int pim_zebra_interface_vrf_update(ZAPI_CALLBACK_ARGS)
68 {
69 struct interface *ifp;
70 vrf_id_t new_vrf_id;
71
72 ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
73 &new_vrf_id);
74 if (!ifp)
75 return 0;
76
77 if (PIM_DEBUG_ZEBRA)
78 zlog_debug("%s: %s updating from %u to %u", __func__, ifp->name,
79 vrf_id, new_vrf_id);
80
81 if_update_to_new_vrf(ifp, new_vrf_id);
82
83 return 0;
84 }
85
86 #ifdef PIM_DEBUG_IFADDR_DUMP
87 static void dump_if_address(struct interface *ifp)
88 {
89 struct connected *ifc;
90 struct listnode *node;
91
92 zlog_debug("%s %s: interface %s addresses:", __FILE__,
93 __PRETTY_FUNCTION__, ifp->name);
94
95 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
96 struct prefix *p = ifc->address;
97
98 if (p->family != AF_INET)
99 continue;
100
101 zlog_debug("%s %s: interface %s address %s %s", __FILE__,
102 __PRETTY_FUNCTION__, ifp->name,
103 inet_ntoa(p->u.prefix4),
104 CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)
105 ? "secondary"
106 : "primary");
107 }
108 }
109 #endif
110
111 static int pim_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
112 {
113 struct connected *c;
114 struct prefix *p;
115 struct pim_interface *pim_ifp;
116 struct pim_instance *pim;
117
118 /*
119 zebra api notifies address adds/dels events by using the same call
120 interface_add_read below, see comments in lib/zclient.c
121
122 zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...)
123 will add address to interface list by calling
124 connected_add_by_prefix()
125 */
126 c = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
127 if (!c)
128 return 0;
129
130 pim_ifp = c->ifp->info;
131 p = c->address;
132
133 if (PIM_DEBUG_ZEBRA) {
134 char buf[BUFSIZ];
135 prefix2str(p, buf, BUFSIZ);
136 zlog_debug("%s: %s(%u) connected IP address %s flags %u %s",
137 __func__, c->ifp->name, vrf_id, buf, c->flags,
138 CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
139 ? "secondary"
140 : "primary");
141
142 #ifdef PIM_DEBUG_IFADDR_DUMP
143 dump_if_address(c->ifp);
144 #endif
145 }
146
147 if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) {
148 /* trying to add primary address */
149
150 struct in_addr primary_addr = pim_find_primary_addr(c->ifp);
151 if (p->family != AF_INET
152 || primary_addr.s_addr != p->u.prefix4.s_addr) {
153 if (PIM_DEBUG_ZEBRA) {
154 /* but we had a primary address already */
155
156 char buf[BUFSIZ];
157
158 prefix2str(p, buf, BUFSIZ);
159
160 zlog_warn(
161 "%s: %s : forcing secondary flag on %s",
162 __func__, c->ifp->name, buf);
163 }
164 SET_FLAG(c->flags, ZEBRA_IFA_SECONDARY);
165 }
166 }
167
168 pim_if_addr_add(c);
169 if (pim_ifp) {
170 pim = pim_get_pim_instance(vrf_id);
171 pim_ifp->pim = pim;
172
173 pim_rp_check_on_if_add(pim_ifp);
174 }
175
176 if (if_is_loopback(c->ifp)) {
177 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
178 struct interface *ifp;
179
180 FOR_ALL_INTERFACES (vrf, ifp) {
181 if (!if_is_loopback(ifp) && if_is_operative(ifp))
182 pim_if_addr_add_all(ifp);
183 }
184 }
185
186 return 0;
187 }
188
189 static int pim_zebra_if_address_del(ZAPI_CALLBACK_ARGS)
190 {
191 struct connected *c;
192 struct prefix *p;
193 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
194 struct pim_instance *pim;
195
196 if (!vrf)
197 return 0;
198 pim = vrf->info;
199
200 /*
201 zebra api notifies address adds/dels events by using the same call
202 interface_add_read below, see comments in lib/zclient.c
203
204 zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...)
205 will remove address from interface list by calling
206 connected_delete_by_prefix()
207 */
208 c = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
209 if (!c)
210 return 0;
211
212 p = c->address;
213 if (p->family == AF_INET) {
214 if (PIM_DEBUG_ZEBRA) {
215 char buf[BUFSIZ];
216 prefix2str(p, buf, BUFSIZ);
217 zlog_debug(
218 "%s: %s(%u) disconnected IP address %s flags %u %s",
219 __func__, c->ifp->name, vrf_id, buf, c->flags,
220 CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
221 ? "secondary"
222 : "primary");
223
224 #ifdef PIM_DEBUG_IFADDR_DUMP
225 dump_if_address(c->ifp);
226 #endif
227 }
228
229 pim_if_addr_del(c, 0);
230 pim_rp_setup(pim);
231 pim_i_am_rp_re_evaluate(pim);
232 }
233
234 connected_free(&c);
235 return 0;
236 }
237
238 void pim_zebra_update_all_interfaces(struct pim_instance *pim)
239 {
240 struct interface *ifp;
241
242 FOR_ALL_INTERFACES (pim->vrf, ifp) {
243 struct pim_interface *pim_ifp = ifp->info;
244 struct pim_iface_upstream_switch *us;
245 struct listnode *node;
246
247 if (!pim_ifp)
248 continue;
249
250 for (ALL_LIST_ELEMENTS_RO(pim_ifp->upstream_switch_list, node,
251 us)) {
252 struct pim_rpf rpf;
253
254 rpf.source_nexthop.interface = ifp;
255 rpf.rpf_addr.u.prefix4 = us->address;
256 pim_joinprune_send(&rpf, us->us);
257 pim_jp_agg_clear_group(us->us);
258 }
259 }
260 }
261
262 void pim_zebra_upstream_rpf_changed(struct pim_instance *pim,
263 struct pim_upstream *up,
264 struct pim_rpf *old)
265 {
266 if (old->source_nexthop.interface) {
267 struct pim_neighbor *nbr;
268
269 nbr = pim_neighbor_find(old->source_nexthop.interface,
270 old->rpf_addr.u.prefix4);
271 if (nbr)
272 pim_jp_agg_remove_group(nbr->upstream_jp_agg, up, nbr);
273
274 /*
275 * We have detected a case where we might need
276 * to rescan the inherited o_list so do it.
277 */
278 if (up->channel_oil->oil_inherited_rescan) {
279 pim_upstream_inherited_olist_decide(pim, up);
280 up->channel_oil->oil_inherited_rescan = 0;
281 }
282
283 if (up->join_state == PIM_UPSTREAM_JOINED) {
284 /*
285 * If we come up real fast we can be here
286 * where the mroute has not been installed
287 * so install it.
288 */
289 if (!up->channel_oil->installed)
290 pim_upstream_mroute_add(up->channel_oil,
291 __func__);
292
293 /*
294 * RFC 4601: 4.5.7. Sending (S,G)
295 * Join/Prune Messages
296 *
297 * Transitions from Joined State
298 *
299 * RPF'(S,G) changes not due to an Assert
300 *
301 * The upstream (S,G) state machine remains
302 * in Joined state. Send Join(S,G) to the new
303 * upstream neighbor, which is the new value
304 * of RPF'(S,G). Send Prune(S,G) to the old
305 * upstream neighbor, which is the old value
306 * of RPF'(S,G). Set the Join Timer (JT) to
307 * expire after t_periodic seconds.
308 */
309 pim_jp_agg_switch_interface(old, &up->rpf, up);
310
311 pim_upstream_join_timer_restart(up, old);
312 } /* up->join_state == PIM_UPSTREAM_JOINED */
313 }
314
315 else {
316 /*
317 * We have detected a case where we might need
318 * to rescan the inherited o_list so do it.
319 */
320 if (up->channel_oil->oil_inherited_rescan) {
321 pim_upstream_inherited_olist_decide(pim, up);
322 up->channel_oil->oil_inherited_rescan = 0;
323 }
324
325 if (up->join_state == PIM_UPSTREAM_JOINED)
326 pim_jp_agg_switch_interface(old, &up->rpf, up);
327
328 if (!up->channel_oil->installed)
329 pim_upstream_mroute_add(up->channel_oil, __func__);
330 }
331
332 /* FIXME can join_desired actually be changed by pim_rpf_update()
333 * returning PIM_RPF_CHANGED ?
334 */
335 pim_upstream_update_join_desired(pim, up);
336 }
337
338 static int pim_zebra_vxlan_sg_proc(ZAPI_CALLBACK_ARGS)
339 {
340 struct stream *s;
341 struct pim_instance *pim;
342 struct prefix_sg sg;
343
344 pim = pim_get_pim_instance(vrf_id);
345 if (!pim)
346 return 0;
347
348 s = zclient->ibuf;
349
350 sg.family = AF_INET;
351 sg.prefixlen = stream_getl(s);
352 stream_get(&sg.src.s_addr, s, sg.prefixlen);
353 stream_get(&sg.grp.s_addr, s, sg.prefixlen);
354
355 if (PIM_DEBUG_ZEBRA) {
356 char sg_str[PIM_SG_LEN];
357
358 pim_str_sg_set(&sg, sg_str);
359 zlog_debug("%u:recv SG %s %s", vrf_id,
360 (cmd == ZEBRA_VXLAN_SG_ADD)?"add":"del",
361 sg_str);
362 }
363
364 if (cmd == ZEBRA_VXLAN_SG_ADD)
365 pim_vxlan_sg_add(pim, &sg);
366 else
367 pim_vxlan_sg_del(pim, &sg);
368
369 return 0;
370 }
371
372 static void pim_zebra_vxlan_replay(void)
373 {
374 struct stream *s = NULL;
375
376 /* Check socket. */
377 if (!zclient || zclient->sock < 0)
378 return;
379
380 s = zclient->obuf;
381 stream_reset(s);
382
383 zclient_create_header(s, ZEBRA_VXLAN_SG_REPLAY, VRF_DEFAULT);
384 stream_putw_at(s, 0, stream_get_endp(s));
385
386 zclient_send_message(zclient);
387 }
388
389 void pim_scan_oil(struct pim_instance *pim)
390 {
391 struct channel_oil *c_oil;
392
393 pim->scan_oil_last = pim_time_monotonic_sec();
394 ++pim->scan_oil_events;
395
396 frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil)
397 pim_upstream_mroute_iif_update(c_oil, __func__);
398 }
399
400 static int on_rpf_cache_refresh(struct thread *t)
401 {
402 struct pim_instance *pim = THREAD_ARG(t);
403
404 /* update kernel multicast forwarding cache (MFC) */
405 pim_scan_oil(pim);
406
407 pim->rpf_cache_refresh_last = pim_time_monotonic_sec();
408 ++pim->rpf_cache_refresh_events;
409
410 // It is called as part of pim_neighbor_add
411 // pim_rp_setup ();
412 return 0;
413 }
414
415 void sched_rpf_cache_refresh(struct pim_instance *pim)
416 {
417 ++pim->rpf_cache_refresh_requests;
418
419 pim_rpf_set_refresh_time(pim);
420
421 if (pim->rpf_cache_refresher) {
422 /* Refresh timer is already running */
423 return;
424 }
425
426 /* Start refresh timer */
427
428 if (PIM_DEBUG_ZEBRA) {
429 zlog_debug("%s: triggering %ld msec timer", __func__,
430 router->rpf_cache_refresh_delay_msec);
431 }
432
433 thread_add_timer_msec(router->master, on_rpf_cache_refresh, pim,
434 router->rpf_cache_refresh_delay_msec,
435 &pim->rpf_cache_refresher);
436 }
437
438 static void pim_zebra_connected(struct zclient *zclient)
439 {
440 /* Send the client registration */
441 bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER, router->vrf_id);
442
443 zclient_send_reg_requests(zclient, router->vrf_id);
444
445 /* request for VxLAN BUM group addresses */
446 pim_zebra_vxlan_replay();
447 }
448
449 static void pim_zebra_capabilities(struct zclient_capabilities *cap)
450 {
451 router->mlag_role = cap->role;
452 }
453
454 void pim_zebra_init(void)
455 {
456 /* Socket for receiving updates from Zebra daemon */
457 zclient = zclient_new(router->master, &zclient_options_default);
458
459 zclient->zebra_capabilities = pim_zebra_capabilities;
460 zclient->zebra_connected = pim_zebra_connected;
461 zclient->router_id_update = pim_router_id_update_zebra;
462 zclient->interface_address_add = pim_zebra_if_address_add;
463 zclient->interface_address_delete = pim_zebra_if_address_del;
464 zclient->interface_vrf_update = pim_zebra_interface_vrf_update;
465 zclient->nexthop_update = pim_parse_nexthop_update;
466 zclient->vxlan_sg_add = pim_zebra_vxlan_sg_proc;
467 zclient->vxlan_sg_del = pim_zebra_vxlan_sg_proc;
468 zclient->mlag_process_up = pim_zebra_mlag_process_up;
469 zclient->mlag_process_down = pim_zebra_mlag_process_down;
470 zclient->mlag_handle_msg = pim_zebra_mlag_handle_msg;
471
472 zclient_init(zclient, ZEBRA_ROUTE_PIM, 0, &pimd_privs);
473 if (PIM_DEBUG_PIM_TRACE) {
474 zlog_notice("%s: zclient socket initialized", __func__);
475 }
476
477 zclient_lookup_new();
478 }
479
480 void igmp_anysource_forward_start(struct pim_instance *pim,
481 struct igmp_group *group)
482 {
483 struct igmp_source *source;
484 struct in_addr src_addr = {.s_addr = 0};
485 /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */
486 zassert(group->group_filtermode_isexcl);
487 zassert(listcount(group->group_source_list) < 1);
488
489 source = source_new(group, src_addr);
490 if (!source) {
491 zlog_warn("%s: Failure to create * source", __func__);
492 return;
493 }
494
495 igmp_source_forward_start(pim, source);
496 }
497
498 void igmp_anysource_forward_stop(struct igmp_group *group)
499 {
500 struct igmp_source *source;
501 struct in_addr star = {.s_addr = 0};
502
503 source = igmp_find_source_by_addr(group, star);
504 if (source)
505 igmp_source_forward_stop(source);
506 }
507
508 static void igmp_source_forward_reevaluate_one(struct pim_instance *pim,
509 struct igmp_source *source)
510 {
511 struct prefix_sg sg;
512 struct igmp_group *group = source->source_group;
513 struct pim_ifchannel *ch;
514
515 if ((source->source_addr.s_addr != INADDR_ANY)
516 || !IGMP_SOURCE_TEST_FORWARDING(source->source_flags))
517 return;
518
519 memset(&sg, 0, sizeof(struct prefix_sg));
520 sg.src = source->source_addr;
521 sg.grp = group->group_addr;
522
523 ch = pim_ifchannel_find(group->group_igmp_sock->interface, &sg);
524 if (pim_is_grp_ssm(pim, group->group_addr)) {
525 /* If SSM group withdraw local membership */
526 if (ch
527 && (ch->local_ifmembership == PIM_IFMEMBERSHIP_INCLUDE)) {
528 if (PIM_DEBUG_PIM_EVENTS)
529 zlog_debug(
530 "local membership del for %s as G is now SSM",
531 pim_str_sg_dump(&sg));
532 pim_ifchannel_local_membership_del(
533 group->group_igmp_sock->interface, &sg);
534 }
535 } else {
536 /* If ASM group add local membership */
537 if (!ch
538 || (ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO)) {
539 if (PIM_DEBUG_PIM_EVENTS)
540 zlog_debug(
541 "local membership add for %s as G is now ASM",
542 pim_str_sg_dump(&sg));
543 pim_ifchannel_local_membership_add(
544 group->group_igmp_sock->interface, &sg,
545 false /*is_vxlan*/);
546 }
547 }
548 }
549
550 void igmp_source_forward_reevaluate_all(struct pim_instance *pim)
551 {
552 struct interface *ifp;
553
554 FOR_ALL_INTERFACES (pim->vrf, ifp) {
555 struct pim_interface *pim_ifp = ifp->info;
556 struct listnode *sock_node;
557 struct igmp_sock *igmp;
558
559 if (!pim_ifp)
560 continue;
561
562 /* scan igmp sockets */
563 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
564 igmp)) {
565 struct listnode *grpnode;
566 struct igmp_group *grp;
567
568 /* scan igmp groups */
569 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
570 grpnode, grp)) {
571 struct listnode *srcnode;
572 struct igmp_source *src;
573
574 /* scan group sources */
575 for (ALL_LIST_ELEMENTS_RO(
576 grp->group_source_list, srcnode,
577 src)) {
578 igmp_source_forward_reevaluate_one(pim,
579 src);
580 } /* scan group sources */
581 } /* scan igmp groups */
582 } /* scan igmp sockets */
583 } /* scan interfaces */
584 }
585
586 void igmp_source_forward_start(struct pim_instance *pim,
587 struct igmp_source *source)
588 {
589 struct pim_interface *pim_oif;
590 struct igmp_group *group;
591 struct prefix_sg sg;
592 int result;
593 int input_iface_vif_index = 0;
594
595 memset(&sg, 0, sizeof(struct prefix_sg));
596 sg.src = source->source_addr;
597 sg.grp = source->source_group->group_addr;
598
599 if (PIM_DEBUG_IGMP_TRACE) {
600 zlog_debug(
601 "%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d", __func__,
602 pim_str_sg_dump(&sg),
603 source->source_group->group_igmp_sock->fd,
604 source->source_group->group_igmp_sock->interface->name,
605 IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
606 }
607
608 /* Prevent IGMP interface from installing multicast route multiple
609 times */
610 if (IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
611 return;
612 }
613
614 group = source->source_group;
615 pim_oif = group->group_igmp_sock->interface->info;
616 if (!pim_oif) {
617 if (PIM_DEBUG_IGMP_TRACE) {
618 zlog_debug("%s: multicast not enabled on oif=%s ?",
619 __func__,
620 source->source_group->group_igmp_sock
621 ->interface->name);
622 }
623 return;
624 }
625
626 if (!source->source_channel_oil) {
627 struct in_addr vif_source;
628 struct prefix src, grp;
629 struct pim_nexthop nexthop;
630 struct pim_upstream *up = NULL;
631
632 if (!pim_rp_set_upstream_addr(pim, &vif_source,
633 source->source_addr, sg.grp)) {
634 /*Create a dummy channel oil */
635 source->source_channel_oil =
636 pim_channel_oil_add(pim, &sg, __func__);
637 }
638
639 else {
640 src.family = AF_INET;
641 src.prefixlen = IPV4_MAX_BITLEN;
642 src.u.prefix4 = vif_source; // RP or Src address
643 grp.family = AF_INET;
644 grp.prefixlen = IPV4_MAX_BITLEN;
645 grp.u.prefix4 = sg.grp;
646
647 up = pim_upstream_find(pim, &sg);
648 if (up) {
649 memcpy(&nexthop, &up->rpf.source_nexthop,
650 sizeof(struct pim_nexthop));
651 pim_ecmp_nexthop_lookup(pim, &nexthop, &src,
652 &grp, 0);
653 if (nexthop.interface)
654 input_iface_vif_index =
655 pim_if_find_vifindex_by_ifindex(
656 pim,
657 nexthop.interface->ifindex);
658 } else
659 input_iface_vif_index =
660 pim_ecmp_fib_lookup_if_vif_index(
661 pim, &src, &grp);
662
663 if (PIM_DEBUG_ZEBRA) {
664 char buf2[INET_ADDRSTRLEN];
665
666 pim_inet4_dump("<source?>", vif_source, buf2,
667 sizeof(buf2));
668 zlog_debug(
669 "%s: NHT %s vif_source %s vif_index:%d ",
670 __func__, pim_str_sg_dump(&sg), buf2,
671 input_iface_vif_index);
672 }
673
674 if (input_iface_vif_index < 1) {
675 if (PIM_DEBUG_IGMP_TRACE) {
676 char source_str[INET_ADDRSTRLEN];
677 pim_inet4_dump("<source?>",
678 source->source_addr,
679 source_str, sizeof(source_str));
680 zlog_debug(
681 "%s %s: could not find input interface for source %s",
682 __FILE__, __func__, source_str);
683 }
684 source->source_channel_oil =
685 pim_channel_oil_add(pim, &sg, __func__);
686 }
687
688 else {
689 /*
690 * Protect IGMP against adding looped MFC
691 * entries created by both source and receiver
692 * attached to the same interface. See TODO
693 * T22. Block only when the intf is non DR
694 * DR must create upstream.
695 */
696 if ((input_iface_vif_index ==
697 pim_oif->mroute_vif_index) &&
698 !(PIM_I_am_DR(pim_oif))) {
699 /* ignore request for looped MFC entry
700 */
701 if (PIM_DEBUG_IGMP_TRACE) {
702 zlog_debug(
703 "%s: ignoring request for looped MFC entry (S,G)=%s: igmp_sock=%d oif=%s vif_index=%d",
704 __func__,
705 pim_str_sg_dump(&sg),
706 source->source_group
707 ->group_igmp_sock
708 ->fd,
709 source->source_group
710 ->group_igmp_sock
711 ->interface->name,
712 input_iface_vif_index);
713 }
714 return;
715 }
716
717 source->source_channel_oil =
718 pim_channel_oil_add(pim, &sg, __func__);
719 if (!source->source_channel_oil) {
720 if (PIM_DEBUG_IGMP_TRACE) {
721 zlog_debug(
722 "%s %s: could not create OIL for channel (S,G)=%s",
723 __FILE__, __func__,
724 pim_str_sg_dump(&sg));
725 }
726 return;
727 }
728 }
729 }
730 }
731
732 if (PIM_I_am_DR(pim_oif)) {
733 result = pim_channel_add_oif(source->source_channel_oil,
734 group->group_igmp_sock->interface,
735 PIM_OIF_FLAG_PROTO_IGMP, __func__);
736 if (result) {
737 if (PIM_DEBUG_MROUTE) {
738 zlog_warn("%s: add_oif() failed with return=%d",
739 __func__, result);
740 }
741 return;
742 }
743 } else {
744 if (PIM_DEBUG_IGMP_TRACE)
745 zlog_debug(
746 "%s: %s was received on %s interface but we are not DR for that interface",
747 __func__, pim_str_sg_dump(&sg),
748 group->group_igmp_sock->interface->name);
749
750 return;
751 }
752 /*
753 Feed IGMPv3-gathered local membership information into PIM
754 per-interface (S,G) state.
755 */
756 if (!pim_ifchannel_local_membership_add(
757 group->group_igmp_sock->interface, &sg,
758 false /*is_vxlan*/)) {
759 if (PIM_DEBUG_MROUTE)
760 zlog_warn("%s: Failure to add local membership for %s",
761 __func__, pim_str_sg_dump(&sg));
762
763 pim_channel_del_oif(source->source_channel_oil,
764 group->group_igmp_sock->interface,
765 PIM_OIF_FLAG_PROTO_IGMP, __func__);
766 return;
767 }
768
769 IGMP_SOURCE_DO_FORWARDING(source->source_flags);
770 }
771
772 /*
773 igmp_source_forward_stop: stop fowarding, but keep the source
774 igmp_source_delete: stop fowarding, and delete the source
775 */
776 void igmp_source_forward_stop(struct igmp_source *source)
777 {
778 struct igmp_group *group;
779 struct prefix_sg sg;
780 int result;
781
782 memset(&sg, 0, sizeof(struct prefix_sg));
783 sg.src = source->source_addr;
784 sg.grp = source->source_group->group_addr;
785
786 if (PIM_DEBUG_IGMP_TRACE) {
787 zlog_debug(
788 "%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d", __func__,
789 pim_str_sg_dump(&sg),
790 source->source_group->group_igmp_sock->fd,
791 source->source_group->group_igmp_sock->interface->name,
792 IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
793 }
794
795 /* Prevent IGMP interface from removing multicast route multiple
796 times */
797 if (!IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
798 return;
799 }
800
801 group = source->source_group;
802
803 /*
804 It appears that in certain circumstances that
805 igmp_source_forward_stop is called when IGMP forwarding
806 was not enabled in oif_flags for this outgoing interface.
807 Possibly because of multiple calls. When that happens, we
808 enter the below if statement and this function returns early
809 which in turn triggers the calling function to assert.
810 Making the call to pim_channel_del_oif and ignoring the return code
811 fixes the issue without ill effect, similar to
812 pim_forward_stop below.
813 */
814 result = pim_channel_del_oif(source->source_channel_oil,
815 group->group_igmp_sock->interface,
816 PIM_OIF_FLAG_PROTO_IGMP,
817 __func__);
818 if (result) {
819 if (PIM_DEBUG_IGMP_TRACE)
820 zlog_debug(
821 "%s: pim_channel_del_oif() failed with return=%d",
822 __func__, result);
823 return;
824 }
825
826 /*
827 Feed IGMPv3-gathered local membership information into PIM
828 per-interface (S,G) state.
829 */
830 pim_ifchannel_local_membership_del(group->group_igmp_sock->interface,
831 &sg);
832
833 IGMP_SOURCE_DONT_FORWARDING(source->source_flags);
834 }
835
836 void pim_forward_start(struct pim_ifchannel *ch)
837 {
838 struct pim_upstream *up = ch->upstream;
839 uint32_t mask = PIM_OIF_FLAG_PROTO_PIM;
840
841 if (PIM_DEBUG_PIM_TRACE) {
842 char source_str[INET_ADDRSTRLEN];
843 char group_str[INET_ADDRSTRLEN];
844 char upstream_str[INET_ADDRSTRLEN];
845
846 pim_inet4_dump("<source?>", ch->sg.src, source_str,
847 sizeof(source_str));
848 pim_inet4_dump("<group?>", ch->sg.grp, group_str,
849 sizeof(group_str));
850 pim_inet4_dump("<upstream?>", up->upstream_addr, upstream_str,
851 sizeof(upstream_str));
852 zlog_debug("%s: (S,G)=(%s,%s) oif=%s (%s)", __func__,
853 source_str, group_str, ch->interface->name,
854 inet_ntoa(up->upstream_addr));
855 }
856
857 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
858 mask = PIM_OIF_FLAG_PROTO_IGMP;
859
860 pim_channel_add_oif(up->channel_oil, ch->interface,
861 mask, __func__);
862 }
863
864 void pim_forward_stop(struct pim_ifchannel *ch, bool install_it)
865 {
866 struct pim_upstream *up = ch->upstream;
867
868 if (PIM_DEBUG_PIM_TRACE) {
869 zlog_debug("%s: (S,G)=%s oif=%s install_it: %d installed: %d",
870 __func__, ch->sg_str, ch->interface->name,
871 install_it, up->channel_oil->installed);
872 }
873
874 /*
875 * If a channel is being removed, check to see if we still need
876 * to inherit the interface. If so make sure it is added in
877 */
878 if (pim_upstream_evaluate_join_desired_interface(up, ch, ch->parent))
879 pim_channel_add_oif(up->channel_oil, ch->interface,
880 PIM_OIF_FLAG_PROTO_PIM, __func__);
881 else
882 pim_channel_del_oif(up->channel_oil, ch->interface,
883 PIM_OIF_FLAG_PROTO_PIM, __func__);
884
885 if (install_it && !up->channel_oil->installed)
886 pim_upstream_mroute_add(up->channel_oil, __func__);
887 }
888
889 void pim_zebra_zclient_update(struct vty *vty)
890 {
891 vty_out(vty, "Zclient update socket: ");
892
893 if (zclient) {
894 vty_out(vty, "%d failures=%d\n", zclient->sock, zclient->fail);
895 } else {
896 vty_out(vty, "<null zclient>\n");
897 }
898 }
899
900 struct zclient *pim_zebra_zclient_get(void)
901 {
902 if (zclient)
903 return zclient;
904 else
905 return NULL;
906 }
907
908 void pim_zebra_interface_set_master(struct interface *vrf,
909 struct interface *ifp)
910 {
911 zclient_interface_set_master(zclient, vrf, ifp);
912 }