]> git.proxmox.com Git - mirror_frr.git/blob - ripd/rip_bfd.c
Merge pull request #13438 from gpnaveen/vrf_on_loopback
[mirror_frr.git] / ripd / rip_bfd.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * RIP BFD integration.
4 * Copyright (C) 2021-2023 Network Device Education Foundation, Inc. ("NetDEF")
5 */
6
7 #include <zebra.h>
8
9 #include "lib/zclient.h"
10 #include "lib/bfd.h"
11
12 #include "ripd/ripd.h"
13 #include "ripd/rip_bfd.h"
14 #include "ripd/rip_debug.h"
15
16 DEFINE_MTYPE(RIPD, RIP_BFD_PROFILE, "RIP BFD profile name");
17
18 extern struct zclient *zclient;
19
20 static const char *rip_bfd_interface_profile(struct rip_interface *ri)
21 {
22 struct rip *rip = ri->rip;
23
24 if (ri->bfd.profile)
25 return ri->bfd.profile;
26
27 if (rip->default_bfd_profile)
28 return rip->default_bfd_profile;
29
30 return NULL;
31 }
32
33 static void rip_bfd_session_change(struct bfd_session_params *bsp,
34 const struct bfd_session_status *bss,
35 void *arg)
36 {
37 struct rip_peer *rp = arg;
38
39 /* BFD peer went down. */
40 if (bss->state == BFD_STATUS_DOWN &&
41 bss->previous_state == BFD_STATUS_UP) {
42 if (IS_RIP_DEBUG_EVENT)
43 zlog_debug("%s: peer %pI4: BFD Down", __func__,
44 &rp->addr);
45
46 rip_peer_delete_routes(rp);
47 listnode_delete(rp->rip->peer_list, rp);
48 rip_peer_free(rp);
49 return;
50 }
51
52 /* BFD peer went up. */
53 if (bss->state == BSS_UP && bss->previous_state == BSS_DOWN)
54 if (IS_RIP_DEBUG_EVENT)
55 zlog_debug("%s: peer %pI4: BFD Up", __func__,
56 &rp->addr);
57 }
58
59 void rip_bfd_session_update(struct rip_peer *rp)
60 {
61 struct rip_interface *ri = rp->ri;
62
63 /* BFD configuration was removed. */
64 if (ri == NULL || !ri->bfd.enabled) {
65 bfd_sess_free(&rp->bfd_session);
66 return;
67 }
68
69 /* New BFD session. */
70 if (rp->bfd_session == NULL) {
71 rp->bfd_session = bfd_sess_new(rip_bfd_session_change, rp);
72 bfd_sess_set_ipv4_addrs(rp->bfd_session, NULL, &rp->addr);
73 bfd_sess_set_interface(rp->bfd_session, ri->ifp->name);
74 bfd_sess_set_vrf(rp->bfd_session, rp->rip->vrf->vrf_id);
75 }
76
77 /* Set new configuration. */
78 bfd_sess_set_timers(rp->bfd_session, BFD_DEF_DETECT_MULT,
79 BFD_DEF_MIN_RX, BFD_DEF_MIN_TX);
80 bfd_sess_set_profile(rp->bfd_session, rip_bfd_interface_profile(ri));
81
82 bfd_sess_install(rp->bfd_session);
83 }
84
85 void rip_bfd_interface_update(struct rip_interface *ri)
86 {
87 struct rip *rip;
88 struct rip_peer *rp;
89 struct listnode *node;
90
91 rip = ri->rip;
92 if (!rip)
93 return;
94
95 for (ALL_LIST_ELEMENTS_RO(rip->peer_list, node, rp)) {
96 if (rp->ri != ri)
97 continue;
98
99 rip_bfd_session_update(rp);
100 }
101 }
102
103 void rip_bfd_instance_update(struct rip *rip)
104 {
105 struct interface *ifp;
106
107 FOR_ALL_INTERFACES (rip->vrf, ifp) {
108 struct rip_interface *ri;
109
110 ri = ifp->info;
111 if (!ri)
112 continue;
113
114 rip_bfd_interface_update(ri);
115 }
116 }
117
118 void rip_bfd_init(struct event_loop *tm)
119 {
120 bfd_protocol_integration_init(zclient, tm);
121 }