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