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