3 * Copyright (C) 2008 Everton da Silva Marques
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "pim_zebra.h"
35 #include "pim_iface.h"
41 #include "pim_zlookup.h"
42 #include "pim_ifchannel.h"
44 #include "pim_igmpv3.h"
45 #include "pim_jp_agg.h"
48 #include "pim_vxlan.h"
51 #undef PIM_DEBUG_IFADDR_DUMP
52 #define PIM_DEBUG_IFADDR_DUMP
54 struct zclient
*zclient
;
57 /* Router-id update message from zebra. */
58 static int pim_router_id_update_zebra(ZAPI_CALLBACK_ARGS
)
60 struct prefix router_id
;
62 zebra_router_id_update_read(zclient
->ibuf
, &router_id
);
67 static int pim_zebra_interface_vrf_update(ZAPI_CALLBACK_ARGS
)
69 struct interface
*ifp
;
72 ifp
= zebra_interface_vrf_update_read(zclient
->ibuf
, vrf_id
,
78 zlog_debug("%s: %s updating from %u to %u", __func__
, ifp
->name
,
81 if_update_to_new_vrf(ifp
, new_vrf_id
);
86 #ifdef PIM_DEBUG_IFADDR_DUMP
87 static void dump_if_address(struct interface
*ifp
)
89 struct connected
*ifc
;
90 struct listnode
*node
;
92 zlog_debug("%s %s: interface %s addresses:", __FILE__
, __func__
,
95 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
96 struct prefix
*p
= ifc
->address
;
98 if (p
->family
!= AF_INET
)
101 zlog_debug("%s %s: interface %s address %pI4 %s", __FILE__
,
102 __func__
, ifp
->name
, &p
->u
.prefix4
,
103 CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_SECONDARY
)
110 static int pim_zebra_if_address_add(ZAPI_CALLBACK_ARGS
)
114 struct pim_interface
*pim_ifp
;
117 zebra api notifies address adds/dels events by using the same call
118 interface_add_read below, see comments in lib/zclient.c
120 zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...)
121 will add address to interface list by calling
122 connected_add_by_prefix()
124 c
= zebra_interface_address_read(cmd
, zclient
->ibuf
, vrf_id
);
128 pim_ifp
= c
->ifp
->info
;
131 if (PIM_DEBUG_ZEBRA
) {
132 zlog_debug("%s: %s(%u) connected IP address %pFX flags %u %s",
133 __func__
, c
->ifp
->name
, vrf_id
, p
, c
->flags
,
134 CHECK_FLAG(c
->flags
, ZEBRA_IFA_SECONDARY
)
138 #ifdef PIM_DEBUG_IFADDR_DUMP
139 dump_if_address(c
->ifp
);
144 if (p
->family
!= PIM_AF
)
145 SET_FLAG(c
->flags
, ZEBRA_IFA_SECONDARY
);
146 else if (!CHECK_FLAG(c
->flags
, ZEBRA_IFA_SECONDARY
)) {
147 /* trying to add primary address? */
148 pim_addr primary_addr
= pim_find_primary_addr(c
->ifp
);
149 pim_addr addr
= pim_addr_from_prefix(p
);
151 if (pim_addr_cmp(primary_addr
, addr
)) {
154 "%s: %s : forcing secondary flag on %pFX",
155 __func__
, c
->ifp
->name
, p
);
156 SET_FLAG(c
->flags
, ZEBRA_IFA_SECONDARY
);
159 #else /* PIM_IPV != 4 */
160 if (p
->family
!= PIM_AF
)
166 struct pim_instance
*pim
;
168 pim
= pim_get_pim_instance(vrf_id
);
171 pim_rp_check_on_if_add(pim_ifp
);
174 if (if_is_loopback(c
->ifp
)) {
175 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
176 struct interface
*ifp
;
178 FOR_ALL_INTERFACES (vrf
, ifp
) {
179 if (!if_is_loopback(ifp
) && if_is_operative(ifp
))
180 pim_if_addr_add_all(ifp
);
186 static int pim_zebra_if_address_del(ZAPI_CALLBACK_ARGS
)
190 struct vrf
*vrf
= vrf_lookup_by_id(vrf_id
);
196 zebra api notifies address adds/dels events by using the same call
197 interface_add_read below, see comments in lib/zclient.c
199 zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...)
200 will remove address from interface list by calling
201 connected_delete_by_prefix()
203 c
= zebra_interface_address_read(cmd
, zclient
->ibuf
, vrf_id
);
209 if (PIM_DEBUG_ZEBRA
) {
211 "%s: %s(%u) disconnected IP address %pFX flags %u %s",
212 __func__
, c
->ifp
->name
, vrf_id
, p
, c
->flags
,
213 CHECK_FLAG(c
->flags
, ZEBRA_IFA_SECONDARY
)
216 #ifdef PIM_DEBUG_IFADDR_DUMP
217 dump_if_address(c
->ifp
);
221 if (p
->family
== PIM_AF
) {
222 struct pim_instance
*pim
;
225 pim_if_addr_del(c
, 0);
227 pim_i_am_rp_re_evaluate(pim
);
234 void pim_zebra_update_all_interfaces(struct pim_instance
*pim
)
236 struct interface
*ifp
;
238 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
239 struct pim_interface
*pim_ifp
= ifp
->info
;
240 struct pim_iface_upstream_switch
*us
;
241 struct listnode
*node
;
246 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->upstream_switch_list
, node
,
250 rpf
.source_nexthop
.interface
= ifp
;
251 pim_addr_to_prefix(&rpf
.rpf_addr
, us
->address
);
252 pim_joinprune_send(&rpf
, us
->us
);
253 pim_jp_agg_clear_group(us
->us
);
258 void pim_zebra_upstream_rpf_changed(struct pim_instance
*pim
,
259 struct pim_upstream
*up
,
262 if (old
->source_nexthop
.interface
) {
263 struct pim_neighbor
*nbr
;
265 nbr
= pim_neighbor_find_prefix(old
->source_nexthop
.interface
,
268 pim_jp_agg_remove_group(nbr
->upstream_jp_agg
, up
, nbr
);
271 * We have detected a case where we might need
272 * to rescan the inherited o_list so do it.
274 if (up
->channel_oil
->oil_inherited_rescan
) {
275 pim_upstream_inherited_olist_decide(pim
, up
);
276 up
->channel_oil
->oil_inherited_rescan
= 0;
279 if (up
->join_state
== PIM_UPSTREAM_JOINED
) {
281 * If we come up real fast we can be here
282 * where the mroute has not been installed
285 if (!up
->channel_oil
->installed
)
286 pim_upstream_mroute_add(up
->channel_oil
,
290 * RFC 4601: 4.5.7. Sending (S,G)
291 * Join/Prune Messages
293 * Transitions from Joined State
295 * RPF'(S,G) changes not due to an Assert
297 * The upstream (S,G) state machine remains
298 * in Joined state. Send Join(S,G) to the new
299 * upstream neighbor, which is the new value
300 * of RPF'(S,G). Send Prune(S,G) to the old
301 * upstream neighbor, which is the old value
302 * of RPF'(S,G). Set the Join Timer (JT) to
303 * expire after t_periodic seconds.
305 pim_jp_agg_switch_interface(old
, &up
->rpf
, up
);
307 pim_upstream_join_timer_restart(up
, old
);
308 } /* up->join_state == PIM_UPSTREAM_JOINED */
313 * We have detected a case where we might need
314 * to rescan the inherited o_list so do it.
316 if (up
->channel_oil
->oil_inherited_rescan
) {
317 pim_upstream_inherited_olist_decide(pim
, up
);
318 up
->channel_oil
->oil_inherited_rescan
= 0;
321 if (up
->join_state
== PIM_UPSTREAM_JOINED
)
322 pim_jp_agg_switch_interface(old
, &up
->rpf
, up
);
324 if (!up
->channel_oil
->installed
)
325 pim_upstream_mroute_add(up
->channel_oil
, __func__
);
328 /* FIXME can join_desired actually be changed by pim_rpf_update()
329 * returning PIM_RPF_CHANGED ?
331 pim_upstream_update_join_desired(pim
, up
);
334 __attribute__((unused
))
335 static int pim_zebra_vxlan_sg_proc(ZAPI_CALLBACK_ARGS
)
338 struct pim_instance
*pim
;
342 pim
= pim_get_pim_instance(vrf_id
);
348 prefixlen
= stream_getl(s
);
349 stream_get(&sg
.src
, s
, prefixlen
);
350 stream_get(&sg
.grp
, s
, prefixlen
);
353 zlog_debug("%u:recv SG %s %pSG", vrf_id
,
354 (cmd
== ZEBRA_VXLAN_SG_ADD
) ? "add" : "del", &sg
);
356 if (cmd
== ZEBRA_VXLAN_SG_ADD
)
357 pim_vxlan_sg_add(pim
, &sg
);
359 pim_vxlan_sg_del(pim
, &sg
);
364 __attribute__((unused
))
365 static void pim_zebra_vxlan_replay(void)
367 struct stream
*s
= NULL
;
370 if (!zclient
|| zclient
->sock
< 0)
376 zclient_create_header(s
, ZEBRA_VXLAN_SG_REPLAY
, VRF_DEFAULT
);
377 stream_putw_at(s
, 0, stream_get_endp(s
));
379 zclient_send_message(zclient
);
382 void pim_scan_oil(struct pim_instance
*pim
)
384 struct channel_oil
*c_oil
;
386 pim
->scan_oil_last
= pim_time_monotonic_sec();
387 ++pim
->scan_oil_events
;
389 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
)
390 pim_upstream_mroute_iif_update(c_oil
, __func__
);
393 static void on_rpf_cache_refresh(struct thread
*t
)
395 struct pim_instance
*pim
= THREAD_ARG(t
);
397 /* update kernel multicast forwarding cache (MFC) */
400 pim
->rpf_cache_refresh_last
= pim_time_monotonic_sec();
401 ++pim
->rpf_cache_refresh_events
;
403 // It is called as part of pim_neighbor_add
407 void sched_rpf_cache_refresh(struct pim_instance
*pim
)
409 ++pim
->rpf_cache_refresh_requests
;
411 pim_rpf_set_refresh_time(pim
);
413 if (pim
->rpf_cache_refresher
) {
414 /* Refresh timer is already running */
418 /* Start refresh timer */
420 if (PIM_DEBUG_ZEBRA
) {
421 zlog_debug("%s: triggering %ld msec timer", __func__
,
422 router
->rpf_cache_refresh_delay_msec
);
425 thread_add_timer_msec(router
->master
, on_rpf_cache_refresh
, pim
,
426 router
->rpf_cache_refresh_delay_msec
,
427 &pim
->rpf_cache_refresher
);
430 static void pim_zebra_connected(struct zclient
*zclient
)
433 /* Send the client registration */
434 bfd_client_sendmsg(zclient
, ZEBRA_BFD_CLIENT_REGISTER
, router
->vrf_id
);
437 zclient_send_reg_requests(zclient
, router
->vrf_id
);
440 /* request for VxLAN BUM group addresses */
441 pim_zebra_vxlan_replay();
445 static void pim_zebra_capabilities(struct zclient_capabilities
*cap
)
447 router
->mlag_role
= cap
->role
;
450 static zclient_handler
*const pim_handlers
[] = {
451 [ZEBRA_INTERFACE_ADDRESS_ADD
] = pim_zebra_if_address_add
,
452 [ZEBRA_INTERFACE_ADDRESS_DELETE
] = pim_zebra_if_address_del
,
454 [ZEBRA_NEXTHOP_UPDATE
] = pim_parse_nexthop_update
,
455 [ZEBRA_ROUTER_ID_UPDATE
] = pim_router_id_update_zebra
,
456 [ZEBRA_INTERFACE_VRF_UPDATE
] = pim_zebra_interface_vrf_update
,
459 [ZEBRA_VXLAN_SG_ADD
] = pim_zebra_vxlan_sg_proc
,
460 [ZEBRA_VXLAN_SG_DEL
] = pim_zebra_vxlan_sg_proc
,
462 [ZEBRA_MLAG_PROCESS_UP
] = pim_zebra_mlag_process_up
,
463 [ZEBRA_MLAG_PROCESS_DOWN
] = pim_zebra_mlag_process_down
,
464 [ZEBRA_MLAG_FORWARD_MSG
] = pim_zebra_mlag_handle_msg
,
468 void pim_zebra_init(void)
470 /* Socket for receiving updates from Zebra daemon */
471 zclient
= zclient_new(router
->master
, &zclient_options_default
,
472 pim_handlers
, array_size(pim_handlers
));
474 zclient
->zebra_capabilities
= pim_zebra_capabilities
;
475 zclient
->zebra_connected
= pim_zebra_connected
;
477 zclient_init(zclient
, ZEBRA_ROUTE_PIM
, 0, &pimd_privs
);
478 if (PIM_DEBUG_PIM_TRACE
) {
479 zlog_notice("%s: zclient socket initialized", __func__
);
482 zclient_lookup_new();
485 void pim_forward_start(struct pim_ifchannel
*ch
)
487 struct pim_upstream
*up
= ch
->upstream
;
490 if (PIM_DEBUG_PIM_TRACE
)
491 zlog_debug("%s: (S,G)=%pSG oif=%s (%pPA)", __func__
, &ch
->sg
,
492 ch
->interface
->name
, &up
->upstream_addr
);
494 if (PIM_IF_FLAG_TEST_PROTO_IGMP(ch
->flags
))
495 mask
= PIM_OIF_FLAG_PROTO_IGMP
;
497 if (PIM_IF_FLAG_TEST_PROTO_PIM(ch
->flags
))
498 mask
|= PIM_OIF_FLAG_PROTO_PIM
;
500 pim_channel_add_oif(up
->channel_oil
, ch
->interface
,
504 void pim_forward_stop(struct pim_ifchannel
*ch
)
506 struct pim_upstream
*up
= ch
->upstream
;
508 if (PIM_DEBUG_PIM_TRACE
) {
509 zlog_debug("%s: (S,G)=%s oif=%s installed: %d",
510 __func__
, ch
->sg_str
, ch
->interface
->name
,
511 up
->channel_oil
->installed
);
515 * If a channel is being removed, check to see if we still need
516 * to inherit the interface. If so make sure it is added in
518 if (pim_upstream_evaluate_join_desired_interface(up
, ch
, ch
->parent
))
519 pim_channel_add_oif(up
->channel_oil
, ch
->interface
,
520 PIM_OIF_FLAG_PROTO_PIM
, __func__
);
522 pim_channel_del_oif(up
->channel_oil
, ch
->interface
,
523 PIM_OIF_FLAG_PROTO_PIM
, __func__
);
526 void pim_zebra_zclient_update(struct vty
*vty
)
528 vty_out(vty
, "Zclient update socket: ");
531 vty_out(vty
, "%d failures=%d\n", zclient
->sock
, zclient
->fail
);
533 vty_out(vty
, "<null zclient>\n");
537 struct zclient
*pim_zebra_zclient_get(void)
545 void pim_zebra_interface_set_master(struct interface
*vrf
,
546 struct interface
*ifp
)
548 zclient_interface_set_master(zclient
, vrf
, ifp
);