]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_zebra.c
Merge branch 'master' into pim_5549
[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
16 along with this program; see the file COPYING; if not, write to the
17 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
18 MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "zebra/rib.h"
24
25 #include "if.h"
26 #include "log.h"
27 #include "prefix.h"
28 #include "zclient.h"
29 #include "stream.h"
30 #include "network.h"
31 #include "vty.h"
32 #include "plist.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 static int fib_lookup_if_vif_index(struct in_addr addr);
57
58 /* Router-id update message from zebra. */
59 static int pim_router_id_update_zebra(int command, struct zclient *zclient,
60 zebra_size_t length, vrf_id_t vrf_id)
61 {
62 struct prefix router_id;
63
64 zebra_router_id_update_read(zclient->ibuf, &router_id);
65
66 return 0;
67 }
68
69 static int pim_zebra_if_add(int command, struct zclient *zclient,
70 zebra_size_t length, vrf_id_t vrf_id)
71 {
72 struct interface *ifp;
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 if (PIM_DEBUG_ZEBRA) {
83 zlog_debug("%s: %s index %d flags %ld metric %d mtu %d operative %d",
84 __PRETTY_FUNCTION__,
85 ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric,
86 ifp->mtu, if_is_operative(ifp));
87 }
88
89 if (if_is_operative(ifp))
90 pim_if_addr_add_all(ifp);
91
92 return 0;
93 }
94
95 static int pim_zebra_if_del(int command, struct zclient *zclient,
96 zebra_size_t length, vrf_id_t vrf_id)
97 {
98 struct interface *ifp;
99
100 /*
101 zebra api adds/dels interfaces using the same call
102 interface_add_read below, see comments in lib/zclient.c
103
104 comments in lib/zclient.c seem to indicate that calling
105 zebra_interface_add_read is the correct call, but that
106 results in an attemted out of bounds read which causes
107 pimd to assert. Other clients use zebra_interface_state_read
108 and it appears to work just fine.
109 */
110 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
111 if (!ifp)
112 return 0;
113
114 if (PIM_DEBUG_ZEBRA) {
115 zlog_debug("%s: %s index %d flags %ld metric %d mtu %d operative %d",
116 __PRETTY_FUNCTION__,
117 ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric,
118 ifp->mtu, if_is_operative(ifp));
119 }
120
121 if (!if_is_operative(ifp))
122 pim_if_addr_del_all(ifp);
123
124 return 0;
125 }
126
127 static int pim_zebra_if_state_up(int command, struct zclient *zclient,
128 zebra_size_t length, vrf_id_t vrf_id)
129 {
130 struct interface *ifp;
131
132 /*
133 zebra api notifies interface up/down events by using the same call
134 zebra_interface_state_read below, see comments in lib/zclient.c
135 */
136 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
137 if (!ifp)
138 return 0;
139
140 if (PIM_DEBUG_ZEBRA) {
141 zlog_debug("%s: %s index %d flags %ld metric %d mtu %d operative %d",
142 __PRETTY_FUNCTION__,
143 ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric,
144 ifp->mtu, if_is_operative(ifp));
145 }
146
147 if (if_is_operative(ifp)) {
148 /*
149 pim_if_addr_add_all() suffices for bringing up both IGMP and PIM
150 */
151 pim_if_addr_add_all(ifp);
152 }
153
154 return 0;
155 }
156
157 static int pim_zebra_if_state_down(int command, struct zclient *zclient,
158 zebra_size_t length, vrf_id_t vrf_id)
159 {
160 struct interface *ifp;
161
162 /*
163 zebra api notifies interface up/down events by using the same call
164 zebra_interface_state_read below, see comments in lib/zclient.c
165 */
166 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
167 if (!ifp)
168 return 0;
169
170 if (PIM_DEBUG_ZEBRA) {
171 zlog_debug("%s: %s index %d flags %ld metric %d mtu %d operative %d",
172 __PRETTY_FUNCTION__,
173 ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric,
174 ifp->mtu, if_is_operative(ifp));
175 }
176
177 if (!if_is_operative(ifp)) {
178 pim_ifchannel_delete_all(ifp);
179 /*
180 pim_if_addr_del_all() suffices for shutting down IGMP,
181 but not for shutting down PIM
182 */
183 pim_if_addr_del_all(ifp);
184
185 /*
186 pim_sock_delete() closes the socket, stops read and timer threads,
187 and kills all neighbors.
188 */
189 if (ifp->info) {
190 pim_sock_delete(ifp, "link down");
191 }
192 }
193
194 if (ifp->info)
195 pim_if_del_vif(ifp);
196
197 return 0;
198 }
199
200 #ifdef PIM_DEBUG_IFADDR_DUMP
201 static void dump_if_address(struct interface *ifp)
202 {
203 struct connected *ifc;
204 struct listnode *node;
205
206 zlog_debug("%s %s: interface %s addresses:",
207 __FILE__, __PRETTY_FUNCTION__,
208 ifp->name);
209
210 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
211 struct prefix *p = ifc->address;
212
213 if (p->family != AF_INET)
214 continue;
215
216 zlog_debug("%s %s: interface %s address %s %s",
217 __FILE__, __PRETTY_FUNCTION__,
218 ifp->name,
219 inet_ntoa(p->u.prefix4),
220 CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ?
221 "secondary" : "primary");
222 }
223 }
224 #endif
225
226 static int pim_zebra_if_address_add(int command, struct zclient *zclient,
227 zebra_size_t length, vrf_id_t vrf_id)
228 {
229 struct connected *c;
230 struct prefix *p;
231 struct pim_interface *pim_ifp;
232
233 /*
234 zebra api notifies address adds/dels events by using the same call
235 interface_add_read below, see comments in lib/zclient.c
236
237 zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...)
238 will add address to interface list by calling
239 connected_add_by_prefix()
240 */
241 c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
242 if (!c)
243 return 0;
244
245 pim_ifp = c->ifp->info;
246 p = c->address;
247
248 if (PIM_DEBUG_ZEBRA) {
249 char buf[BUFSIZ];
250 prefix2str(p, buf, BUFSIZ);
251 zlog_debug("%s: %s connected IP address %s flags %u %s",
252 __PRETTY_FUNCTION__,
253 c->ifp->name, buf, c->flags,
254 CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary");
255
256 #ifdef PIM_DEBUG_IFADDR_DUMP
257 dump_if_address(c->ifp);
258 #endif
259 }
260
261 if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) {
262 /* trying to add primary address */
263
264 struct in_addr primary_addr = pim_find_primary_addr(c->ifp);
265 if (p->family != AF_INET || primary_addr.s_addr != p->u.prefix4.s_addr) {
266 if (PIM_DEBUG_ZEBRA) {
267 /* but we had a primary address already */
268
269 char buf[BUFSIZ];
270
271 prefix2str(p, buf, BUFSIZ);
272
273 zlog_warn("%s: %s : forcing secondary flag on %s",
274 __PRETTY_FUNCTION__,
275 c->ifp->name, buf);
276 }
277 SET_FLAG(c->flags, ZEBRA_IFA_SECONDARY);
278 }
279 }
280
281 pim_if_addr_add(c);
282 if (pim_ifp)
283 pim_rp_check_on_if_add(pim_ifp);
284
285 if (if_is_loopback (c->ifp))
286 {
287 struct listnode *ifnode;
288 struct interface *ifp;
289
290 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp))
291 {
292 if (!if_is_loopback (ifp) && if_is_operative (ifp))
293 pim_if_addr_add_all (ifp);
294 }
295 }
296
297 return 0;
298 }
299
300 static int pim_zebra_if_address_del(int command, struct zclient *client,
301 zebra_size_t length, vrf_id_t vrf_id)
302 {
303 struct connected *c;
304 struct prefix *p;
305
306 /*
307 zebra api notifies address adds/dels events by using the same call
308 interface_add_read below, see comments in lib/zclient.c
309
310 zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...)
311 will remove address from interface list by calling
312 connected_delete_by_prefix()
313 */
314 c = zebra_interface_address_read(command, client->ibuf, vrf_id);
315 if (!c)
316 return 0;
317
318 p = c->address;
319 if (p->family == AF_INET)
320 {
321 if (PIM_DEBUG_ZEBRA) {
322 char buf[BUFSIZ];
323 prefix2str(p, buf, BUFSIZ);
324 zlog_debug("%s: %s disconnected IP address %s flags %u %s",
325 __PRETTY_FUNCTION__,
326 c->ifp->name, buf, c->flags,
327 CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary");
328
329 #ifdef PIM_DEBUG_IFADDR_DUMP
330 dump_if_address(c->ifp);
331 #endif
332 }
333
334 pim_if_addr_del(c, 0);
335 pim_rp_setup();
336 pim_i_am_rp_re_evaluate();
337 }
338
339 connected_free (c);
340 return 0;
341 }
342
343 static void scan_upstream_rpf_cache()
344 {
345 struct listnode *up_node;
346 struct listnode *ifnode;
347 struct listnode *up_nextnode;
348 struct listnode *node;
349 struct pim_upstream *up;
350 struct interface *ifp;
351
352 for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up)) {
353 enum pim_rpf_result rpf_result;
354 struct pim_rpf old;
355
356 old.source_nexthop.interface = up->rpf.source_nexthop.interface;
357 old.source_nexthop.nbr = up->rpf.source_nexthop.nbr;
358 rpf_result = pim_rpf_update(up, &old, 0);
359
360 if (rpf_result == PIM_RPF_FAILURE)
361 continue;
362
363 if (rpf_result == PIM_RPF_CHANGED) {
364 struct pim_neighbor *nbr;
365
366 nbr = pim_neighbor_find (old.source_nexthop.interface,
367 old.rpf_addr.u.prefix4);
368 if (nbr)
369 pim_jp_agg_remove_group (nbr->upstream_jp_agg, up);
370
371 /*
372 * We have detected a case where we might need to rescan
373 * the inherited o_list so do it.
374 */
375 if (up->channel_oil->oil_inherited_rescan)
376 {
377 pim_upstream_inherited_olist_decide (up);
378 up->channel_oil->oil_inherited_rescan = 0;
379 }
380
381 if (up->join_state == PIM_UPSTREAM_JOINED) {
382 /*
383 * If we come up real fast we can be here
384 * where the mroute has not been installed
385 * so install it.
386 */
387 if (!up->channel_oil->installed)
388 pim_mroute_add (up->channel_oil, __PRETTY_FUNCTION__);
389
390 /*
391 * RFC 4601: 4.5.7. Sending (S,G) Join/Prune Messages
392 *
393 * Transitions from Joined State
394 *
395 * RPF'(S,G) changes not due to an Assert
396 *
397 * The upstream (S,G) state machine remains in Joined
398 * state. Send Join(S,G) to the new upstream neighbor, which is
399 * the new value of RPF'(S,G). Send Prune(S,G) to the old
400 * upstream neighbor, which is the old value of RPF'(S,G). Set
401 * the Join Timer (JT) to expire after t_periodic seconds.
402 */
403 pim_jp_agg_switch_interface (&old, &up->rpf, up);
404
405 pim_upstream_join_timer_restart(up, &old);
406 } /* up->join_state == PIM_UPSTREAM_JOINED */
407
408 /* FIXME can join_desired actually be changed by pim_rpf_update()
409 returning PIM_RPF_CHANGED ? */
410 pim_upstream_update_join_desired(up);
411
412 } /* PIM_RPF_CHANGED */
413
414 } /* for (qpim_upstream_list) */
415
416 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp))
417 if (ifp->info)
418 {
419 struct pim_interface *pim_ifp = ifp->info;
420 struct pim_iface_upstream_switch *us;
421
422 for (ALL_LIST_ELEMENTS_RO(pim_ifp->upstream_switch_list, node, us))
423 {
424 struct pim_rpf rpf;
425 rpf.source_nexthop.interface = ifp;
426 rpf.rpf_addr.u.prefix4 = us->address;
427 pim_joinprune_send(&rpf, us->us);
428 pim_jp_agg_clear_group(us->us);
429 }
430 }
431 }
432
433 void
434 pim_scan_individual_oil (struct channel_oil *c_oil, int in_vif_index)
435 {
436 struct in_addr vif_source;
437 int input_iface_vif_index;
438 int old_vif_index;
439
440 if (!pim_rp_set_upstream_addr (&vif_source, c_oil->oil.mfcc_origin, c_oil->oil.mfcc_mcastgrp))
441 return;
442
443 if (in_vif_index)
444 input_iface_vif_index = in_vif_index;
445 else
446 input_iface_vif_index = fib_lookup_if_vif_index (vif_source);
447 if (input_iface_vif_index < 1)
448 {
449 if (PIM_DEBUG_ZEBRA)
450 {
451 char source_str[INET_ADDRSTRLEN];
452 char group_str[INET_ADDRSTRLEN];
453 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
454 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
455 zlog_debug("%s %s: could not find input interface(%d) for (S,G)=(%s,%s)",
456 __FILE__, __PRETTY_FUNCTION__, c_oil->oil.mfcc_parent,
457 source_str, group_str);
458 }
459 pim_mroute_del (c_oil, __PRETTY_FUNCTION__);
460 return;
461 }
462
463 if (input_iface_vif_index == c_oil->oil.mfcc_parent)
464 {
465 if (!c_oil->installed)
466 pim_mroute_add (c_oil, __PRETTY_FUNCTION__);
467
468 /* RPF unchanged */
469 return;
470 }
471
472 if (PIM_DEBUG_ZEBRA)
473 {
474 struct interface *old_iif = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
475 struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index);
476 char source_str[INET_ADDRSTRLEN];
477 char group_str[INET_ADDRSTRLEN];
478 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
479 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
480 zlog_debug("%s %s: (S,G)=(%s,%s) input interface changed from %s vif_index=%d to %s vif_index=%d",
481 __FILE__, __PRETTY_FUNCTION__,
482 source_str, group_str,
483 old_iif->name, c_oil->oil.mfcc_parent,
484 new_iif->name, input_iface_vif_index);
485 }
486
487 /* new iif loops to existing oif ? */
488 if (c_oil->oil.mfcc_ttls[input_iface_vif_index])
489 {
490 struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index);
491
492 if (PIM_DEBUG_ZEBRA) {
493 char source_str[INET_ADDRSTRLEN];
494 char group_str[INET_ADDRSTRLEN];
495 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
496 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
497 zlog_debug("%s %s: (S,G)=(%s,%s) new iif loops to existing oif: %s vif_index=%d",
498 __FILE__, __PRETTY_FUNCTION__,
499 source_str, group_str,
500 new_iif->name, input_iface_vif_index);
501 }
502 }
503
504 /* update iif vif_index */
505 old_vif_index = c_oil->oil.mfcc_parent;
506 c_oil->oil.mfcc_parent = input_iface_vif_index;
507
508 /* update kernel multicast forwarding cache (MFC) */
509 if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__))
510 {
511 if (PIM_DEBUG_MROUTE)
512 {
513 /* just log warning */
514 struct interface *old_iif = pim_if_find_by_vif_index(old_vif_index);
515 struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index);
516 char source_str[INET_ADDRSTRLEN];
517 char group_str[INET_ADDRSTRLEN];
518 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
519 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
520 zlog_debug("%s %s: (S,G)=(%s,%s) failure updating input interface from %s vif_index=%d to %s vif_index=%d",
521 __FILE__, __PRETTY_FUNCTION__,
522 source_str, group_str,
523 old_iif ? old_iif->name : "<old_iif?>", c_oil->oil.mfcc_parent,
524 new_iif ? new_iif->name : "<new_iif?>", input_iface_vif_index);
525 }
526 }
527 }
528
529 void pim_scan_oil()
530 {
531 struct listnode *node;
532 struct listnode *nextnode;
533 struct channel_oil *c_oil;
534
535 qpim_scan_oil_last = pim_time_monotonic_sec();
536 ++qpim_scan_oil_events;
537
538 for (ALL_LIST_ELEMENTS(pim_channel_oil_list, node, nextnode, c_oil))
539 pim_scan_individual_oil (c_oil, 0);
540 }
541
542 static int on_rpf_cache_refresh(struct thread *t)
543 {
544 zassert(qpim_rpf_cache_refresher);
545
546 qpim_rpf_cache_refresher = 0;
547
548 /* update PIM protocol state */
549 scan_upstream_rpf_cache();
550
551 /* update kernel multicast forwarding cache (MFC) */
552 pim_scan_oil();
553
554 qpim_rpf_cache_refresh_last = pim_time_monotonic_sec();
555 ++qpim_rpf_cache_refresh_events;
556
557 pim_rp_setup ();
558 return 0;
559 }
560
561 void sched_rpf_cache_refresh(void)
562 {
563 ++qpim_rpf_cache_refresh_requests;
564
565 pim_rpf_set_refresh_time ();
566
567 if (qpim_rpf_cache_refresher) {
568 /* Refresh timer is already running */
569 return;
570 }
571
572 /* Start refresh timer */
573
574 if (PIM_DEBUG_ZEBRA) {
575 zlog_debug("%s: triggering %ld msec timer",
576 __PRETTY_FUNCTION__,
577 qpim_rpf_cache_refresh_delay_msec);
578 }
579
580 THREAD_TIMER_MSEC_ON(master, qpim_rpf_cache_refresher,
581 on_rpf_cache_refresh,
582 0, qpim_rpf_cache_refresh_delay_msec);
583 }
584
585 static int
586 pim_zebra_nexthop_update (int command, struct zclient *zclient,
587 zebra_size_t length, vrf_id_t vrf_id)
588 {
589 pim_parse_nexthop_update (zclient, command, vrf_id);
590 return 0;
591 }
592
593 static void
594 pim_zebra_connected (struct zclient *zclient)
595 {
596 zclient_send_reg_requests (zclient, VRF_DEFAULT);
597 }
598
599 void pim_zebra_init(void)
600 {
601 int i;
602
603 #ifdef HAVE_TCP_ZEBRA
604 zlog_notice("zclient update contacting ZEBRA daemon at socket TCP %s,%d", "127.0.0.1", ZEBRA_PORT);
605 #else
606 zlog_notice("zclient update contacting ZEBRA daemon at socket UNIX %s", zclient_serv_path_get());
607 #endif
608
609 /* Socket for receiving updates from Zebra daemon */
610 zclient = zclient_new (master);
611
612 zclient->zebra_connected = pim_zebra_connected;
613 zclient->router_id_update = pim_router_id_update_zebra;
614 zclient->interface_add = pim_zebra_if_add;
615 zclient->interface_delete = pim_zebra_if_del;
616 zclient->interface_up = pim_zebra_if_state_up;
617 zclient->interface_down = pim_zebra_if_state_down;
618 zclient->interface_address_add = pim_zebra_if_address_add;
619 zclient->interface_address_delete = pim_zebra_if_address_del;
620 zclient->nexthop_update = pim_zebra_nexthop_update;
621
622 zclient_init(zclient, ZEBRA_ROUTE_PIM, 0);
623 if (PIM_DEBUG_PIM_TRACE) {
624 zlog_info("zclient_init cleared redistribution request");
625 }
626
627 zassert(zclient->redist_default == ZEBRA_ROUTE_PIM);
628
629 /* Request all redistribution */
630 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
631 if (i == zclient->redist_default)
632 continue;
633 vrf_bitmap_set (zclient->redist[AFI_IP][i], VRF_DEFAULT);;
634 if (PIM_DEBUG_PIM_TRACE) {
635 zlog_debug("%s: requesting redistribution for %s (%i)",
636 __PRETTY_FUNCTION__, zebra_route_string(i), i);
637 }
638 }
639
640 /* Request default information */
641 zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
642 zclient, VRF_DEFAULT);
643
644 if (PIM_DEBUG_PIM_TRACE) {
645 zlog_info("%s: requesting default information redistribution",
646 __PRETTY_FUNCTION__);
647
648 zlog_notice("%s: zclient update socket initialized",
649 __PRETTY_FUNCTION__);
650 }
651
652 zclient_lookup_new();
653 }
654
655 void igmp_anysource_forward_start(struct igmp_group *group)
656 {
657 struct igmp_source *source;
658 struct in_addr src_addr = { .s_addr = 0 };
659 /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */
660 zassert(group->group_filtermode_isexcl);
661 zassert(listcount(group->group_source_list) < 1);
662
663 source = source_new (group, src_addr);
664 if (!source)
665 {
666 zlog_warn ("%s: Failure to create * source", __PRETTY_FUNCTION__);
667 return;
668 }
669
670 igmp_source_forward_start (source);
671 }
672
673 void igmp_anysource_forward_stop(struct igmp_group *group)
674 {
675 struct igmp_source *source;
676 struct in_addr star = { .s_addr = 0 };
677
678 source = igmp_find_source_by_addr (group, star);
679 if (source)
680 igmp_source_forward_stop (source);
681 }
682
683 static int fib_lookup_if_vif_index(struct in_addr addr)
684 {
685 struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
686 int num_ifindex;
687 int vif_index;
688 ifindex_t first_ifindex;
689
690 num_ifindex = zclient_lookup_nexthop(nexthop_tab,
691 MULTIPATH_NUM, addr,
692 PIM_NEXTHOP_LOOKUP_MAX);
693 if (num_ifindex < 1) {
694 if (PIM_DEBUG_ZEBRA)
695 {
696 char addr_str[INET_ADDRSTRLEN];
697 pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
698 zlog_debug("%s %s: could not find nexthop ifindex for address %s",
699 __FILE__, __PRETTY_FUNCTION__,
700 addr_str);
701 }
702 return -1;
703 }
704
705 first_ifindex = nexthop_tab[0].ifindex;
706
707 if (num_ifindex > 1) {
708 if (PIM_DEBUG_ZEBRA)
709 {
710 char addr_str[INET_ADDRSTRLEN];
711 pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
712 zlog_debug("%s %s: FIXME ignoring multiple nexthop ifindex'es num_ifindex=%d for address %s (using only ifindex=%d)",
713 __FILE__, __PRETTY_FUNCTION__,
714 num_ifindex, addr_str, first_ifindex);
715 }
716 /* debug warning only, do not return */
717 }
718
719 if (PIM_DEBUG_ZEBRA) {
720 char addr_str[INET_ADDRSTRLEN];
721 pim_inet4_dump("<ifaddr?>", addr, addr_str, sizeof(addr_str));
722 zlog_debug("%s %s: found nexthop ifindex=%d (interface %s) for address %s",
723 __FILE__, __PRETTY_FUNCTION__,
724 first_ifindex, ifindex2ifname(first_ifindex, VRF_DEFAULT), addr_str);
725 }
726
727 vif_index = pim_if_find_vifindex_by_ifindex(first_ifindex);
728
729 if (vif_index < 0) {
730 if (PIM_DEBUG_ZEBRA)
731 {
732 char addr_str[INET_ADDRSTRLEN];
733 pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
734 zlog_debug("%s %s: low vif_index=%d < 1 nexthop for address %s",
735 __FILE__, __PRETTY_FUNCTION__,
736 vif_index, addr_str);
737 }
738 return -2;
739 }
740
741 return vif_index;
742 }
743
744 static void
745 igmp_source_forward_reevaluate_one(struct igmp_source *source)
746 {
747 struct prefix_sg sg;
748 struct igmp_group *group = source->source_group;
749 struct pim_ifchannel *ch;
750
751 if ((source->source_addr.s_addr != INADDR_ANY) ||
752 !IGMP_SOURCE_TEST_FORWARDING (source->source_flags))
753 return;
754
755 memset (&sg, 0, sizeof (struct prefix_sg));
756 sg.src = source->source_addr;
757 sg.grp = group->group_addr;
758
759 ch = pim_ifchannel_find (group->group_igmp_sock->interface, &sg);
760 if (pim_is_grp_ssm (group->group_addr))
761 {
762 /* If SSM group withdraw local membership */
763 if (ch && (ch->local_ifmembership == PIM_IFMEMBERSHIP_INCLUDE))
764 {
765 if (PIM_DEBUG_PIM_EVENTS)
766 zlog_debug ("local membership del for %s as G is now SSM",
767 pim_str_sg_dump (&sg));
768 pim_ifchannel_local_membership_del (group->group_igmp_sock->interface, &sg);
769 }
770 }
771 else
772 {
773 /* If ASM group add local membership */
774 if (!ch || (ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO))
775 {
776 if (PIM_DEBUG_PIM_EVENTS)
777 zlog_debug ("local membership add for %s as G is now ASM",
778 pim_str_sg_dump (&sg));
779 pim_ifchannel_local_membership_add (group->group_igmp_sock->interface, &sg);
780 }
781 }
782 }
783
784 void
785 igmp_source_forward_reevaluate_all(void)
786 {
787 struct listnode *ifnode;
788 struct interface *ifp;
789
790 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp))
791 {
792 struct pim_interface *pim_ifp = ifp->info;
793 struct listnode *sock_node;
794 struct igmp_sock *igmp;
795
796 if (!pim_ifp)
797 continue;
798
799 /* scan igmp sockets */
800 for (ALL_LIST_ELEMENTS_RO (pim_ifp->igmp_socket_list, sock_node, igmp))
801 {
802 struct listnode *grpnode;
803 struct igmp_group *grp;
804
805 /* scan igmp groups */
806 for (ALL_LIST_ELEMENTS_RO (igmp->igmp_group_list, grpnode, grp))
807 {
808 struct listnode *srcnode;
809 struct igmp_source *src;
810
811 /* scan group sources */
812 for (ALL_LIST_ELEMENTS_RO (grp->group_source_list,
813 srcnode, src))
814 {
815 igmp_source_forward_reevaluate_one (src);
816 } /* scan group sources */
817 } /* scan igmp groups */
818 } /* scan igmp sockets */
819 } /* scan interfaces */
820 }
821
822 void igmp_source_forward_start(struct igmp_source *source)
823 {
824 struct igmp_group *group;
825 struct prefix_sg sg;
826 int result;
827
828 memset (&sg, 0, sizeof (struct prefix_sg));
829 sg.src = source->source_addr;
830 sg.grp = source->source_group->group_addr;
831
832 if (PIM_DEBUG_IGMP_TRACE) {
833 zlog_debug("%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d",
834 __PRETTY_FUNCTION__,
835 pim_str_sg_dump (&sg),
836 source->source_group->group_igmp_sock->fd,
837 source->source_group->group_igmp_sock->interface->name,
838 IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
839 }
840
841 /* Prevent IGMP interface from installing multicast route multiple
842 times */
843 if (IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
844 return;
845 }
846
847 group = source->source_group;
848
849 if (!source->source_channel_oil) {
850 struct in_addr vif_source;
851 struct pim_interface *pim_oif;
852
853 if (!pim_rp_set_upstream_addr (&vif_source, source->source_addr, sg.grp))
854 return;
855
856 int input_iface_vif_index = fib_lookup_if_vif_index(vif_source);
857 if (input_iface_vif_index < 1) {
858 if (PIM_DEBUG_IGMP_TRACE)
859 {
860 char source_str[INET_ADDRSTRLEN];
861 pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
862 zlog_debug("%s %s: could not find input interface for source %s",
863 __FILE__, __PRETTY_FUNCTION__,
864 source_str);
865 }
866 return;
867 }
868
869 /*
870 Protect IGMP against adding looped MFC entries created by both
871 source and receiver attached to the same interface. See TODO
872 T22.
873 */
874 pim_oif = source->source_group->group_igmp_sock->interface->info;
875 if (!pim_oif) {
876 if (PIM_DEBUG_IGMP_TRACE)
877 {
878 zlog_debug("%s: multicast not enabled on oif=%s ?",
879 __PRETTY_FUNCTION__,
880 source->source_group->group_igmp_sock->interface->name);
881 }
882 return;
883 }
884
885 if (input_iface_vif_index == pim_oif->mroute_vif_index) {
886 /* ignore request for looped MFC entry */
887 if (PIM_DEBUG_IGMP_TRACE) {
888 zlog_debug("%s: ignoring request for looped MFC entry (S,G)=%s: igmp_sock=%d oif=%s vif_index=%d",
889 __PRETTY_FUNCTION__,
890 pim_str_sg_dump (&sg),
891 source->source_group->group_igmp_sock->fd,
892 source->source_group->group_igmp_sock->interface->name,
893 input_iface_vif_index);
894 }
895 return;
896 }
897
898 source->source_channel_oil = pim_channel_oil_add(&sg,
899 input_iface_vif_index);
900 if (!source->source_channel_oil) {
901 if (PIM_DEBUG_IGMP_TRACE)
902 {
903 zlog_debug("%s %s: could not create OIL for channel (S,G)=%s",
904 __FILE__, __PRETTY_FUNCTION__,
905 pim_str_sg_dump (&sg));
906 }
907 return;
908 }
909 }
910
911 result = pim_channel_add_oif(source->source_channel_oil,
912 group->group_igmp_sock->interface,
913 PIM_OIF_FLAG_PROTO_IGMP);
914 if (result) {
915 if (PIM_DEBUG_MROUTE)
916 {
917 zlog_warn("%s: add_oif() failed with return=%d",
918 __func__, result);
919 }
920 return;
921 }
922
923 /*
924 Feed IGMPv3-gathered local membership information into PIM
925 per-interface (S,G) state.
926 */
927 if (!pim_ifchannel_local_membership_add(group->group_igmp_sock->interface, &sg))
928 {
929 if (PIM_DEBUG_MROUTE)
930 zlog_warn ("%s: Failure to add local membership for %s",
931 __PRETTY_FUNCTION__, pim_str_sg_dump (&sg));
932 return;
933 }
934
935 IGMP_SOURCE_DO_FORWARDING(source->source_flags);
936 }
937
938 /*
939 igmp_source_forward_stop: stop fowarding, but keep the source
940 igmp_source_delete: stop fowarding, and delete the source
941 */
942 void igmp_source_forward_stop(struct igmp_source *source)
943 {
944 struct igmp_group *group;
945 struct prefix_sg sg;
946 int result;
947
948 memset (&sg, 0, sizeof (struct prefix_sg));
949 sg.src = source->source_addr;
950 sg.grp = source->source_group->group_addr;
951
952 if (PIM_DEBUG_IGMP_TRACE) {
953 zlog_debug("%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d",
954 __PRETTY_FUNCTION__,
955 pim_str_sg_dump (&sg),
956 source->source_group->group_igmp_sock->fd,
957 source->source_group->group_igmp_sock->interface->name,
958 IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
959 }
960
961 /* Prevent IGMP interface from removing multicast route multiple
962 times */
963 if (!IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
964 return;
965 }
966
967 group = source->source_group;
968
969 /*
970 It appears that in certain circumstances that
971 igmp_source_forward_stop is called when IGMP forwarding
972 was not enabled in oif_flags for this outgoing interface.
973 Possibly because of multiple calls. When that happens, we
974 enter the below if statement and this function returns early
975 which in turn triggers the calling function to assert.
976 Making the call to pim_channel_del_oif and ignoring the return code
977 fixes the issue without ill effect, similar to
978 pim_forward_stop below.
979 */
980 result = pim_channel_del_oif(source->source_channel_oil,
981 group->group_igmp_sock->interface,
982 PIM_OIF_FLAG_PROTO_IGMP);
983 if (result) {
984 if (PIM_DEBUG_IGMP_TRACE)
985 zlog_debug("%s: pim_channel_del_oif() failed with return=%d",
986 __func__, result);
987 return;
988 }
989
990 /*
991 Feed IGMPv3-gathered local membership information into PIM
992 per-interface (S,G) state.
993 */
994 pim_ifchannel_local_membership_del(group->group_igmp_sock->interface,
995 &sg);
996
997 IGMP_SOURCE_DONT_FORWARDING(source->source_flags);
998 }
999
1000 void pim_forward_start(struct pim_ifchannel *ch)
1001 {
1002 struct pim_upstream *up = ch->upstream;
1003 uint32_t mask = PIM_OIF_FLAG_PROTO_PIM;
1004
1005 if (PIM_DEBUG_PIM_TRACE) {
1006 char source_str[INET_ADDRSTRLEN];
1007 char group_str[INET_ADDRSTRLEN];
1008 char upstream_str[INET_ADDRSTRLEN];
1009
1010 pim_inet4_dump("<source?>", ch->sg.src, source_str, sizeof(source_str));
1011 pim_inet4_dump("<group?>", ch->sg.grp, group_str, sizeof(group_str));
1012 pim_inet4_dump("<upstream?>", up->upstream_addr, upstream_str, sizeof(upstream_str));
1013 zlog_debug("%s: (S,G)=(%s,%s) oif=%s(%s)",
1014 __PRETTY_FUNCTION__,
1015 source_str, group_str, ch->interface->name, upstream_str);
1016 }
1017
1018 if (!up->channel_oil) {
1019 int input_iface_vif_index = fib_lookup_if_vif_index(up->upstream_addr);
1020 if (input_iface_vif_index < 1) {
1021 if (PIM_DEBUG_PIM_TRACE)
1022 {
1023 char source_str[INET_ADDRSTRLEN];
1024 pim_inet4_dump("<source?>", up->sg.src, source_str, sizeof(source_str));
1025 zlog_debug("%s %s: could not find input interface for source %s",
1026 __FILE__, __PRETTY_FUNCTION__,
1027 source_str);
1028 }
1029 return;
1030 }
1031
1032 up->channel_oil = pim_channel_oil_add(&up->sg,
1033 input_iface_vif_index);
1034 if (!up->channel_oil) {
1035 if (PIM_DEBUG_PIM_TRACE)
1036 zlog_debug("%s %s: could not create OIL for channel (S,G)=%s",
1037 __FILE__, __PRETTY_FUNCTION__,
1038 up->sg_str);
1039 return;
1040 }
1041 }
1042
1043 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
1044 mask = PIM_OIF_FLAG_PROTO_IGMP;
1045
1046 pim_channel_add_oif(up->channel_oil, ch->interface, mask);
1047 }
1048
1049 void pim_forward_stop(struct pim_ifchannel *ch)
1050 {
1051 struct pim_upstream *up = ch->upstream;
1052
1053 if (PIM_DEBUG_PIM_TRACE) {
1054 zlog_debug("%s: (S,G)=%s oif=%s",
1055 __PRETTY_FUNCTION__,
1056 ch->sg_str, ch->interface->name);
1057 }
1058
1059 pim_channel_del_oif(up->channel_oil,
1060 ch->interface,
1061 PIM_OIF_FLAG_PROTO_PIM);
1062 }
1063
1064 void
1065 pim_zebra_zclient_update (struct vty *vty)
1066 {
1067 vty_out(vty, "Zclient update socket: ");
1068
1069 if (zclient) {
1070 vty_out(vty, "%d failures=%d%s", zclient->sock,
1071 zclient->fail, VTY_NEWLINE);
1072 }
1073 else {
1074 vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
1075 }
1076 }
1077
1078 struct zclient *pim_zebra_zclient_get (void)
1079 {
1080 if (zclient)
1081 return zclient;
1082 else
1083 return NULL;
1084 }