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.
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.
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
34 #include "pim_instance.h"
35 #include "pim_zebra.h"
36 #include "pim_iface.h"
38 #include "pim_mroute.h"
42 #include "pim_neighbor.h"
43 #include "pim_ifchannel.h"
46 #include "pim_ssmpingd.h"
49 #include "pim_jp_agg.h"
50 #include "pim_igmp_join.h"
51 #include "pim_vxlan.h"
53 static void pim_if_igmp_join_del_all(struct interface
*ifp
);
54 static int igmp_join_sock(const char *ifname
, ifindex_t ifindex
,
55 struct in_addr group_addr
,
56 struct in_addr source_addr
);
58 void pim_if_init(struct pim_instance
*pim
)
62 for (i
= 0; i
< MAXVIFS
; i
++)
63 pim
->iface_vif_index
[i
] = 0;
66 void pim_if_terminate(struct pim_instance
*pim
)
68 struct interface
*ifp
;
70 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
71 struct pim_interface
*pim_ifp
= ifp
->info
;
81 static void pim_sec_addr_free(struct pim_secondary_addr
*sec_addr
)
83 XFREE(MTYPE_PIM_SEC_ADDR
, sec_addr
);
86 static int pim_sec_addr_comp(const void *p1
, const void *p2
)
88 const struct pim_secondary_addr
*sec1
= p1
;
89 const struct pim_secondary_addr
*sec2
= p2
;
91 if (sec1
->addr
.family
== AF_INET
&& sec2
->addr
.family
== AF_INET6
)
94 if (sec1
->addr
.family
== AF_INET6
&& sec2
->addr
.family
== AF_INET
)
97 if (sec1
->addr
.family
== AF_INET
) {
98 if (ntohl(sec1
->addr
.u
.prefix4
.s_addr
)
99 < ntohl(sec2
->addr
.u
.prefix4
.s_addr
))
102 if (ntohl(sec1
->addr
.u
.prefix4
.s_addr
)
103 > ntohl(sec2
->addr
.u
.prefix4
.s_addr
))
106 return memcmp(&sec1
->addr
.u
.prefix6
, &sec2
->addr
.u
.prefix6
,
107 sizeof(struct in6_addr
));
113 struct pim_interface
*pim_if_new(struct interface
*ifp
, bool igmp
, bool pim
,
114 bool ispimreg
, bool is_vxlan_term
)
116 struct pim_interface
*pim_ifp
;
121 pim_ifp
= XCALLOC(MTYPE_PIM_INTERFACE
, sizeof(*pim_ifp
));
123 pim_ifp
->options
= 0;
124 pim_ifp
->pim
= pim_get_pim_instance(ifp
->vrf_id
);
125 pim_ifp
->mroute_vif_index
= -1;
127 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
128 pim_ifp
->igmp_default_robustness_variable
=
129 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
130 pim_ifp
->igmp_default_query_interval
= IGMP_GENERAL_QUERY_INTERVAL
;
131 pim_ifp
->igmp_query_max_response_time_dsec
=
132 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
;
133 pim_ifp
->igmp_specific_query_max_response_time_dsec
=
134 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
;
135 pim_ifp
->igmp_last_member_query_count
=
136 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
;
138 /* BSM config on interface: true by default */
139 pim_ifp
->bsm_enable
= true;
140 pim_ifp
->ucast_bsm_accept
= true;
141 pim_ifp
->am_i_dr
= false;
144 RFC 3376: 8.3. Query Response Interval
145 The number of seconds represented by the [Query Response Interval]
146 must be less than the [Query Interval].
148 zassert(pim_ifp
->igmp_query_max_response_time_dsec
149 < pim_ifp
->igmp_default_query_interval
);
152 PIM_IF_DO_PIM(pim_ifp
->options
);
154 PIM_IF_DO_IGMP(pim_ifp
->options
);
156 PIM_IF_DO_IGMP_LISTEN_ALLROUTERS(pim_ifp
->options
);
158 pim_ifp
->igmp_join_list
= NULL
;
159 pim_ifp
->igmp_socket_list
= NULL
;
160 pim_ifp
->pim_neighbor_list
= NULL
;
161 pim_ifp
->upstream_switch_list
= NULL
;
162 pim_ifp
->pim_generation_id
= 0;
164 /* list of struct igmp_sock */
165 pim_ifp
->igmp_socket_list
= list_new();
166 pim_ifp
->igmp_socket_list
->del
= (void (*)(void *))igmp_sock_free
;
168 /* list of struct pim_neighbor */
169 pim_ifp
->pim_neighbor_list
= list_new();
170 pim_ifp
->pim_neighbor_list
->del
= (void (*)(void *))pim_neighbor_free
;
172 pim_ifp
->upstream_switch_list
= list_new();
173 pim_ifp
->upstream_switch_list
->del
=
174 (void (*)(void *))pim_jp_agg_group_list_free
;
175 pim_ifp
->upstream_switch_list
->cmp
= pim_jp_agg_group_list_cmp
;
177 pim_ifp
->sec_addr_list
= list_new();
178 pim_ifp
->sec_addr_list
->del
= (void (*)(void *))pim_sec_addr_free
;
179 pim_ifp
->sec_addr_list
->cmp
=
180 (int (*)(void *, void *))pim_sec_addr_comp
;
182 pim_ifp
->activeactive
= false;
184 RB_INIT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
190 pim_if_add_vif(ifp
, ispimreg
, is_vxlan_term
);
191 pim_ifp
->pim
->mcast_if_count
++;
196 void pim_if_delete(struct interface
*ifp
)
198 struct pim_interface
*pim_ifp
;
199 struct pim_ifchannel
*ch
;
205 if (pim_ifp
->igmp_join_list
) {
206 pim_if_igmp_join_del_all(ifp
);
209 pim_ifchannel_delete_all(ifp
);
210 igmp_sock_delete_all(ifp
);
212 pim_neighbor_delete_all(ifp
, "Interface removed from configuration");
215 pim_ifp
->pim
->mcast_if_count
--;
217 list_delete(&pim_ifp
->igmp_socket_list
);
218 list_delete(&pim_ifp
->pim_neighbor_list
);
219 list_delete(&pim_ifp
->upstream_switch_list
);
220 list_delete(&pim_ifp
->sec_addr_list
);
222 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
224 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
225 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
227 pim_ifchannel_delete(ch
);
230 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
);
235 void pim_if_update_could_assert(struct interface
*ifp
)
237 struct pim_interface
*pim_ifp
;
238 struct pim_ifchannel
*ch
;
243 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
244 pim_ifchannel_update_could_assert(ch
);
248 static void pim_if_update_my_assert_metric(struct interface
*ifp
)
250 struct pim_interface
*pim_ifp
;
251 struct pim_ifchannel
*ch
;
256 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
257 pim_ifchannel_update_my_assert_metric(ch
);
261 static void pim_addr_change(struct interface
*ifp
)
263 struct pim_interface
*pim_ifp
;
268 pim_if_dr_election(ifp
); /* router's own DR Priority (addr) changes --
270 pim_if_update_join_desired(pim_ifp
); /* depends on DR */
271 pim_if_update_could_assert(ifp
); /* depends on DR */
272 pim_if_update_my_assert_metric(ifp
); /* depends on could_assert */
273 pim_if_update_assert_tracking_desired(
274 ifp
); /* depends on DR, join_desired */
277 RFC 4601: 4.3.1. Sending Hello Messages
279 1) Before an interface goes down or changes primary IP address, a
280 Hello message with a zero HoldTime should be sent immediately
281 (with the old IP address if the IP address changed).
282 -- Done at the caller of the function as new ip already updated here
284 2) After an interface has changed its IP address, it MUST send a
285 Hello message with its new IP address.
288 3) If an interface changes one of its secondary IP addresses, a
289 Hello message with an updated Address_List option and a non-zero
290 HoldTime should be sent immediately.
291 -- FIXME See TODO T31
293 pim_ifp
->pim_ifstat_hello_sent
= 0; /* reset hello counter */
294 if (pim_ifp
->pim_sock_fd
< 0)
296 pim_hello_restart_now(ifp
); /* send hello and restart timer */
299 static int detect_primary_address_change(struct interface
*ifp
,
300 int force_prim_as_any
,
303 struct pim_interface
*pim_ifp
= ifp
->info
;
304 struct in_addr new_prim_addr
;
307 if (force_prim_as_any
)
308 new_prim_addr
.s_addr
= INADDR_ANY
;
310 new_prim_addr
= pim_find_primary_addr(ifp
);
312 changed
= new_prim_addr
.s_addr
!= pim_ifp
->primary_address
.s_addr
;
314 if (PIM_DEBUG_ZEBRA
) {
315 char new_prim_str
[INET_ADDRSTRLEN
];
316 char old_prim_str
[INET_ADDRSTRLEN
];
317 pim_inet4_dump("<new?>", new_prim_addr
, new_prim_str
,
318 sizeof(new_prim_str
));
319 pim_inet4_dump("<old?>", pim_ifp
->primary_address
, old_prim_str
,
320 sizeof(old_prim_str
));
321 zlog_debug("%s: old=%s new=%s on interface %s: %s", __func__
,
322 old_prim_str
, new_prim_str
, ifp
->name
,
323 changed
? "changed" : "unchanged");
327 /* Before updating pim_ifp send Hello time with 0 hold time */
328 if (PIM_IF_TEST_PIM(pim_ifp
->options
)) {
329 pim_hello_send(ifp
, 0 /* zero-sec holdtime */);
331 pim_ifp
->primary_address
= new_prim_addr
;
337 static struct pim_secondary_addr
*
338 pim_sec_addr_find(struct pim_interface
*pim_ifp
, struct prefix
*addr
)
340 struct pim_secondary_addr
*sec_addr
;
341 struct listnode
*node
;
343 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->sec_addr_list
, node
, sec_addr
)) {
344 if (prefix_cmp(&sec_addr
->addr
, addr
)) {
352 static void pim_sec_addr_del(struct pim_interface
*pim_ifp
,
353 struct pim_secondary_addr
*sec_addr
)
355 listnode_delete(pim_ifp
->sec_addr_list
, sec_addr
);
356 pim_sec_addr_free(sec_addr
);
359 static int pim_sec_addr_add(struct pim_interface
*pim_ifp
, struct prefix
*addr
)
362 struct pim_secondary_addr
*sec_addr
;
364 sec_addr
= pim_sec_addr_find(pim_ifp
, addr
);
366 sec_addr
->flags
&= ~PIM_SEC_ADDRF_STALE
;
370 sec_addr
= XCALLOC(MTYPE_PIM_SEC_ADDR
, sizeof(*sec_addr
));
373 sec_addr
->addr
= *addr
;
374 listnode_add_sort(pim_ifp
->sec_addr_list
, sec_addr
);
379 static int pim_sec_addr_del_all(struct pim_interface
*pim_ifp
)
383 if (!list_isempty(pim_ifp
->sec_addr_list
)) {
385 /* remove all nodes and free up the list itself */
386 list_delete_all_node(pim_ifp
->sec_addr_list
);
392 static int pim_sec_addr_update(struct interface
*ifp
)
394 struct pim_interface
*pim_ifp
= ifp
->info
;
395 struct connected
*ifc
;
396 struct listnode
*node
;
397 struct listnode
*nextnode
;
398 struct pim_secondary_addr
*sec_addr
;
401 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->sec_addr_list
, node
, sec_addr
)) {
402 sec_addr
->flags
|= PIM_SEC_ADDRF_STALE
;
405 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
406 struct prefix
*p
= ifc
->address
;
408 if (PIM_INADDR_IS_ANY(p
->u
.prefix4
)) {
412 if (pim_ifp
->primary_address
.s_addr
== p
->u
.prefix4
.s_addr
) {
413 /* don't add the primary address into the secondary
418 if (pim_sec_addr_add(pim_ifp
, p
)) {
423 /* Drop stale entries */
424 for (ALL_LIST_ELEMENTS(pim_ifp
->sec_addr_list
, node
, nextnode
,
426 if (sec_addr
->flags
& PIM_SEC_ADDRF_STALE
) {
427 pim_sec_addr_del(pim_ifp
, sec_addr
);
435 static int detect_secondary_address_change(struct interface
*ifp
,
436 int force_prim_as_any
,
439 struct pim_interface
*pim_ifp
= ifp
->info
;
442 if (force_prim_as_any
) {
443 /* if primary address is being forced to zero just flush the
444 * secondary address list */
445 changed
= pim_sec_addr_del_all(pim_ifp
);
447 /* re-evaluate the secondary address list */
448 changed
= pim_sec_addr_update(ifp
);
454 static void detect_address_change(struct interface
*ifp
, int force_prim_as_any
,
458 struct pim_interface
*pim_ifp
;
464 if (detect_primary_address_change(ifp
, force_prim_as_any
, caller
)) {
468 if (detect_secondary_address_change(ifp
, force_prim_as_any
, caller
)) {
474 if (!PIM_IF_TEST_PIM(pim_ifp
->options
)) {
478 pim_addr_change(ifp
);
481 /* XXX: if we have unnumbered interfaces we need to run detect address
482 * address change on all of them when the lo address changes */
485 int pim_update_source_set(struct interface
*ifp
, struct in_addr source
)
487 struct pim_interface
*pim_ifp
= ifp
->info
;
490 return PIM_IFACE_NOT_FOUND
;
493 if (pim_ifp
->update_source
.s_addr
== source
.s_addr
) {
494 return PIM_UPDATE_SOURCE_DUP
;
497 pim_ifp
->update_source
= source
;
498 detect_address_change(ifp
, 0 /* force_prim_as_any */, __func__
);
503 void pim_if_addr_add(struct connected
*ifc
)
505 struct pim_interface
*pim_ifp
;
506 struct interface
*ifp
;
507 struct in_addr ifaddr
;
518 if (!if_is_operative(ifp
))
521 if (PIM_DEBUG_ZEBRA
) {
523 prefix2str(ifc
->address
, buf
, BUFSIZ
);
524 zlog_debug("%s: %s ifindex=%d connected IP address %s %s",
525 __func__
, ifp
->name
, ifp
->ifindex
, buf
,
526 CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)
531 ifaddr
= ifc
->address
->u
.prefix4
;
533 detect_address_change(ifp
, 0, __func__
);
535 // if (ifc->address->family != AF_INET)
538 if (PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
539 struct igmp_sock
*igmp
;
541 /* lookup IGMP socket */
542 igmp
= pim_igmp_sock_lookup_ifaddr(pim_ifp
->igmp_socket_list
,
545 /* if addr new, add IGMP socket */
546 if (ifc
->address
->family
== AF_INET
)
547 pim_igmp_sock_add(pim_ifp
->igmp_socket_list
,
549 } else if (igmp
->mtrace_only
) {
550 igmp_sock_delete(igmp
);
551 pim_igmp_sock_add(pim_ifp
->igmp_socket_list
, ifaddr
,
555 /* Replay Static IGMP groups */
556 if (pim_ifp
->igmp_join_list
) {
557 struct listnode
*node
;
558 struct listnode
*nextnode
;
559 struct igmp_join
*ij
;
562 for (ALL_LIST_ELEMENTS(pim_ifp
->igmp_join_list
, node
,
564 /* Close socket and reopen with Source and Group
567 join_fd
= igmp_join_sock(
568 ifp
->name
, ifp
->ifindex
, ij
->group_addr
,
571 char group_str
[INET_ADDRSTRLEN
];
572 char source_str
[INET_ADDRSTRLEN
];
573 pim_inet4_dump("<grp?>", ij
->group_addr
,
577 "<src?>", ij
->source_addr
,
578 source_str
, sizeof(source_str
));
580 "%s: igmp_join_sock() failure for IGMP group %s source %s on interface %s",
581 __func__
, group_str
, source_str
,
585 ij
->sock_fd
= join_fd
;
590 struct igmp_sock
*igmp
;
592 /* lookup IGMP socket */
593 igmp
= pim_igmp_sock_lookup_ifaddr(pim_ifp
->igmp_socket_list
,
595 if (ifc
->address
->family
== AF_INET
) {
597 igmp_sock_delete(igmp
);
598 /* if addr new, add IGMP socket */
599 pim_igmp_sock_add(pim_ifp
->igmp_socket_list
, ifaddr
,
602 } /* igmp mtrace only */
604 if (PIM_IF_TEST_PIM(pim_ifp
->options
)) {
606 if (PIM_INADDR_ISNOT_ANY(pim_ifp
->primary_address
)) {
608 /* Interface has a valid socket ? */
609 if (pim_ifp
->pim_sock_fd
< 0) {
610 if (pim_sock_add(ifp
)) {
612 "Failure creating PIM socket for interface %s",
616 struct pim_nexthop_cache
*pnc
= NULL
;
618 struct zclient
*zclient
= NULL
;
620 zclient
= pim_zebra_zclient_get();
621 /* RP config might come prior to (local RP's interface)
623 In this case, pnc would not have pim enabled
625 Once Interface is UP and pim info is available,
627 with RNH address to receive update and add the
628 interface as nexthop. */
629 memset(&rpf
, 0, sizeof(struct pim_rpf
));
630 rpf
.rpf_addr
.family
= AF_INET
;
631 rpf
.rpf_addr
.prefixlen
= IPV4_MAX_BITLEN
;
632 rpf
.rpf_addr
.u
.prefix4
= ifc
->address
->u
.prefix4
;
633 pnc
= pim_nexthop_cache_find(pim_ifp
->pim
, &rpf
);
635 pim_sendmsg_zebra_rnh(pim_ifp
->pim
, zclient
,
637 ZEBRA_NEXTHOP_REGISTER
);
642 PIM or IGMP is enabled on interface, and there is at least one
643 address assigned, then try to create a vif_index.
645 if (pim_ifp
->mroute_vif_index
< 0) {
646 vxlan_term
= pim_vxlan_is_term_dev_cfg(pim_ifp
->pim
, ifp
);
647 pim_if_add_vif(ifp
, false, vxlan_term
);
649 pim_ifchannel_scan_forward_start(ifp
);
652 static void pim_if_addr_del_igmp(struct connected
*ifc
)
654 struct pim_interface
*pim_ifp
= ifc
->ifp
->info
;
655 struct igmp_sock
*igmp
;
656 struct in_addr ifaddr
;
658 if (ifc
->address
->family
!= AF_INET
) {
659 /* non-IPv4 address */
664 /* IGMP not enabled on interface */
668 ifaddr
= ifc
->address
->u
.prefix4
;
670 /* lookup IGMP socket */
671 igmp
= pim_igmp_sock_lookup_ifaddr(pim_ifp
->igmp_socket_list
, ifaddr
);
673 /* if addr found, del IGMP socket */
674 igmp_sock_delete(igmp
);
678 static void pim_if_addr_del_pim(struct connected
*ifc
)
680 struct pim_interface
*pim_ifp
= ifc
->ifp
->info
;
682 if (ifc
->address
->family
!= AF_INET
) {
683 /* non-IPv4 address */
688 /* PIM not enabled on interface */
692 if (PIM_INADDR_ISNOT_ANY(pim_ifp
->primary_address
)) {
693 /* Interface keeps a valid primary address */
697 if (pim_ifp
->pim_sock_fd
< 0) {
698 /* Interface does not hold a valid socket any longer */
703 pim_sock_delete() closes the socket, stops read and timer threads,
704 and kills all neighbors.
706 pim_sock_delete(ifc
->ifp
,
707 "last address has been removed from interface");
710 void pim_if_addr_del(struct connected
*ifc
, int force_prim_as_any
)
712 struct interface
*ifp
;
718 if (PIM_DEBUG_ZEBRA
) {
720 prefix2str(ifc
->address
, buf
, BUFSIZ
);
721 zlog_debug("%s: %s ifindex=%d disconnected IP address %s %s",
722 __func__
, ifp
->name
, ifp
->ifindex
, buf
,
723 CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)
728 detect_address_change(ifp
, force_prim_as_any
, __func__
);
730 pim_if_addr_del_igmp(ifc
);
731 pim_if_addr_del_pim(ifc
);
734 void pim_if_addr_add_all(struct interface
*ifp
)
736 struct connected
*ifc
;
737 struct listnode
*node
;
738 struct listnode
*nextnode
;
741 struct pim_interface
*pim_ifp
= ifp
->info
;
745 /* PIM/IGMP enabled ? */
749 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nextnode
, ifc
)) {
750 struct prefix
*p
= ifc
->address
;
752 if (p
->family
!= AF_INET
)
756 pim_if_addr_add(ifc
);
759 if (!v4_addrs
&& v6_addrs
&& !if_is_loopback(ifp
)) {
760 if (PIM_IF_TEST_PIM(pim_ifp
->options
)) {
762 /* Interface has a valid primary address ? */
763 if (PIM_INADDR_ISNOT_ANY(pim_ifp
->primary_address
)) {
765 /* Interface has a valid socket ? */
766 if (pim_ifp
->pim_sock_fd
< 0) {
767 if (pim_sock_add(ifp
)) {
769 "Failure creating PIM socket for interface %s",
777 * PIM or IGMP is enabled on interface, and there is at least one
778 * address assigned, then try to create a vif_index.
780 if (pim_ifp
->mroute_vif_index
< 0) {
781 vxlan_term
= pim_vxlan_is_term_dev_cfg(pim_ifp
->pim
, ifp
);
782 pim_if_add_vif(ifp
, false, vxlan_term
);
784 pim_ifchannel_scan_forward_start(ifp
);
786 pim_rp_setup(pim_ifp
->pim
);
787 pim_rp_check_on_if_add(pim_ifp
);
790 void pim_if_addr_del_all(struct interface
*ifp
)
792 struct connected
*ifc
;
793 struct listnode
*node
;
794 struct listnode
*nextnode
;
795 struct vrf
*vrf
= vrf_lookup_by_id(ifp
->vrf_id
);
796 struct pim_instance
*pim
;
802 /* PIM/IGMP enabled ? */
806 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nextnode
, ifc
)) {
807 struct prefix
*p
= ifc
->address
;
809 if (p
->family
!= AF_INET
)
812 pim_if_addr_del(ifc
, 1 /* force_prim_as_any=true */);
816 pim_i_am_rp_re_evaluate(pim
);
819 void pim_if_addr_del_all_igmp(struct interface
*ifp
)
821 struct connected
*ifc
;
822 struct listnode
*node
;
823 struct listnode
*nextnode
;
825 /* PIM/IGMP enabled ? */
829 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nextnode
, ifc
)) {
830 struct prefix
*p
= ifc
->address
;
832 if (p
->family
!= AF_INET
)
835 pim_if_addr_del_igmp(ifc
);
839 void pim_if_addr_del_all_pim(struct interface
*ifp
)
841 struct connected
*ifc
;
842 struct listnode
*node
;
843 struct listnode
*nextnode
;
845 /* PIM/IGMP enabled ? */
849 for (ALL_LIST_ELEMENTS(ifp
->connected
, node
, nextnode
, ifc
)) {
850 struct prefix
*p
= ifc
->address
;
852 if (p
->family
!= AF_INET
)
855 pim_if_addr_del_pim(ifc
);
859 struct in_addr
pim_find_primary_addr(struct interface
*ifp
)
861 struct connected
*ifc
;
862 struct listnode
*node
;
863 struct in_addr addr
= {0};
866 struct pim_interface
*pim_ifp
= ifp
->info
;
867 struct vrf
*vrf
= vrf_lookup_by_id(ifp
->vrf_id
);
872 if (pim_ifp
&& PIM_INADDR_ISNOT_ANY(pim_ifp
->update_source
)) {
873 return pim_ifp
->update_source
;
876 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
877 struct prefix
*p
= ifc
->address
;
879 if (p
->family
!= AF_INET
) {
884 if (PIM_INADDR_IS_ANY(p
->u
.prefix4
)) {
886 "%s: null IPv4 address connected to interface %s",
887 __func__
, ifp
->name
);
893 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
))
900 * If we have no v4_addrs and v6 is configured
901 * We probably are using unnumbered
902 * So let's grab the loopbacks v4 address
903 * and use that as the primary address
905 if (!v4_addrs
&& v6_addrs
) {
906 struct interface
*lo_ifp
;
908 // DBS - Come back and check here
909 if (ifp
->vrf_id
== VRF_DEFAULT
)
910 lo_ifp
= if_lookup_by_name("lo", vrf
->vrf_id
);
912 lo_ifp
= if_lookup_by_name(vrf
->name
, vrf
->vrf_id
);
914 if (lo_ifp
&& (lo_ifp
!= ifp
))
915 return pim_find_primary_addr(lo_ifp
);
918 addr
.s_addr
= PIM_NET_INADDR_ANY
;
923 static int pim_iface_next_vif_index(struct interface
*ifp
)
925 struct pim_interface
*pim_ifp
= ifp
->info
;
926 struct pim_instance
*pim
= pim_ifp
->pim
;
930 * The pimreg vif is always going to be in index 0
933 if (ifp
->ifindex
== PIM_OIF_PIM_REGISTER_VIF
)
936 for (i
= 1; i
< MAXVIFS
; i
++) {
937 if (pim
->iface_vif_index
[i
] == 0)
944 pim_if_add_vif() uses ifindex as vif_index
946 see also pim_if_find_vifindex_by_ifindex()
948 int pim_if_add_vif(struct interface
*ifp
, bool ispimreg
, bool is_vxlan_term
)
950 struct pim_interface
*pim_ifp
= ifp
->info
;
951 struct in_addr ifaddr
;
952 unsigned char flags
= 0;
956 if (pim_ifp
->mroute_vif_index
> 0) {
957 zlog_warn("%s: vif_index=%d > 0 on interface %s ifindex=%d",
958 __func__
, pim_ifp
->mroute_vif_index
, ifp
->name
,
963 if (ifp
->ifindex
< 0) {
964 zlog_warn("%s: ifindex=%d < 1 on interface %s", __func__
,
965 ifp
->ifindex
, ifp
->name
);
969 ifaddr
= pim_ifp
->primary_address
;
970 if (!ispimreg
&& !is_vxlan_term
&& PIM_INADDR_IS_ANY(ifaddr
)) {
972 "%s: could not get address for interface %s ifindex=%d",
973 __func__
, ifp
->name
, ifp
->ifindex
);
977 pim_ifp
->mroute_vif_index
= pim_iface_next_vif_index(ifp
);
979 if (pim_ifp
->mroute_vif_index
>= MAXVIFS
) {
981 "%s: Attempting to configure more than MAXVIFS=%d on pim enabled interface %s",
982 __func__
, MAXVIFS
, ifp
->name
);
986 if (ifp
->ifindex
== PIM_OIF_PIM_REGISTER_VIF
)
987 flags
= VIFF_REGISTER
;
988 #ifdef VIFF_USE_IFINDEX
990 flags
= VIFF_USE_IFINDEX
;
993 if (pim_mroute_add_vif(ifp
, ifaddr
, flags
)) {
994 /* pim_mroute_add_vif reported error */
998 pim_ifp
->pim
->iface_vif_index
[pim_ifp
->mroute_vif_index
] = 1;
1000 /* if the device qualifies as pim_vxlan iif/oif update vxlan entries */
1001 pim_vxlan_add_vif(ifp
);
1006 int pim_if_del_vif(struct interface
*ifp
)
1008 struct pim_interface
*pim_ifp
= ifp
->info
;
1010 if (pim_ifp
->mroute_vif_index
< 1) {
1011 zlog_warn("%s: vif_index=%d < 1 on interface %s ifindex=%d",
1012 __func__
, pim_ifp
->mroute_vif_index
, ifp
->name
,
1017 /* if the device was a pim_vxlan iif/oif update vxlan mroute entries */
1018 pim_vxlan_del_vif(ifp
);
1020 pim_mroute_del_vif(ifp
);
1025 pim_ifp
->pim
->iface_vif_index
[pim_ifp
->mroute_vif_index
] = 0;
1027 pim_ifp
->mroute_vif_index
= -1;
1033 struct interface
*pim_if_find_by_vif_index(struct pim_instance
*pim
,
1034 ifindex_t vif_index
)
1036 struct interface
*ifp
;
1038 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1040 struct pim_interface
*pim_ifp
;
1041 pim_ifp
= ifp
->info
;
1043 if (vif_index
== pim_ifp
->mroute_vif_index
)
1052 pim_if_add_vif() uses ifindex as vif_index
1054 int pim_if_find_vifindex_by_ifindex(struct pim_instance
*pim
, ifindex_t ifindex
)
1056 struct pim_interface
*pim_ifp
;
1057 struct interface
*ifp
;
1059 ifp
= if_lookup_by_index(ifindex
, pim
->vrf_id
);
1060 if (!ifp
|| !ifp
->info
)
1062 pim_ifp
= ifp
->info
;
1064 return pim_ifp
->mroute_vif_index
;
1067 int pim_if_lan_delay_enabled(struct interface
*ifp
)
1069 struct pim_interface
*pim_ifp
;
1071 pim_ifp
= ifp
->info
;
1073 zassert(pim_ifp
->pim_number_of_nonlandelay_neighbors
>= 0);
1075 return pim_ifp
->pim_number_of_nonlandelay_neighbors
== 0;
1078 uint16_t pim_if_effective_propagation_delay_msec(struct interface
*ifp
)
1080 if (pim_if_lan_delay_enabled(ifp
)) {
1081 struct pim_interface
*pim_ifp
;
1082 pim_ifp
= ifp
->info
;
1083 return pim_ifp
->pim_neighbors_highest_propagation_delay_msec
;
1085 return PIM_DEFAULT_PROPAGATION_DELAY_MSEC
;
1089 uint16_t pim_if_effective_override_interval_msec(struct interface
*ifp
)
1091 if (pim_if_lan_delay_enabled(ifp
)) {
1092 struct pim_interface
*pim_ifp
;
1093 pim_ifp
= ifp
->info
;
1094 return pim_ifp
->pim_neighbors_highest_override_interval_msec
;
1096 return PIM_DEFAULT_OVERRIDE_INTERVAL_MSEC
;
1100 int pim_if_t_override_msec(struct interface
*ifp
)
1102 int effective_override_interval_msec
;
1103 int t_override_msec
;
1105 effective_override_interval_msec
=
1106 pim_if_effective_override_interval_msec(ifp
);
1109 frr_weak_random() % (effective_override_interval_msec
+ 1);
1111 return t_override_msec
;
1114 uint16_t pim_if_jp_override_interval_msec(struct interface
*ifp
)
1116 return pim_if_effective_propagation_delay_msec(ifp
)
1117 + pim_if_effective_override_interval_msec(ifp
);
1121 RFC 4601: 4.1.6. State Summarization Macros
1123 The function NBR( I, A ) uses information gathered through PIM Hello
1124 messages to map the IP address A of a directly connected PIM
1125 neighbor router on interface I to the primary IP address of the same
1126 router (Section 4.3.4). The primary IP address of a neighbor is the
1127 address that it uses as the source of its PIM Hello messages.
1129 struct pim_neighbor
*pim_if_find_neighbor(struct interface
*ifp
,
1130 struct in_addr addr
)
1132 struct listnode
*neighnode
;
1133 struct pim_neighbor
*neigh
;
1134 struct pim_interface
*pim_ifp
;
1139 pim_ifp
= ifp
->info
;
1141 zlog_warn("%s: multicast not enabled on interface %s", __func__
,
1148 p
.prefixlen
= IPV4_MAX_PREFIXLEN
;
1150 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1153 /* primary address ? */
1154 if (neigh
->source_addr
.s_addr
== addr
.s_addr
)
1157 /* secondary address ? */
1158 if (pim_neighbor_find_secondary(neigh
, &p
))
1162 if (PIM_DEBUG_PIM_TRACE
) {
1163 char addr_str
[INET_ADDRSTRLEN
];
1164 pim_inet4_dump("<addr?>", addr
, addr_str
, sizeof(addr_str
));
1166 "%s: neighbor not found for address %s on interface %s",
1167 __func__
, addr_str
, ifp
->name
);
1173 long pim_if_t_suppressed_msec(struct interface
*ifp
)
1175 struct pim_interface
*pim_ifp
;
1176 long t_suppressed_msec
;
1177 uint32_t ramount
= 0;
1179 pim_ifp
= ifp
->info
;
1182 /* join suppression disabled ? */
1183 if (PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp
->options
))
1186 /* t_suppressed = t_periodic * rand(1.1, 1.4) */
1187 ramount
= 1100 + (frr_weak_random() % (1400 - 1100 + 1));
1188 t_suppressed_msec
= router
->t_periodic
* ramount
;
1190 return t_suppressed_msec
;
1193 static void igmp_join_free(struct igmp_join
*ij
)
1195 XFREE(MTYPE_PIM_IGMP_JOIN
, ij
);
1198 static struct igmp_join
*igmp_join_find(struct list
*join_list
,
1199 struct in_addr group_addr
,
1200 struct in_addr source_addr
)
1202 struct listnode
*node
;
1203 struct igmp_join
*ij
;
1207 for (ALL_LIST_ELEMENTS_RO(join_list
, node
, ij
)) {
1208 if ((group_addr
.s_addr
== ij
->group_addr
.s_addr
)
1209 && (source_addr
.s_addr
== ij
->source_addr
.s_addr
))
1216 static int igmp_join_sock(const char *ifname
, ifindex_t ifindex
,
1217 struct in_addr group_addr
, struct in_addr source_addr
)
1221 join_fd
= pim_socket_raw(IPPROTO_IGMP
);
1226 if (pim_igmp_join_source(join_fd
, ifindex
, group_addr
, source_addr
)) {
1227 char group_str
[INET_ADDRSTRLEN
];
1228 char source_str
[INET_ADDRSTRLEN
];
1229 pim_inet4_dump("<grp?>", group_addr
, group_str
,
1231 pim_inet4_dump("<src?>", source_addr
, source_str
,
1232 sizeof(source_str
));
1234 "%s: setsockopt(fd=%d) failure for IGMP group %s source %s ifindex %d on interface %s: errno=%d: %s",
1235 __func__
, join_fd
, group_str
, source_str
, ifindex
,
1236 ifname
, errno
, safe_strerror(errno
));
1245 static struct igmp_join
*igmp_join_new(struct interface
*ifp
,
1246 struct in_addr group_addr
,
1247 struct in_addr source_addr
)
1249 struct pim_interface
*pim_ifp
;
1250 struct igmp_join
*ij
;
1253 pim_ifp
= ifp
->info
;
1256 join_fd
= igmp_join_sock(ifp
->name
, ifp
->ifindex
, group_addr
,
1259 char group_str
[INET_ADDRSTRLEN
];
1260 char source_str
[INET_ADDRSTRLEN
];
1262 pim_inet4_dump("<grp?>", group_addr
, group_str
,
1264 pim_inet4_dump("<src?>", source_addr
, source_str
,
1265 sizeof(source_str
));
1267 "%s: igmp_join_sock() failure for IGMP group %s source %s on interface %s",
1268 __func__
, group_str
, source_str
, ifp
->name
);
1272 ij
= XCALLOC(MTYPE_PIM_IGMP_JOIN
, sizeof(*ij
));
1274 ij
->sock_fd
= join_fd
;
1275 ij
->group_addr
= group_addr
;
1276 ij
->source_addr
= source_addr
;
1277 ij
->sock_creation
= pim_time_monotonic_sec();
1279 listnode_add(pim_ifp
->igmp_join_list
, ij
);
1284 ferr_r
pim_if_igmp_join_add(struct interface
*ifp
, struct in_addr group_addr
,
1285 struct in_addr source_addr
)
1287 struct pim_interface
*pim_ifp
;
1288 struct igmp_join
*ij
;
1290 pim_ifp
= ifp
->info
;
1292 return ferr_cfg_invalid("multicast not enabled on interface %s",
1296 if (!pim_ifp
->igmp_join_list
) {
1297 pim_ifp
->igmp_join_list
= list_new();
1298 pim_ifp
->igmp_join_list
->del
= (void (*)(void *))igmp_join_free
;
1301 ij
= igmp_join_find(pim_ifp
->igmp_join_list
, group_addr
, source_addr
);
1303 /* This interface has already been configured to join this IGMP group
1309 (void)igmp_join_new(ifp
, group_addr
, source_addr
);
1311 if (PIM_DEBUG_IGMP_EVENTS
) {
1312 char group_str
[INET_ADDRSTRLEN
];
1313 char source_str
[INET_ADDRSTRLEN
];
1314 pim_inet4_dump("<grp?>", group_addr
, group_str
,
1316 pim_inet4_dump("<src?>", source_addr
, source_str
,
1317 sizeof(source_str
));
1319 "%s: issued static igmp join for channel (S,G)=(%s,%s) on interface %s",
1320 __func__
, source_str
, group_str
, ifp
->name
);
1327 int pim_if_igmp_join_del(struct interface
*ifp
, struct in_addr group_addr
,
1328 struct in_addr source_addr
)
1330 struct pim_interface
*pim_ifp
;
1331 struct igmp_join
*ij
;
1333 pim_ifp
= ifp
->info
;
1335 zlog_warn("%s: multicast not enabled on interface %s", __func__
,
1340 if (!pim_ifp
->igmp_join_list
) {
1341 zlog_warn("%s: no IGMP join on interface %s", __func__
,
1346 ij
= igmp_join_find(pim_ifp
->igmp_join_list
, group_addr
, source_addr
);
1348 char group_str
[INET_ADDRSTRLEN
];
1349 char source_str
[INET_ADDRSTRLEN
];
1350 pim_inet4_dump("<grp?>", group_addr
, group_str
,
1352 pim_inet4_dump("<src?>", source_addr
, source_str
,
1353 sizeof(source_str
));
1355 "%s: could not find IGMP group %s source %s on interface %s",
1356 __func__
, group_str
, source_str
, ifp
->name
);
1360 if (close(ij
->sock_fd
)) {
1361 char group_str
[INET_ADDRSTRLEN
];
1362 char source_str
[INET_ADDRSTRLEN
];
1363 pim_inet4_dump("<grp?>", group_addr
, group_str
,
1365 pim_inet4_dump("<src?>", source_addr
, source_str
,
1366 sizeof(source_str
));
1368 "%s: failure closing sock_fd=%d for IGMP group %s source %s on interface %s: errno=%d: %s",
1369 __func__
, ij
->sock_fd
, group_str
, source_str
, ifp
->name
,
1370 errno
, safe_strerror(errno
));
1373 listnode_delete(pim_ifp
->igmp_join_list
, ij
);
1375 if (listcount(pim_ifp
->igmp_join_list
) < 1) {
1376 list_delete(&pim_ifp
->igmp_join_list
);
1377 pim_ifp
->igmp_join_list
= 0;
1383 static void pim_if_igmp_join_del_all(struct interface
*ifp
)
1385 struct pim_interface
*pim_ifp
;
1386 struct listnode
*node
;
1387 struct listnode
*nextnode
;
1388 struct igmp_join
*ij
;
1390 pim_ifp
= ifp
->info
;
1392 zlog_warn("%s: multicast not enabled on interface %s", __func__
,
1397 if (!pim_ifp
->igmp_join_list
)
1400 for (ALL_LIST_ELEMENTS(pim_ifp
->igmp_join_list
, node
, nextnode
, ij
))
1401 pim_if_igmp_join_del(ifp
, ij
->group_addr
, ij
->source_addr
);
1407 Transitions from "I am Assert Loser" State
1409 Current Winner's GenID Changes or NLT Expires
1411 The Neighbor Liveness Timer associated with the current winner
1412 expires or we receive a Hello message from the current winner
1413 reporting a different GenID from the one it previously reported.
1414 This indicates that the current winner's interface or router has
1415 gone down (and may have come back up), and so we must assume it no
1416 longer knows it was the winner.
1418 void pim_if_assert_on_neighbor_down(struct interface
*ifp
,
1419 struct in_addr neigh_addr
)
1421 struct pim_interface
*pim_ifp
;
1422 struct pim_ifchannel
*ch
;
1424 pim_ifp
= ifp
->info
;
1427 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1428 /* Is (S,G,I) assert loser ? */
1429 if (ch
->ifassert_state
!= PIM_IFASSERT_I_AM_LOSER
)
1431 /* Dead neighbor was winner ? */
1432 if (ch
->ifassert_winner
.s_addr
!= neigh_addr
.s_addr
)
1435 assert_action_a5(ch
);
1439 void pim_if_update_join_desired(struct pim_interface
*pim_ifp
)
1441 struct pim_ifchannel
*ch
;
1443 /* clear off flag from interface's upstreams */
1444 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1445 PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED_UPDATED(
1446 ch
->upstream
->flags
);
1449 /* scan per-interface (S,G,I) state on this I interface */
1450 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1451 struct pim_upstream
*up
= ch
->upstream
;
1453 if (PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED_UPDATED(up
->flags
))
1456 /* update join_desired for the global (S,G) state */
1457 pim_upstream_update_join_desired(pim_ifp
->pim
, up
);
1458 PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED_UPDATED(up
->flags
);
1462 void pim_if_update_assert_tracking_desired(struct interface
*ifp
)
1464 struct pim_interface
*pim_ifp
;
1465 struct pim_ifchannel
*ch
;
1467 pim_ifp
= ifp
->info
;
1471 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1472 pim_ifchannel_update_assert_tracking_desired(ch
);
1477 * PIM wants to have an interface pointer for everything it does.
1478 * The pimreg is a special interface that we have that is not
1479 * quite an inteface but a VIF is created for it.
1481 void pim_if_create_pimreg(struct pim_instance
*pim
)
1483 char pimreg_name
[INTERFACE_NAMSIZ
];
1485 if (!pim
->regiface
) {
1486 if (pim
->vrf_id
== VRF_DEFAULT
)
1487 strlcpy(pimreg_name
, "pimreg", sizeof(pimreg_name
));
1489 snprintf(pimreg_name
, sizeof(pimreg_name
), "pimreg%u",
1490 pim
->vrf
->data
.l
.table_id
);
1492 pim
->regiface
= if_create_name(pimreg_name
, pim
->vrf_id
);
1493 pim
->regiface
->ifindex
= PIM_OIF_PIM_REGISTER_VIF
;
1495 pim_if_new(pim
->regiface
, false, false, true,
1496 false /*vxlan_term*/);
1498 * On vrf moves we delete the interface if there
1499 * is nothing going on with it. We cannot have
1500 * the pimregiface deleted.
1502 pim
->regiface
->configured
= true;
1507 int pim_if_connected_to_source(struct interface
*ifp
, struct in_addr src
)
1509 struct listnode
*cnode
;
1510 struct connected
*c
;
1518 p
.prefixlen
= IPV4_MAX_BITLEN
;
1520 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, cnode
, c
)) {
1521 if ((c
->address
->family
== AF_INET
)
1522 && prefix_match(CONNECTED_PREFIX(c
), &p
)) {
1530 bool pim_if_is_vrf_device(struct interface
*ifp
)
1538 int pim_if_ifchannel_count(struct pim_interface
*pim_ifp
)
1540 struct pim_ifchannel
*ch
;
1543 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1550 int pim_ifp_create(struct interface
*ifp
)
1552 struct pim_instance
*pim
;
1554 pim
= pim_get_pim_instance(ifp
->vrf_id
);
1555 if (PIM_DEBUG_ZEBRA
) {
1557 "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
1558 __func__
, ifp
->name
, ifp
->ifindex
, ifp
->vrf_id
,
1559 (long)ifp
->flags
, ifp
->metric
, ifp
->mtu
,
1560 if_is_operative(ifp
));
1563 if (if_is_operative(ifp
)) {
1564 struct pim_interface
*pim_ifp
;
1566 pim_ifp
= ifp
->info
;
1568 * If we have a pim_ifp already and this is an if_add
1569 * that means that we probably have a vrf move event
1570 * If that is the case, set the proper vrfness.
1574 pim_if_addr_add_all(ifp
);
1578 * If we are a vrf device that is up, open up the pim_socket for
1580 * to incoming pim messages irrelevant if the user has configured us
1583 if (pim_if_is_vrf_device(ifp
)) {
1584 struct pim_interface
*pim_ifp
;
1587 pim_ifp
= pim_if_new(ifp
, false, false, false,
1588 false /*vxlan_term*/);
1589 ifp
->info
= pim_ifp
;
1595 if (!strncmp(ifp
->name
, PIM_VXLAN_TERM_DEV_NAME
,
1596 sizeof(PIM_VXLAN_TERM_DEV_NAME
))) {
1597 if (pim
->mcast_if_count
< MAXVIFS
)
1598 pim_vxlan_add_term_dev(pim
, ifp
);
1601 "%s: Cannot enable pim on %s. MAXVIFS(%d) reached. Deleting and readding the vxlan termimation device after unconfiguring pim from other interfaces may succeed.",
1602 __func__
, ifp
->name
, MAXVIFS
);
1608 int pim_ifp_up(struct interface
*ifp
)
1610 struct pim_interface
*pim_ifp
;
1611 struct pim_instance
*pim
;
1614 if (PIM_DEBUG_ZEBRA
) {
1616 "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
1617 __func__
, ifp
->name
, ifp
->ifindex
, ifp
->vrf_id
,
1618 (long)ifp
->flags
, ifp
->metric
, ifp
->mtu
,
1619 if_is_operative(ifp
));
1622 pim
= pim_get_pim_instance(ifp
->vrf_id
);
1624 pim_ifp
= ifp
->info
;
1626 * If we have a pim_ifp already and this is an if_add
1627 * that means that we probably have a vrf move event
1628 * If that is the case, set the proper vrfness.
1634 pim_if_addr_add_all() suffices for bringing up both IGMP and
1637 pim_if_addr_add_all(ifp
);
1640 * If we have a pimreg device callback and it's for a specific
1641 * table set the master appropriately
1643 if (sscanf(ifp
->name
, "pimreg%" SCNu32
, &table_id
) == 1) {
1645 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1646 if ((table_id
== vrf
->data
.l
.table_id
)
1647 && (ifp
->vrf_id
!= vrf
->vrf_id
)) {
1648 struct interface
*master
= if_lookup_by_name(
1649 vrf
->name
, vrf
->vrf_id
);
1653 "%s: Unable to find Master interface for %s",
1654 __func__
, vrf
->name
);
1657 pim_zebra_interface_set_master(master
, ifp
);
1664 int pim_ifp_down(struct interface
*ifp
)
1666 if (PIM_DEBUG_ZEBRA
) {
1668 "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
1669 __func__
, ifp
->name
, ifp
->ifindex
, ifp
->vrf_id
,
1670 (long)ifp
->flags
, ifp
->metric
, ifp
->mtu
,
1671 if_is_operative(ifp
));
1674 if (!if_is_operative(ifp
)) {
1675 pim_ifchannel_delete_all(ifp
);
1677 pim_if_addr_del_all() suffices for shutting down IGMP,
1678 but not for shutting down PIM
1680 pim_if_addr_del_all(ifp
);
1683 pim_sock_delete() closes the socket, stops read and timer
1685 and kills all neighbors.
1688 pim_sock_delete(ifp
, "link down");
1693 pim_if_del_vif(ifp
);
1698 int pim_ifp_destroy(struct interface
*ifp
)
1700 struct pim_instance
*pim
;
1702 if (PIM_DEBUG_ZEBRA
) {
1704 "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
1705 __func__
, ifp
->name
, ifp
->ifindex
, ifp
->vrf_id
,
1706 (long)ifp
->flags
, ifp
->metric
, ifp
->mtu
,
1707 if_is_operative(ifp
));
1710 if (!if_is_operative(ifp
))
1711 pim_if_addr_del_all(ifp
);
1713 pim
= pim_get_pim_instance(ifp
->vrf_id
);
1714 if (pim
&& pim
->vxlan
.term_if
== ifp
)
1715 pim_vxlan_del_term_dev(pim
);