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