]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_iface.c
Merge pull request #11826 from mjstapp/stop_zebra_last
[mirror_frr.git] / pimd / pim_iface.c
1 /*
2 * PIM for Quagga
3 * Copyright (C) 2008 Everton da Silva Marques
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; see the file COPYING; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <zebra.h>
20
21 #include "if.h"
22 #include "log.h"
23 #include "vty.h"
24 #include "memory.h"
25 #include "prefix.h"
26 #include "vrf.h"
27 #include "linklist.h"
28 #include "plist.h"
29 #include "hash.h"
30 #include "ferr.h"
31 #include "network.h"
32
33 #include "pimd.h"
34 #include "pim_instance.h"
35 #include "pim_zebra.h"
36 #include "pim_iface.h"
37 #include "pim_igmp.h"
38 #include "pim_mroute.h"
39 #include "pim_oil.h"
40 #include "pim_str.h"
41 #include "pim_pim.h"
42 #include "pim_neighbor.h"
43 #include "pim_ifchannel.h"
44 #include "pim_sock.h"
45 #include "pim_time.h"
46 #include "pim_ssmpingd.h"
47 #include "pim_rp.h"
48 #include "pim_nht.h"
49 #include "pim_jp_agg.h"
50 #include "pim_igmp_join.h"
51 #include "pim_vxlan.h"
52
53 #include "pim6_mld.h"
54
55 #if PIM_IPV == 4
56 static void pim_if_igmp_join_del_all(struct interface *ifp);
57 static int igmp_join_sock(const char *ifname, ifindex_t ifindex,
58 struct in_addr group_addr, struct in_addr source_addr,
59 struct pim_interface *pim_ifp);
60 #endif
61
62 void pim_if_init(struct pim_instance *pim)
63 {
64 int i;
65
66 for (i = 0; i < MAXVIFS; i++)
67 pim->iface_vif_index[i] = 0;
68 }
69
70 void pim_if_terminate(struct pim_instance *pim)
71 {
72 struct interface *ifp;
73
74 FOR_ALL_INTERFACES (pim->vrf, ifp) {
75 struct pim_interface *pim_ifp = ifp->info;
76
77 if (!pim_ifp)
78 continue;
79
80 pim_if_delete(ifp);
81 }
82 return;
83 }
84
85 static void pim_sec_addr_free(struct pim_secondary_addr *sec_addr)
86 {
87 XFREE(MTYPE_PIM_SEC_ADDR, sec_addr);
88 }
89
90 __attribute__((unused))
91 static int pim_sec_addr_comp(const void *p1, const void *p2)
92 {
93 const struct pim_secondary_addr *sec1 = p1;
94 const struct pim_secondary_addr *sec2 = p2;
95
96 if (sec1->addr.family == AF_INET && sec2->addr.family == AF_INET6)
97 return -1;
98
99 if (sec1->addr.family == AF_INET6 && sec2->addr.family == AF_INET)
100 return 1;
101
102 if (sec1->addr.family == AF_INET) {
103 if (ntohl(sec1->addr.u.prefix4.s_addr)
104 < ntohl(sec2->addr.u.prefix4.s_addr))
105 return -1;
106
107 if (ntohl(sec1->addr.u.prefix4.s_addr)
108 > ntohl(sec2->addr.u.prefix4.s_addr))
109 return 1;
110 } else {
111 return memcmp(&sec1->addr.u.prefix6, &sec2->addr.u.prefix6,
112 sizeof(struct in6_addr));
113 }
114
115 return 0;
116 }
117
118 struct pim_interface *pim_if_new(struct interface *ifp, bool igmp, bool pim,
119 bool ispimreg, bool is_vxlan_term)
120 {
121 struct pim_interface *pim_ifp;
122
123 assert(ifp);
124 assert(!ifp->info);
125
126 pim_ifp = XCALLOC(MTYPE_PIM_INTERFACE, sizeof(*pim_ifp));
127
128 pim_ifp->pim = ifp->vrf->info;
129 pim_ifp->mroute_vif_index = -1;
130
131 pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
132 pim_ifp->mld_version = MLD_DEFAULT_VERSION;
133 pim_ifp->gm_default_robustness_variable =
134 IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
135 pim_ifp->gm_default_query_interval = IGMP_GENERAL_QUERY_INTERVAL;
136 pim_ifp->gm_query_max_response_time_dsec =
137 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC;
138 pim_ifp->gm_specific_query_max_response_time_dsec =
139 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC;
140 pim_ifp->gm_last_member_query_count = IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
141
142 /* BSM config on interface: true by default */
143 pim_ifp->bsm_enable = true;
144 pim_ifp->ucast_bsm_accept = true;
145 pim_ifp->am_i_dr = false;
146
147 /*
148 RFC 3376: 8.3. Query Response Interval
149 The number of seconds represented by the [Query Response Interval]
150 must be less than the [Query Interval].
151 */
152 assert(pim_ifp->gm_query_max_response_time_dsec <
153 pim_ifp->gm_default_query_interval);
154
155 pim_ifp->pim_enable = pim;
156 pim_ifp->pim_passive_enable = false;
157 #if PIM_IPV == 4
158 pim_ifp->gm_enable = igmp;
159 #endif
160
161 pim_ifp->gm_join_list = NULL;
162 pim_ifp->pim_neighbor_list = NULL;
163 pim_ifp->upstream_switch_list = NULL;
164 pim_ifp->pim_generation_id = 0;
165
166 /* list of struct gm_sock */
167 pim_igmp_if_init(pim_ifp, ifp);
168
169 /* list of struct pim_neighbor */
170 pim_ifp->pim_neighbor_list = list_new();
171 pim_ifp->pim_neighbor_list->del = (void (*)(void *))pim_neighbor_free;
172
173 pim_ifp->upstream_switch_list = list_new();
174 pim_ifp->upstream_switch_list->del =
175 (void (*)(void *))pim_jp_agg_group_list_free;
176 pim_ifp->upstream_switch_list->cmp = pim_jp_agg_group_list_cmp;
177
178 pim_ifp->sec_addr_list = list_new();
179 pim_ifp->sec_addr_list->del = (void (*)(void *))pim_sec_addr_free;
180 pim_ifp->sec_addr_list->cmp =
181 (int (*)(void *, void *))pim_sec_addr_comp;
182
183 pim_ifp->activeactive = false;
184
185 RB_INIT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb);
186
187 ifp->info = pim_ifp;
188
189 pim_sock_reset(ifp);
190
191 pim_if_add_vif(ifp, ispimreg, is_vxlan_term);
192 pim_ifp->pim->mcast_if_count++;
193
194 return pim_ifp;
195 }
196
197 void pim_if_delete(struct interface *ifp)
198 {
199 struct pim_interface *pim_ifp;
200
201 assert(ifp);
202 pim_ifp = ifp->info;
203 assert(pim_ifp);
204
205 pim_ifp->pim->mcast_if_count--;
206 #if PIM_IPV == 4
207 if (pim_ifp->gm_join_list) {
208 pim_if_igmp_join_del_all(ifp);
209 }
210 #endif
211
212 pim_ifchannel_delete_all(ifp);
213 #if PIM_IPV == 4
214 igmp_sock_delete_all(ifp);
215 #endif
216 if (pim_ifp->pim_sock_fd >= 0)
217 pim_sock_delete(ifp, "Interface removed from configuration");
218
219 pim_if_del_vif(ifp);
220
221 pim_igmp_if_fini(pim_ifp);
222
223 list_delete(&pim_ifp->pim_neighbor_list);
224 list_delete(&pim_ifp->upstream_switch_list);
225 list_delete(&pim_ifp->sec_addr_list);
226
227 XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
228 XFREE(MTYPE_PIM_INTERFACE, pim_ifp);
229
230 ifp->info = NULL;
231 }
232
233 void pim_if_update_could_assert(struct interface *ifp)
234 {
235 struct pim_interface *pim_ifp;
236 struct pim_ifchannel *ch;
237
238 pim_ifp = ifp->info;
239 assert(pim_ifp);
240
241 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
242 pim_ifchannel_update_could_assert(ch);
243 }
244 }
245
246 static void pim_if_update_my_assert_metric(struct interface *ifp)
247 {
248 struct pim_interface *pim_ifp;
249 struct pim_ifchannel *ch;
250
251 pim_ifp = ifp->info;
252 assert(pim_ifp);
253
254 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
255 pim_ifchannel_update_my_assert_metric(ch);
256 }
257 }
258
259 static void pim_addr_change(struct interface *ifp)
260 {
261 struct pim_interface *pim_ifp;
262
263 pim_ifp = ifp->info;
264 assert(pim_ifp);
265
266 pim_if_dr_election(ifp); /* router's own DR Priority (addr) changes --
267 Done TODO T30 */
268 pim_if_update_join_desired(pim_ifp); /* depends on DR */
269 pim_if_update_could_assert(ifp); /* depends on DR */
270 pim_if_update_my_assert_metric(ifp); /* depends on could_assert */
271 pim_if_update_assert_tracking_desired(
272 ifp); /* depends on DR, join_desired */
273
274 /*
275 RFC 4601: 4.3.1. Sending Hello Messages
276
277 1) Before an interface goes down or changes primary IP address, a
278 Hello message with a zero HoldTime should be sent immediately
279 (with the old IP address if the IP address changed).
280 -- Done at the caller of the function as new ip already updated here
281
282 2) After an interface has changed its IP address, it MUST send a
283 Hello message with its new IP address.
284 -- DONE below
285
286 3) If an interface changes one of its secondary IP addresses, a
287 Hello message with an updated Address_List option and a non-zero
288 HoldTime should be sent immediately.
289 -- FIXME See TODO T31
290 */
291 PIM_IF_FLAG_UNSET_HELLO_SENT(pim_ifp->flags);
292 if (pim_ifp->pim_sock_fd < 0)
293 return;
294 pim_hello_restart_now(ifp); /* send hello and restart timer */
295 }
296
297 static int detect_primary_address_change(struct interface *ifp,
298 int force_prim_as_any,
299 const char *caller)
300 {
301 struct pim_interface *pim_ifp = ifp->info;
302 pim_addr new_prim_addr;
303 int changed;
304
305 if (force_prim_as_any)
306 new_prim_addr = PIMADDR_ANY;
307 else
308 new_prim_addr = pim_find_primary_addr(ifp);
309
310 changed = pim_addr_cmp(new_prim_addr, pim_ifp->primary_address);
311
312 if (PIM_DEBUG_ZEBRA)
313 zlog_debug("%s: old=%pPA new=%pPA on interface %s: %s",
314 __func__, &pim_ifp->primary_address, &new_prim_addr,
315 ifp->name, changed ? "changed" : "unchanged");
316
317 if (changed) {
318 /* Before updating pim_ifp send Hello time with 0 hold time */
319 if (pim_ifp->pim_enable) {
320 pim_hello_send(ifp, 0 /* zero-sec holdtime */);
321 }
322 pim_ifp->primary_address = new_prim_addr;
323 }
324
325 return changed;
326 }
327
328 static struct pim_secondary_addr *
329 pim_sec_addr_find(struct pim_interface *pim_ifp, struct prefix *addr)
330 {
331 struct pim_secondary_addr *sec_addr;
332 struct listnode *node;
333
334 for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) {
335 if (prefix_cmp(&sec_addr->addr, addr) == 0) {
336 return sec_addr;
337 }
338 }
339
340 return NULL;
341 }
342
343 static void pim_sec_addr_del(struct pim_interface *pim_ifp,
344 struct pim_secondary_addr *sec_addr)
345 {
346 listnode_delete(pim_ifp->sec_addr_list, sec_addr);
347 pim_sec_addr_free(sec_addr);
348 }
349
350 static int pim_sec_addr_add(struct pim_interface *pim_ifp, struct prefix *addr)
351 {
352 int changed = 0;
353 struct pim_secondary_addr *sec_addr;
354
355 sec_addr = pim_sec_addr_find(pim_ifp, addr);
356 if (sec_addr) {
357 sec_addr->flags &= ~PIM_SEC_ADDRF_STALE;
358 return changed;
359 }
360
361 sec_addr = XCALLOC(MTYPE_PIM_SEC_ADDR, sizeof(*sec_addr));
362
363 changed = 1;
364 sec_addr->addr = *addr;
365 listnode_add_sort(pim_ifp->sec_addr_list, sec_addr);
366
367 return changed;
368 }
369
370 static int pim_sec_addr_del_all(struct pim_interface *pim_ifp)
371 {
372 int changed = 0;
373
374 if (!list_isempty(pim_ifp->sec_addr_list)) {
375 changed = 1;
376 /* remove all nodes and free up the list itself */
377 list_delete_all_node(pim_ifp->sec_addr_list);
378 }
379
380 return changed;
381 }
382
383 static int pim_sec_addr_update(struct interface *ifp)
384 {
385 struct pim_interface *pim_ifp = ifp->info;
386 struct connected *ifc;
387 struct listnode *node;
388 struct listnode *nextnode;
389 struct pim_secondary_addr *sec_addr;
390 int changed = 0;
391
392 for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) {
393 sec_addr->flags |= PIM_SEC_ADDRF_STALE;
394 }
395
396 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
397 pim_addr addr = pim_addr_from_prefix(ifc->address);
398
399 if (pim_addr_is_any(addr))
400 continue;
401
402 if (!pim_addr_cmp(addr, pim_ifp->primary_address)) {
403 /* don't add the primary address into the secondary
404 * address list */
405 continue;
406 }
407
408 if (pim_sec_addr_add(pim_ifp, ifc->address)) {
409 changed = 1;
410 }
411 }
412
413 /* Drop stale entries */
414 for (ALL_LIST_ELEMENTS(pim_ifp->sec_addr_list, node, nextnode,
415 sec_addr)) {
416 if (sec_addr->flags & PIM_SEC_ADDRF_STALE) {
417 pim_sec_addr_del(pim_ifp, sec_addr);
418 changed = 1;
419 }
420 }
421
422 return changed;
423 }
424
425 static int detect_secondary_address_change(struct interface *ifp,
426 int force_prim_as_any,
427 const char *caller)
428 {
429 struct pim_interface *pim_ifp = ifp->info;
430 int changed = 0;
431
432 if (force_prim_as_any) {
433 /* if primary address is being forced to zero just flush the
434 * secondary address list */
435 changed = pim_sec_addr_del_all(pim_ifp);
436 } else {
437 /* re-evaluate the secondary address list */
438 changed = pim_sec_addr_update(ifp);
439 }
440
441 return changed;
442 }
443
444 static void detect_address_change(struct interface *ifp, int force_prim_as_any,
445 const char *caller)
446 {
447 int changed = 0;
448 struct pim_interface *pim_ifp;
449
450 pim_ifp = ifp->info;
451 if (!pim_ifp)
452 return;
453
454 if (detect_primary_address_change(ifp, force_prim_as_any, caller)) {
455 changed = 1;
456 }
457
458 if (detect_secondary_address_change(ifp, force_prim_as_any, caller)) {
459 changed = 1;
460 }
461
462
463 if (changed) {
464 if (!pim_ifp->pim_enable) {
465 return;
466 }
467
468 pim_addr_change(ifp);
469 }
470
471 /* XXX: if we have unnumbered interfaces we need to run detect address
472 * address change on all of them when the lo address changes */
473 }
474
475 int pim_update_source_set(struct interface *ifp, pim_addr source)
476 {
477 struct pim_interface *pim_ifp = ifp->info;
478
479 if (!pim_ifp) {
480 return PIM_IFACE_NOT_FOUND;
481 }
482
483 if (!pim_addr_cmp(pim_ifp->update_source, source)) {
484 return PIM_UPDATE_SOURCE_DUP;
485 }
486
487 pim_ifp->update_source = source;
488 detect_address_change(ifp, 0 /* force_prim_as_any */, __func__);
489
490 return PIM_SUCCESS;
491 }
492
493 void pim_if_addr_add(struct connected *ifc)
494 {
495 struct pim_interface *pim_ifp;
496 struct interface *ifp;
497 bool vxlan_term;
498
499 assert(ifc);
500
501 ifp = ifc->ifp;
502 assert(ifp);
503 pim_ifp = ifp->info;
504 if (!pim_ifp)
505 return;
506
507 if (!if_is_operative(ifp))
508 return;
509
510 if (PIM_DEBUG_ZEBRA)
511 zlog_debug("%s: %s ifindex=%d connected IP address %pFX %s",
512 __func__, ifp->name, ifp->ifindex, ifc->address,
513 CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)
514 ? "secondary"
515 : "primary");
516 #if PIM_IPV != 4
517 if (IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6) ||
518 IN6_IS_ADDR_LOOPBACK(&ifc->address->u.prefix6)) {
519 if (IN6_IS_ADDR_UNSPECIFIED(&pim_ifp->ll_lowest))
520 pim_ifp->ll_lowest = ifc->address->u.prefix6;
521 else if (IPV6_ADDR_CMP(&ifc->address->u.prefix6,
522 &pim_ifp->ll_lowest) < 0)
523 pim_ifp->ll_lowest = ifc->address->u.prefix6;
524
525 if (IPV6_ADDR_CMP(&ifc->address->u.prefix6,
526 &pim_ifp->ll_highest) > 0)
527 pim_ifp->ll_highest = ifc->address->u.prefix6;
528
529 if (PIM_DEBUG_ZEBRA)
530 zlog_debug(
531 "%s: new link-local %pI6, lowest now %pI6, highest %pI6",
532 ifc->ifp->name, &ifc->address->u.prefix6,
533 &pim_ifp->ll_lowest, &pim_ifp->ll_highest);
534 }
535 #endif
536
537 detect_address_change(ifp, 0, __func__);
538
539 // if (ifc->address->family != AF_INET)
540 // return;
541
542 #if PIM_IPV == 4
543 struct in_addr ifaddr = ifc->address->u.prefix4;
544
545 if (pim_ifp->gm_enable) {
546 struct gm_sock *igmp;
547
548 /* lookup IGMP socket */
549 igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->gm_socket_list,
550 ifaddr);
551 if (!igmp) {
552 /* if addr new, add IGMP socket */
553 if (ifc->address->family == AF_INET)
554 pim_igmp_sock_add(pim_ifp->gm_socket_list,
555 ifaddr, ifp, false);
556 } else if (igmp->mtrace_only) {
557 igmp_sock_delete(igmp);
558 pim_igmp_sock_add(pim_ifp->gm_socket_list, ifaddr, ifp,
559 false);
560 }
561
562 /* Replay Static IGMP groups */
563 if (pim_ifp->gm_join_list) {
564 struct listnode *node;
565 struct listnode *nextnode;
566 struct gm_join *ij;
567 int join_fd;
568
569 for (ALL_LIST_ELEMENTS(pim_ifp->gm_join_list, node,
570 nextnode, ij)) {
571 /* Close socket and reopen with Source and Group
572 */
573 close(ij->sock_fd);
574 join_fd = igmp_join_sock(
575 ifp->name, ifp->ifindex, ij->group_addr,
576 ij->source_addr, pim_ifp);
577 if (join_fd < 0) {
578 char group_str[INET_ADDRSTRLEN];
579 char source_str[INET_ADDRSTRLEN];
580 pim_inet4_dump("<grp?>", ij->group_addr,
581 group_str,
582 sizeof(group_str));
583 pim_inet4_dump(
584 "<src?>", ij->source_addr,
585 source_str, sizeof(source_str));
586 zlog_warn(
587 "%s: igmp_join_sock() failure for IGMP group %s source %s on interface %s",
588 __func__, group_str, source_str,
589 ifp->name);
590 /* warning only */
591 } else
592 ij->sock_fd = join_fd;
593 }
594 }
595 } /* igmp */
596 else {
597 struct gm_sock *igmp;
598
599 /* lookup IGMP socket */
600 igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->gm_socket_list,
601 ifaddr);
602 if (ifc->address->family == AF_INET) {
603 if (igmp)
604 igmp_sock_delete(igmp);
605 /* if addr new, add IGMP socket */
606 pim_igmp_sock_add(pim_ifp->gm_socket_list, ifaddr, ifp,
607 true);
608 }
609 } /* igmp mtrace only */
610 #endif
611
612 if (pim_ifp->pim_enable) {
613
614 if (!pim_addr_is_any(pim_ifp->primary_address)) {
615
616 /* Interface has a valid socket ? */
617 if (pim_ifp->pim_sock_fd < 0) {
618 if (pim_sock_add(ifp)) {
619 zlog_warn(
620 "Failure creating PIM socket for interface %s",
621 ifp->name);
622 }
623 }
624 struct pim_nexthop_cache *pnc = NULL;
625 struct pim_rpf rpf;
626 struct zclient *zclient = NULL;
627
628 zclient = pim_zebra_zclient_get();
629 /* RP config might come prior to (local RP's interface)
630 IF UP event.
631 In this case, pnc would not have pim enabled
632 nexthops.
633 Once Interface is UP and pim info is available,
634 reregister
635 with RNH address to receive update and add the
636 interface as nexthop. */
637 memset(&rpf, 0, sizeof(struct pim_rpf));
638 rpf.rpf_addr = pim_addr_from_prefix(ifc->address);
639 pnc = pim_nexthop_cache_find(pim_ifp->pim, &rpf);
640 if (pnc)
641 pim_sendmsg_zebra_rnh(pim_ifp->pim, zclient,
642 pnc,
643 ZEBRA_NEXTHOP_REGISTER);
644 }
645 } /* pim */
646
647 /*
648 PIM or IGMP is enabled on interface, and there is at least one
649 address assigned, then try to create a vif_index.
650 */
651 if (pim_ifp->mroute_vif_index < 0) {
652 vxlan_term = pim_vxlan_is_term_dev_cfg(pim_ifp->pim, ifp);
653 pim_if_add_vif(ifp, false, vxlan_term);
654 }
655 gm_ifp_update(ifp);
656 pim_ifchannel_scan_forward_start(ifp);
657 }
658
659 static void pim_if_addr_del_igmp(struct connected *ifc)
660 {
661 #if PIM_IPV == 4
662 struct pim_interface *pim_ifp = ifc->ifp->info;
663 struct gm_sock *igmp;
664 struct in_addr ifaddr;
665
666 if (ifc->address->family != AF_INET) {
667 /* non-IPv4 address */
668 return;
669 }
670
671 if (!pim_ifp) {
672 /* IGMP not enabled on interface */
673 return;
674 }
675
676 ifaddr = ifc->address->u.prefix4;
677
678 /* lookup IGMP socket */
679 igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->gm_socket_list, ifaddr);
680 if (igmp) {
681 /* if addr found, del IGMP socket */
682 igmp_sock_delete(igmp);
683 }
684 #endif
685 }
686
687 static void pim_if_addr_del_pim(struct connected *ifc)
688 {
689 struct pim_interface *pim_ifp = ifc->ifp->info;
690
691 if (ifc->address->family != AF_INET) {
692 /* non-IPv4 address */
693 return;
694 }
695
696 if (!pim_ifp) {
697 /* PIM not enabled on interface */
698 return;
699 }
700
701 if (!pim_addr_is_any(pim_ifp->primary_address)) {
702 /* Interface keeps a valid primary address */
703 return;
704 }
705
706 if (pim_ifp->pim_sock_fd < 0) {
707 /* Interface does not hold a valid socket any longer */
708 return;
709 }
710
711 /*
712 pim_sock_delete() closes the socket, stops read and timer threads,
713 and kills all neighbors.
714 */
715 pim_sock_delete(ifc->ifp,
716 "last address has been removed from interface");
717 }
718
719 void pim_if_addr_del(struct connected *ifc, int force_prim_as_any)
720 {
721 struct interface *ifp;
722
723 assert(ifc);
724 ifp = ifc->ifp;
725 assert(ifp);
726
727 if (PIM_DEBUG_ZEBRA)
728 zlog_debug("%s: %s ifindex=%d disconnected IP address %pFX %s",
729 __func__, ifp->name, ifp->ifindex, ifc->address,
730 CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)
731 ? "secondary"
732 : "primary");
733
734 #if PIM_IPV == 6
735 struct pim_interface *pim_ifp = ifc->ifp->info;
736
737 if (pim_ifp &&
738 (!IPV6_ADDR_CMP(&ifc->address->u.prefix6, &pim_ifp->ll_lowest) ||
739 !IPV6_ADDR_CMP(&ifc->address->u.prefix6, &pim_ifp->ll_highest))) {
740 struct listnode *cnode;
741 struct connected *cc;
742
743 memset(&pim_ifp->ll_lowest, 0xff, sizeof(pim_ifp->ll_lowest));
744 memset(&pim_ifp->ll_highest, 0, sizeof(pim_ifp->ll_highest));
745
746 for (ALL_LIST_ELEMENTS_RO(ifc->ifp->connected, cnode, cc)) {
747 if (!IN6_IS_ADDR_LINKLOCAL(&cc->address->u.prefix6) &&
748 !IN6_IS_ADDR_LOOPBACK(&cc->address->u.prefix6))
749 continue;
750
751 if (IPV6_ADDR_CMP(&cc->address->u.prefix6,
752 &pim_ifp->ll_lowest) < 0)
753 pim_ifp->ll_lowest = cc->address->u.prefix6;
754 if (IPV6_ADDR_CMP(&cc->address->u.prefix6,
755 &pim_ifp->ll_highest) > 0)
756 pim_ifp->ll_highest = cc->address->u.prefix6;
757 }
758
759 if (pim_ifp->ll_lowest.s6_addr[0] == 0xff)
760 memset(&pim_ifp->ll_lowest, 0,
761 sizeof(pim_ifp->ll_lowest));
762
763 if (PIM_DEBUG_ZEBRA)
764 zlog_debug(
765 "%s: removed link-local %pI6, lowest now %pI6, highest %pI6",
766 ifc->ifp->name, &ifc->address->u.prefix6,
767 &pim_ifp->ll_lowest, &pim_ifp->ll_highest);
768
769 gm_ifp_update(ifp);
770 }
771 #endif
772
773 detect_address_change(ifp, force_prim_as_any, __func__);
774
775 pim_if_addr_del_igmp(ifc);
776 pim_if_addr_del_pim(ifc);
777 }
778
779 void pim_if_addr_add_all(struct interface *ifp)
780 {
781 struct connected *ifc;
782 struct listnode *node;
783 struct listnode *nextnode;
784 int v4_addrs = 0;
785 int v6_addrs = 0;
786 struct pim_interface *pim_ifp = ifp->info;
787 bool vxlan_term;
788
789
790 /* PIM/IGMP enabled ? */
791 if (!pim_ifp)
792 return;
793
794 for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
795 struct prefix *p = ifc->address;
796
797 if (p->family != AF_INET)
798 v6_addrs++;
799 else
800 v4_addrs++;
801 pim_if_addr_add(ifc);
802 }
803
804 if (!v4_addrs && v6_addrs && !if_is_loopback(ifp) &&
805 pim_ifp->pim_enable && !pim_addr_is_any(pim_ifp->primary_address) &&
806 pim_ifp->pim_sock_fd < 0 && pim_sock_add(ifp)) {
807 /* Interface has a valid primary address ? */
808 /* Interface has a valid socket ? */
809 zlog_warn("Failure creating PIM socket for interface %s",
810 ifp->name);
811 }
812 /*
813 * PIM or IGMP is enabled on interface, and there is at least one
814 * address assigned, then try to create a vif_index.
815 */
816 if (pim_ifp->mroute_vif_index < 0) {
817 vxlan_term = pim_vxlan_is_term_dev_cfg(pim_ifp->pim, ifp);
818 pim_if_add_vif(ifp, false, vxlan_term);
819 }
820 gm_ifp_update(ifp);
821 pim_ifchannel_scan_forward_start(ifp);
822
823 pim_rp_setup(pim_ifp->pim);
824 pim_rp_check_on_if_add(pim_ifp);
825 }
826
827 void pim_if_addr_del_all(struct interface *ifp)
828 {
829 struct connected *ifc;
830 struct listnode *node;
831 struct listnode *nextnode;
832 struct pim_instance *pim;
833
834 pim = ifp->vrf->info;
835 if (!pim)
836 return;
837
838 /* PIM/IGMP enabled ? */
839 if (!ifp->info)
840 return;
841
842 for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
843 struct prefix *p = ifc->address;
844
845 if (p->family != AF_INET)
846 continue;
847
848 pim_if_addr_del(ifc, 1 /* force_prim_as_any=true */);
849 }
850
851 pim_rp_setup(pim);
852 pim_i_am_rp_re_evaluate(pim);
853 }
854
855 void pim_if_addr_del_all_igmp(struct interface *ifp)
856 {
857 struct connected *ifc;
858 struct listnode *node;
859 struct listnode *nextnode;
860
861 /* PIM/IGMP enabled ? */
862 if (!ifp->info)
863 return;
864
865 for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
866 struct prefix *p = ifc->address;
867
868 if (p->family != AF_INET)
869 continue;
870
871 pim_if_addr_del_igmp(ifc);
872 }
873 }
874
875 pim_addr pim_find_primary_addr(struct interface *ifp)
876 {
877 struct connected *ifc;
878 struct listnode *node;
879 struct pim_interface *pim_ifp = ifp->info;
880
881 if (pim_ifp && !pim_addr_is_any(pim_ifp->update_source))
882 return pim_ifp->update_source;
883
884 #if PIM_IPV == 6
885 if (pim_ifp)
886 return pim_ifp->ll_highest;
887
888 pim_addr best_addr = PIMADDR_ANY;
889
890 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
891 pim_addr addr;
892
893 if (ifc->address->family != AF_INET6)
894 continue;
895
896 addr = pim_addr_from_prefix(ifc->address);
897 if (!IN6_IS_ADDR_LINKLOCAL(&addr))
898 continue;
899 if (pim_addr_cmp(addr, best_addr) > 0)
900 best_addr = addr;
901 }
902
903 return best_addr;
904 #else
905 int v4_addrs = 0;
906 int v6_addrs = 0;
907
908 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
909 switch (ifc->address->family) {
910 case AF_INET:
911 v4_addrs++;
912 break;
913 case AF_INET6:
914 v6_addrs++;
915 break;
916 default:
917 continue;
918 }
919
920 if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
921 continue;
922
923 if (ifc->address->family != PIM_AF)
924 continue;
925
926 return pim_addr_from_prefix(ifc->address);
927 }
928
929 /*
930 * If we have no v4_addrs and v6 is configured
931 * We probably are using unnumbered
932 * So let's grab the loopbacks v4 address
933 * and use that as the primary address
934 */
935 if (!v4_addrs && v6_addrs) {
936 struct interface *lo_ifp;
937
938 // DBS - Come back and check here
939 if (ifp->vrf->vrf_id == VRF_DEFAULT)
940 lo_ifp = if_lookup_by_name("lo", ifp->vrf->vrf_id);
941 else
942 lo_ifp = if_lookup_by_name(ifp->vrf->name,
943 ifp->vrf->vrf_id);
944
945 if (lo_ifp && (lo_ifp != ifp))
946 return pim_find_primary_addr(lo_ifp);
947 }
948 return PIMADDR_ANY;
949 #endif
950 }
951
952 static int pim_iface_next_vif_index(struct interface *ifp)
953 {
954 struct pim_interface *pim_ifp = ifp->info;
955 struct pim_instance *pim = pim_ifp->pim;
956 int i;
957
958 /*
959 * The pimreg vif is always going to be in index 0
960 * of the table.
961 */
962 if (ifp->ifindex == PIM_OIF_PIM_REGISTER_VIF)
963 return 0;
964
965 for (i = 1; i < MAXVIFS; i++) {
966 if (pim->iface_vif_index[i] == 0)
967 return i;
968 }
969 return MAXVIFS;
970 }
971
972 /*
973 pim_if_add_vif() uses ifindex as vif_index
974
975 see also pim_if_find_vifindex_by_ifindex()
976 */
977 int pim_if_add_vif(struct interface *ifp, bool ispimreg, bool is_vxlan_term)
978 {
979 struct pim_interface *pim_ifp = ifp->info;
980 pim_addr ifaddr;
981 unsigned char flags = 0;
982
983 assert(pim_ifp);
984
985 if (pim_ifp->mroute_vif_index > 0) {
986 zlog_warn("%s: vif_index=%d > 0 on interface %s ifindex=%d",
987 __func__, pim_ifp->mroute_vif_index, ifp->name,
988 ifp->ifindex);
989 return -1;
990 }
991
992 if (ifp->ifindex < 0) {
993 zlog_warn("%s: ifindex=%d < 1 on interface %s", __func__,
994 ifp->ifindex, ifp->name);
995 return -2;
996 }
997
998 ifaddr = pim_ifp->primary_address;
999 #if PIM_IPV != 6
1000 /* IPv6 API is always by interface index */
1001 if (!ispimreg && !is_vxlan_term && pim_addr_is_any(ifaddr)) {
1002 zlog_warn(
1003 "%s: could not get address for interface %s ifindex=%d",
1004 __func__, ifp->name, ifp->ifindex);
1005 return -4;
1006 }
1007 #endif
1008
1009 pim_ifp->mroute_vif_index = pim_iface_next_vif_index(ifp);
1010
1011 if (pim_ifp->mroute_vif_index >= MAXVIFS) {
1012 zlog_warn(
1013 "%s: Attempting to configure more than MAXVIFS=%d on pim enabled interface %s",
1014 __func__, MAXVIFS, ifp->name);
1015 return -3;
1016 }
1017
1018 if (ifp->ifindex == PIM_OIF_PIM_REGISTER_VIF)
1019 flags = VIFF_REGISTER;
1020 #ifdef VIFF_USE_IFINDEX
1021 else
1022 flags = VIFF_USE_IFINDEX;
1023 #endif
1024
1025 if (pim_mroute_add_vif(ifp, ifaddr, flags)) {
1026 /* pim_mroute_add_vif reported error */
1027 return -5;
1028 }
1029
1030 pim_ifp->pim->iface_vif_index[pim_ifp->mroute_vif_index] = 1;
1031
1032 if (!ispimreg)
1033 gm_ifp_update(ifp);
1034
1035 /* if the device qualifies as pim_vxlan iif/oif update vxlan entries */
1036 pim_vxlan_add_vif(ifp);
1037 return 0;
1038 }
1039
1040 int pim_if_del_vif(struct interface *ifp)
1041 {
1042 struct pim_interface *pim_ifp = ifp->info;
1043
1044 if (pim_ifp->mroute_vif_index < 1) {
1045 zlog_warn("%s: vif_index=%d < 1 on interface %s ifindex=%d",
1046 __func__, pim_ifp->mroute_vif_index, ifp->name,
1047 ifp->ifindex);
1048 return -1;
1049 }
1050
1051 /* if the device was a pim_vxlan iif/oif update vxlan mroute entries */
1052 pim_vxlan_del_vif(ifp);
1053
1054 gm_ifp_teardown(ifp);
1055
1056 pim_mroute_del_vif(ifp);
1057
1058 /*
1059 Update vif_index
1060 */
1061 pim_ifp->pim->iface_vif_index[pim_ifp->mroute_vif_index] = 0;
1062
1063 pim_ifp->mroute_vif_index = -1;
1064 return 0;
1065 }
1066
1067 // DBS - VRF Revist
1068 struct interface *pim_if_find_by_vif_index(struct pim_instance *pim,
1069 ifindex_t vif_index)
1070 {
1071 struct interface *ifp;
1072
1073 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1074 if (ifp->info) {
1075 struct pim_interface *pim_ifp;
1076 pim_ifp = ifp->info;
1077
1078 if (vif_index == pim_ifp->mroute_vif_index)
1079 return ifp;
1080 }
1081 }
1082
1083 return 0;
1084 }
1085
1086 /*
1087 pim_if_add_vif() uses ifindex as vif_index
1088 */
1089 int pim_if_find_vifindex_by_ifindex(struct pim_instance *pim, ifindex_t ifindex)
1090 {
1091 struct pim_interface *pim_ifp;
1092 struct interface *ifp;
1093
1094 ifp = if_lookup_by_index(ifindex, pim->vrf->vrf_id);
1095 if (!ifp || !ifp->info)
1096 return -1;
1097 pim_ifp = ifp->info;
1098
1099 return pim_ifp->mroute_vif_index;
1100 }
1101
1102 int pim_if_lan_delay_enabled(struct interface *ifp)
1103 {
1104 struct pim_interface *pim_ifp;
1105
1106 pim_ifp = ifp->info;
1107 assert(pim_ifp);
1108 assert(pim_ifp->pim_number_of_nonlandelay_neighbors >= 0);
1109
1110 return pim_ifp->pim_number_of_nonlandelay_neighbors == 0;
1111 }
1112
1113 uint16_t pim_if_effective_propagation_delay_msec(struct interface *ifp)
1114 {
1115 if (pim_if_lan_delay_enabled(ifp)) {
1116 struct pim_interface *pim_ifp;
1117 pim_ifp = ifp->info;
1118 return pim_ifp->pim_neighbors_highest_propagation_delay_msec;
1119 } else {
1120 return PIM_DEFAULT_PROPAGATION_DELAY_MSEC;
1121 }
1122 }
1123
1124 uint16_t pim_if_effective_override_interval_msec(struct interface *ifp)
1125 {
1126 if (pim_if_lan_delay_enabled(ifp)) {
1127 struct pim_interface *pim_ifp;
1128 pim_ifp = ifp->info;
1129 return pim_ifp->pim_neighbors_highest_override_interval_msec;
1130 } else {
1131 return PIM_DEFAULT_OVERRIDE_INTERVAL_MSEC;
1132 }
1133 }
1134
1135 int pim_if_t_override_msec(struct interface *ifp)
1136 {
1137 int effective_override_interval_msec;
1138 int t_override_msec;
1139
1140 effective_override_interval_msec =
1141 pim_if_effective_override_interval_msec(ifp);
1142
1143 t_override_msec =
1144 frr_weak_random() % (effective_override_interval_msec + 1);
1145
1146 return t_override_msec;
1147 }
1148
1149 uint16_t pim_if_jp_override_interval_msec(struct interface *ifp)
1150 {
1151 return pim_if_effective_propagation_delay_msec(ifp)
1152 + pim_if_effective_override_interval_msec(ifp);
1153 }
1154
1155 /*
1156 RFC 4601: 4.1.6. State Summarization Macros
1157
1158 The function NBR( I, A ) uses information gathered through PIM Hello
1159 messages to map the IP address A of a directly connected PIM
1160 neighbor router on interface I to the primary IP address of the same
1161 router (Section 4.3.4). The primary IP address of a neighbor is the
1162 address that it uses as the source of its PIM Hello messages.
1163 */
1164 struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp, pim_addr addr)
1165 {
1166 struct listnode *neighnode;
1167 struct pim_neighbor *neigh;
1168 struct pim_interface *pim_ifp;
1169 struct prefix p;
1170
1171 assert(ifp);
1172
1173 pim_ifp = ifp->info;
1174 if (!pim_ifp) {
1175 zlog_warn("%s: multicast not enabled on interface %s", __func__,
1176 ifp->name);
1177 return 0;
1178 }
1179
1180 pim_addr_to_prefix(&p, addr);
1181
1182 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
1183 neigh)) {
1184
1185 /* primary address ? */
1186 if (!pim_addr_cmp(neigh->source_addr, addr))
1187 return neigh;
1188
1189 /* secondary address ? */
1190 if (pim_neighbor_find_secondary(neigh, &p))
1191 return neigh;
1192 }
1193
1194 if (PIM_DEBUG_PIM_TRACE)
1195 zlog_debug(
1196 "%s: neighbor not found for address %pPA on interface %s",
1197 __func__, &addr, ifp->name);
1198
1199 return NULL;
1200 }
1201
1202 long pim_if_t_suppressed_msec(struct interface *ifp)
1203 {
1204 struct pim_interface *pim_ifp;
1205 long t_suppressed_msec;
1206 uint32_t ramount = 0;
1207
1208 pim_ifp = ifp->info;
1209 assert(pim_ifp);
1210
1211 /* join suppression disabled ? */
1212 if (pim_ifp->pim_can_disable_join_suppression)
1213 return 0;
1214
1215 /* t_suppressed = t_periodic * rand(1.1, 1.4) */
1216 ramount = 1100 + (frr_weak_random() % (1400 - 1100 + 1));
1217 t_suppressed_msec = router->t_periodic * ramount;
1218
1219 return t_suppressed_msec;
1220 }
1221
1222 #if PIM_IPV == 4
1223 static void igmp_join_free(struct gm_join *ij)
1224 {
1225 XFREE(MTYPE_PIM_IGMP_JOIN, ij);
1226 }
1227
1228 static struct gm_join *igmp_join_find(struct list *join_list,
1229 struct in_addr group_addr,
1230 struct in_addr source_addr)
1231 {
1232 struct listnode *node;
1233 struct gm_join *ij;
1234
1235 assert(join_list);
1236
1237 for (ALL_LIST_ELEMENTS_RO(join_list, node, ij)) {
1238 if ((group_addr.s_addr == ij->group_addr.s_addr)
1239 && (source_addr.s_addr == ij->source_addr.s_addr))
1240 return ij;
1241 }
1242
1243 return 0;
1244 }
1245
1246 static int igmp_join_sock(const char *ifname, ifindex_t ifindex,
1247 struct in_addr group_addr, struct in_addr source_addr,
1248 struct pim_interface *pim_ifp)
1249 {
1250 int join_fd;
1251
1252 pim_ifp->igmp_ifstat_joins_sent++;
1253
1254 join_fd = pim_socket_raw(IPPROTO_IGMP);
1255 if (join_fd < 0) {
1256 pim_ifp->igmp_ifstat_joins_failed++;
1257 return -1;
1258 }
1259
1260 if (pim_igmp_join_source(join_fd, ifindex, group_addr, source_addr)) {
1261 char group_str[INET_ADDRSTRLEN];
1262 char source_str[INET_ADDRSTRLEN];
1263 pim_inet4_dump("<grp?>", group_addr, group_str,
1264 sizeof(group_str));
1265 pim_inet4_dump("<src?>", source_addr, source_str,
1266 sizeof(source_str));
1267 zlog_warn(
1268 "%s: setsockopt(fd=%d) failure for IGMP group %s source %s ifindex %d on interface %s: errno=%d: %s",
1269 __func__, join_fd, group_str, source_str, ifindex,
1270 ifname, errno, safe_strerror(errno));
1271
1272 pim_ifp->igmp_ifstat_joins_failed++;
1273
1274 close(join_fd);
1275 return -2;
1276 }
1277
1278 return join_fd;
1279 }
1280
1281 #if PIM_IPV == 4
1282 static struct gm_join *igmp_join_new(struct interface *ifp,
1283 struct in_addr group_addr,
1284 struct in_addr source_addr)
1285 {
1286 struct pim_interface *pim_ifp;
1287 struct gm_join *ij;
1288 int join_fd;
1289
1290 pim_ifp = ifp->info;
1291 assert(pim_ifp);
1292
1293 join_fd = igmp_join_sock(ifp->name, ifp->ifindex, group_addr,
1294 source_addr, pim_ifp);
1295 if (join_fd < 0) {
1296 char group_str[INET_ADDRSTRLEN];
1297 char source_str[INET_ADDRSTRLEN];
1298
1299 pim_inet4_dump("<grp?>", group_addr, group_str,
1300 sizeof(group_str));
1301 pim_inet4_dump("<src?>", source_addr, source_str,
1302 sizeof(source_str));
1303 zlog_warn(
1304 "%s: igmp_join_sock() failure for IGMP group %s source %s on interface %s",
1305 __func__, group_str, source_str, ifp->name);
1306 return 0;
1307 }
1308
1309 ij = XCALLOC(MTYPE_PIM_IGMP_JOIN, sizeof(*ij));
1310
1311 ij->sock_fd = join_fd;
1312 ij->group_addr = group_addr;
1313 ij->source_addr = source_addr;
1314 ij->sock_creation = pim_time_monotonic_sec();
1315
1316 listnode_add(pim_ifp->gm_join_list, ij);
1317
1318 return ij;
1319 }
1320 #endif /* PIM_IPV == 4 */
1321
1322 #if PIM_IPV == 4
1323 ferr_r pim_if_igmp_join_add(struct interface *ifp, struct in_addr group_addr,
1324 struct in_addr source_addr)
1325 {
1326 struct pim_interface *pim_ifp;
1327 struct gm_join *ij;
1328
1329 pim_ifp = ifp->info;
1330 if (!pim_ifp) {
1331 return ferr_cfg_invalid("multicast not enabled on interface %s",
1332 ifp->name);
1333 }
1334
1335 if (!pim_ifp->gm_join_list) {
1336 pim_ifp->gm_join_list = list_new();
1337 pim_ifp->gm_join_list->del = (void (*)(void *))igmp_join_free;
1338 }
1339
1340 ij = igmp_join_find(pim_ifp->gm_join_list, group_addr, source_addr);
1341
1342 /* This interface has already been configured to join this IGMP group
1343 */
1344 if (ij) {
1345 return ferr_ok();
1346 }
1347
1348 (void)igmp_join_new(ifp, group_addr, source_addr);
1349
1350 if (PIM_DEBUG_IGMP_EVENTS) {
1351 char group_str[INET_ADDRSTRLEN];
1352 char source_str[INET_ADDRSTRLEN];
1353 pim_inet4_dump("<grp?>", group_addr, group_str,
1354 sizeof(group_str));
1355 pim_inet4_dump("<src?>", source_addr, source_str,
1356 sizeof(source_str));
1357 zlog_debug(
1358 "%s: issued static igmp join for channel (S,G)=(%s,%s) on interface %s",
1359 __func__, source_str, group_str, ifp->name);
1360 }
1361
1362 return ferr_ok();
1363 }
1364 #endif /* PIM_IPV == 4 */
1365
1366 int pim_if_igmp_join_del(struct interface *ifp, struct in_addr group_addr,
1367 struct in_addr source_addr)
1368 {
1369 struct pim_interface *pim_ifp;
1370 struct gm_join *ij;
1371
1372 pim_ifp = ifp->info;
1373 if (!pim_ifp) {
1374 zlog_warn("%s: multicast not enabled on interface %s", __func__,
1375 ifp->name);
1376 return -1;
1377 }
1378
1379 if (!pim_ifp->gm_join_list) {
1380 zlog_warn("%s: no IGMP join on interface %s", __func__,
1381 ifp->name);
1382 return -2;
1383 }
1384
1385 ij = igmp_join_find(pim_ifp->gm_join_list, group_addr, source_addr);
1386 if (!ij) {
1387 char group_str[INET_ADDRSTRLEN];
1388 char source_str[INET_ADDRSTRLEN];
1389 pim_inet4_dump("<grp?>", group_addr, group_str,
1390 sizeof(group_str));
1391 pim_inet4_dump("<src?>", source_addr, source_str,
1392 sizeof(source_str));
1393 zlog_warn(
1394 "%s: could not find IGMP group %s source %s on interface %s",
1395 __func__, group_str, source_str, ifp->name);
1396 return -3;
1397 }
1398
1399 if (close(ij->sock_fd)) {
1400 char group_str[INET_ADDRSTRLEN];
1401 char source_str[INET_ADDRSTRLEN];
1402 pim_inet4_dump("<grp?>", group_addr, group_str,
1403 sizeof(group_str));
1404 pim_inet4_dump("<src?>", source_addr, source_str,
1405 sizeof(source_str));
1406 zlog_warn(
1407 "%s: failure closing sock_fd=%d for IGMP group %s source %s on interface %s: errno=%d: %s",
1408 __func__, ij->sock_fd, group_str, source_str, ifp->name,
1409 errno, safe_strerror(errno));
1410 /* warning only */
1411 }
1412 listnode_delete(pim_ifp->gm_join_list, ij);
1413 igmp_join_free(ij);
1414 if (listcount(pim_ifp->gm_join_list) < 1) {
1415 list_delete(&pim_ifp->gm_join_list);
1416 pim_ifp->gm_join_list = 0;
1417 }
1418
1419 return 0;
1420 }
1421
1422 __attribute__((unused))
1423 static void pim_if_igmp_join_del_all(struct interface *ifp)
1424 {
1425 struct pim_interface *pim_ifp;
1426 struct listnode *node;
1427 struct listnode *nextnode;
1428 struct gm_join *ij;
1429
1430 pim_ifp = ifp->info;
1431 if (!pim_ifp) {
1432 zlog_warn("%s: multicast not enabled on interface %s", __func__,
1433 ifp->name);
1434 return;
1435 }
1436
1437 if (!pim_ifp->gm_join_list)
1438 return;
1439
1440 for (ALL_LIST_ELEMENTS(pim_ifp->gm_join_list, node, nextnode, ij))
1441 pim_if_igmp_join_del(ifp, ij->group_addr, ij->source_addr);
1442 }
1443 #else /* PIM_IPV != 4 */
1444 ferr_r pim_if_igmp_join_add(struct interface *ifp, struct in_addr group_addr,
1445 struct in_addr source_addr)
1446 {
1447 return ferr_ok();
1448 }
1449
1450 int pim_if_igmp_join_del(struct interface *ifp, struct in_addr group_addr,
1451 struct in_addr source_addr)
1452 {
1453 return 0;
1454 }
1455 #endif /* PIM_IPV != 4 */
1456
1457 /*
1458 RFC 4601
1459
1460 Transitions from "I am Assert Loser" State
1461
1462 Current Winner's GenID Changes or NLT Expires
1463
1464 The Neighbor Liveness Timer associated with the current winner
1465 expires or we receive a Hello message from the current winner
1466 reporting a different GenID from the one it previously reported.
1467 This indicates that the current winner's interface or router has
1468 gone down (and may have come back up), and so we must assume it no
1469 longer knows it was the winner.
1470 */
1471 void pim_if_assert_on_neighbor_down(struct interface *ifp, pim_addr neigh_addr)
1472 {
1473 struct pim_interface *pim_ifp;
1474 struct pim_ifchannel *ch;
1475
1476 pim_ifp = ifp->info;
1477 assert(pim_ifp);
1478
1479 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1480 /* Is (S,G,I) assert loser ? */
1481 if (ch->ifassert_state != PIM_IFASSERT_I_AM_LOSER)
1482 continue;
1483 /* Dead neighbor was winner ? */
1484 if (pim_addr_cmp(ch->ifassert_winner, neigh_addr))
1485 continue;
1486
1487 assert_action_a5(ch);
1488 }
1489 }
1490
1491 void pim_if_update_join_desired(struct pim_interface *pim_ifp)
1492 {
1493 struct pim_ifchannel *ch;
1494
1495 /* clear off flag from interface's upstreams */
1496 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1497 PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED_UPDATED(
1498 ch->upstream->flags);
1499 }
1500
1501 /* scan per-interface (S,G,I) state on this I interface */
1502 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1503 struct pim_upstream *up = ch->upstream;
1504
1505 if (PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED_UPDATED(up->flags))
1506 continue;
1507
1508 /* update join_desired for the global (S,G) state */
1509 pim_upstream_update_join_desired(pim_ifp->pim, up);
1510 PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED_UPDATED(up->flags);
1511 }
1512 }
1513
1514 void pim_if_update_assert_tracking_desired(struct interface *ifp)
1515 {
1516 struct pim_interface *pim_ifp;
1517 struct pim_ifchannel *ch;
1518
1519 pim_ifp = ifp->info;
1520 if (!pim_ifp)
1521 return;
1522
1523 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1524 pim_ifchannel_update_assert_tracking_desired(ch);
1525 }
1526 }
1527
1528 /*
1529 * PIM wants to have an interface pointer for everything it does.
1530 * The pimreg is a special interface that we have that is not
1531 * quite an interface but a VIF is created for it.
1532 */
1533 void pim_if_create_pimreg(struct pim_instance *pim)
1534 {
1535 char pimreg_name[INTERFACE_NAMSIZ];
1536
1537 if (!pim->regiface) {
1538 if (pim->vrf->vrf_id == VRF_DEFAULT)
1539 strlcpy(pimreg_name, PIMREG, sizeof(pimreg_name));
1540 else
1541 snprintf(pimreg_name, sizeof(pimreg_name), PIMREG "%u",
1542 pim->vrf->data.l.table_id);
1543
1544 pim->regiface = if_get_by_name(pimreg_name, pim->vrf->vrf_id,
1545 pim->vrf->name);
1546 pim->regiface->ifindex = PIM_OIF_PIM_REGISTER_VIF;
1547
1548 pim_if_new(pim->regiface, false, false, true,
1549 false /*vxlan_term*/);
1550 /*
1551 * On vrf moves we delete the interface if there
1552 * is nothing going on with it. We cannot have
1553 * the pimregiface deleted.
1554 */
1555 pim->regiface->configured = true;
1556
1557 }
1558 }
1559
1560 struct prefix *pim_if_connected_to_source(struct interface *ifp, pim_addr src)
1561 {
1562 struct listnode *cnode;
1563 struct connected *c;
1564 struct prefix p;
1565
1566 if (!ifp)
1567 return NULL;
1568
1569 pim_addr_to_prefix(&p, src);
1570
1571 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
1572 if (c->address->family != PIM_AF)
1573 continue;
1574 if (prefix_match(c->address, &p))
1575 return c->address;
1576 if (CONNECTED_PEER(c) && prefix_match(c->destination, &p))
1577 /* this is not a typo, on PtP we need to return the
1578 * *local* address that lines up with src.
1579 */
1580 return c->address;
1581 }
1582
1583 return NULL;
1584 }
1585
1586 bool pim_if_is_vrf_device(struct interface *ifp)
1587 {
1588 if (if_is_vrf(ifp))
1589 return true;
1590
1591 return false;
1592 }
1593
1594 int pim_if_ifchannel_count(struct pim_interface *pim_ifp)
1595 {
1596 struct pim_ifchannel *ch;
1597 int count = 0;
1598
1599 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1600 count++;
1601 }
1602
1603 return count;
1604 }
1605
1606 static int pim_ifp_create(struct interface *ifp)
1607 {
1608 struct pim_instance *pim;
1609
1610 pim = ifp->vrf->info;
1611 if (PIM_DEBUG_ZEBRA) {
1612 zlog_debug(
1613 "%s: %s index %d vrf %s(%u) flags %ld metric %d mtu %d operative %d",
1614 __func__, ifp->name, ifp->ifindex, ifp->vrf->name,
1615 ifp->vrf->vrf_id, (long)ifp->flags, ifp->metric,
1616 ifp->mtu, if_is_operative(ifp));
1617 }
1618
1619 if (if_is_operative(ifp)) {
1620 struct pim_interface *pim_ifp;
1621
1622 pim_ifp = ifp->info;
1623 /*
1624 * If we have a pim_ifp already and this is an if_add
1625 * that means that we probably have a vrf move event
1626 * If that is the case, set the proper vrfness.
1627 */
1628 if (pim_ifp)
1629 pim_ifp->pim = pim;
1630 pim_if_addr_add_all(ifp);
1631
1632 /*
1633 * Due to ordering issues based upon when
1634 * a command is entered we should ensure that
1635 * the pim reg is created for this vrf if we
1636 * have configuration for it already.
1637 *
1638 * this is a no-op if it's already been done.
1639 */
1640 pim_if_create_pimreg(pim);
1641 }
1642
1643 #if PIM_IPV == 4
1644 /*
1645 * If we are a vrf device that is up, open up the pim_socket for
1646 * listening
1647 * to incoming pim messages irrelevant if the user has configured us
1648 * for pim or not.
1649 */
1650 if (pim_if_is_vrf_device(ifp)) {
1651 struct pim_interface *pim_ifp;
1652
1653 if (!ifp->info) {
1654 pim_ifp = pim_if_new(ifp, false, false, false,
1655 false /*vxlan_term*/);
1656 ifp->info = pim_ifp;
1657 }
1658
1659 pim_sock_add(ifp);
1660 }
1661
1662 if (!strncmp(ifp->name, PIM_VXLAN_TERM_DEV_NAME,
1663 sizeof(PIM_VXLAN_TERM_DEV_NAME))) {
1664 if (pim->mcast_if_count < MAXVIFS)
1665 pim_vxlan_add_term_dev(pim, ifp);
1666 else
1667 zlog_warn(
1668 "%s: Cannot enable pim on %s. MAXVIFS(%d) reached. Deleting and readding the vxlan termimation device after unconfiguring pim from other interfaces may succeed.",
1669 __func__, ifp->name, MAXVIFS);
1670 }
1671 #endif
1672
1673 return 0;
1674 }
1675
1676 static int pim_ifp_up(struct interface *ifp)
1677 {
1678 uint32_t table_id;
1679 struct pim_interface *pim_ifp;
1680 struct pim_instance *pim;
1681
1682 if (PIM_DEBUG_ZEBRA) {
1683 zlog_debug(
1684 "%s: %s index %d vrf %s(%u) flags %ld metric %d mtu %d operative %d",
1685 __func__, ifp->name, ifp->ifindex, ifp->vrf->name,
1686 ifp->vrf->vrf_id, (long)ifp->flags, ifp->metric,
1687 ifp->mtu, if_is_operative(ifp));
1688 }
1689
1690 pim = ifp->vrf->info;
1691
1692 pim_ifp = ifp->info;
1693 /*
1694 * If we have a pim_ifp already and this is an if_add
1695 * that means that we probably have a vrf move event
1696 * If that is the case, set the proper vrfness.
1697 */
1698 if (pim_ifp)
1699 pim_ifp->pim = pim;
1700
1701 /*
1702 pim_if_addr_add_all() suffices for bringing up both IGMP and
1703 PIM
1704 */
1705 pim_if_addr_add_all(ifp);
1706
1707 /*
1708 * If we have a pimreg device callback and it's for a specific
1709 * table set the master appropriately
1710 */
1711 if (sscanf(ifp->name, "" PIMREG "%" SCNu32, &table_id) == 1) {
1712 struct vrf *vrf;
1713 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1714 if ((table_id == vrf->data.l.table_id)
1715 && (ifp->vrf->vrf_id != vrf->vrf_id)) {
1716 struct interface *master = if_lookup_by_name(
1717 vrf->name, vrf->vrf_id);
1718
1719 if (!master) {
1720 zlog_debug(
1721 "%s: Unable to find Master interface for %s",
1722 __func__, vrf->name);
1723 return 0;
1724 }
1725 pim_zebra_interface_set_master(master, ifp);
1726 }
1727 }
1728 }
1729 return 0;
1730 }
1731
1732 static int pim_ifp_down(struct interface *ifp)
1733 {
1734 if (PIM_DEBUG_ZEBRA) {
1735 zlog_debug(
1736 "%s: %s index %d vrf %s(%u) flags %ld metric %d mtu %d operative %d",
1737 __func__, ifp->name, ifp->ifindex, ifp->vrf->name,
1738 ifp->vrf->vrf_id, (long)ifp->flags, ifp->metric,
1739 ifp->mtu, if_is_operative(ifp));
1740 }
1741
1742 if (!if_is_operative(ifp)) {
1743 pim_ifchannel_delete_all(ifp);
1744 /*
1745 pim_if_addr_del_all() suffices for shutting down IGMP,
1746 but not for shutting down PIM
1747 */
1748 pim_if_addr_del_all(ifp);
1749
1750 /*
1751 pim_sock_delete() closes the socket, stops read and timer
1752 threads,
1753 and kills all neighbors.
1754 */
1755 if (ifp->info) {
1756 pim_sock_delete(ifp, "link down");
1757 }
1758 }
1759
1760 if (ifp->info) {
1761 pim_if_del_vif(ifp);
1762 pim_ifstat_reset(ifp);
1763 }
1764
1765 return 0;
1766 }
1767
1768 static int pim_ifp_destroy(struct interface *ifp)
1769 {
1770 if (PIM_DEBUG_ZEBRA) {
1771 zlog_debug(
1772 "%s: %s index %d vrf %s(%u) flags %ld metric %d mtu %d operative %d",
1773 __func__, ifp->name, ifp->ifindex, ifp->vrf->name,
1774 ifp->vrf->vrf_id, (long)ifp->flags, ifp->metric,
1775 ifp->mtu, if_is_operative(ifp));
1776 }
1777
1778 if (!if_is_operative(ifp))
1779 pim_if_addr_del_all(ifp);
1780
1781 #if PIM_IPV == 4
1782 struct pim_instance *pim;
1783
1784 pim = ifp->vrf->info;
1785 if (pim && pim->vxlan.term_if == ifp)
1786 pim_vxlan_del_term_dev(pim);
1787 #endif
1788
1789 return 0;
1790 }
1791
1792 static int pim_if_new_hook(struct interface *ifp)
1793 {
1794 return 0;
1795 }
1796
1797 static int pim_if_delete_hook(struct interface *ifp)
1798 {
1799 if (ifp->info)
1800 pim_if_delete(ifp);
1801
1802 return 0;
1803 }
1804
1805 void pim_iface_init(void)
1806 {
1807 hook_register_prio(if_add, 0, pim_if_new_hook);
1808 hook_register_prio(if_del, 0, pim_if_delete_hook);
1809
1810 if_zapi_callbacks(pim_ifp_create, pim_ifp_up, pim_ifp_down,
1811 pim_ifp_destroy);
1812 }