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