]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
ba4eb1bc CS |
2 | /* |
3 | * pim_bfd.c: PIM BFD handling routines | |
4 | * | |
5 | * Copyright (C) 2017 Cumulus Networks, Inc. | |
6 | * Chirag Shah | |
ba4eb1bc CS |
7 | */ |
8 | ||
9 | #include <zebra.h> | |
10 | ||
11 | #include "lib/json.h" | |
12 | #include "command.h" | |
13 | #include "vty.h" | |
14 | #include "zclient.h" | |
15 | ||
9b29ea95 | 16 | #include "pim_instance.h" |
e34e07e6 | 17 | #include "pim_neighbor.h" |
ba4eb1bc CS |
18 | #include "pim_vty.h" |
19 | #include "pim_iface.h" | |
20 | #include "pim_bfd.h" | |
21 | #include "bfd.h" | |
22 | #include "pimd.h" | |
23 | #include "pim_zebra.h" | |
24 | ||
25 | /* | |
26 | * pim_bfd_write_config - Write the interface BFD configuration. | |
27 | */ | |
d62a17ae | 28 | void pim_bfd_write_config(struct vty *vty, struct interface *ifp) |
ba4eb1bc | 29 | { |
d62a17ae | 30 | struct pim_interface *pim_ifp = ifp->info; |
d62a17ae | 31 | |
1f3e6bf5 | 32 | if (!pim_ifp || !pim_ifp->bfd_config.enabled) |
d62a17ae | 33 | return; |
34 | ||
a0841732 | 35 | #if HAVE_BFDD == 0 |
1f3e6bf5 RZ |
36 | if (pim_ifp->bfd_config.detection_multiplier != BFD_DEF_DETECT_MULT |
37 | || pim_ifp->bfd_config.min_rx != BFD_DEF_MIN_RX | |
38 | || pim_ifp->bfd_config.min_tx != BFD_DEF_MIN_TX) | |
d17b6892 | 39 | vty_out(vty, " " PIM_AF_NAME " pim bfd %d %d %d\n", |
1f3e6bf5 RZ |
40 | pim_ifp->bfd_config.detection_multiplier, |
41 | pim_ifp->bfd_config.min_rx, pim_ifp->bfd_config.min_tx); | |
d62a17ae | 42 | else |
a0841732 | 43 | #endif /* ! HAVE_BFDD */ |
d17b6892 | 44 | vty_out(vty, " " PIM_AF_NAME " pim bfd\n"); |
745b8d4a RZ |
45 | |
46 | if (pim_ifp->bfd_config.profile) | |
d17b6892 | 47 | vty_out(vty, " " PIM_AF_NAME " pim bfd profile %s\n", |
745b8d4a | 48 | pim_ifp->bfd_config.profile); |
ba4eb1bc CS |
49 | } |
50 | ||
1f3e6bf5 RZ |
51 | static void pim_neighbor_bfd_cb(struct bfd_session_params *bsp, |
52 | const struct bfd_session_status *bss, void *arg) | |
ba4eb1bc | 53 | { |
1f3e6bf5 RZ |
54 | struct pim_neighbor *nbr = arg; |
55 | ||
56 | if (PIM_DEBUG_PIM_TRACE) { | |
57 | zlog_debug("%s: status %s old_status %s", __func__, | |
58 | bfd_get_status_str(bss->state), | |
59 | bfd_get_status_str(bss->previous_state)); | |
60 | } | |
61 | ||
62 | if (bss->state == BFD_STATUS_DOWN | |
63 | && bss->previous_state == BFD_STATUS_UP) | |
64 | pim_neighbor_delete(nbr->interface, nbr, "BFD Session Expired"); | |
ba4eb1bc CS |
65 | } |
66 | ||
67 | /* | |
68 | * pim_bfd_info_nbr_create - Create/update BFD information for a neighbor. | |
69 | */ | |
d62a17ae | 70 | void pim_bfd_info_nbr_create(struct pim_interface *pim_ifp, |
71 | struct pim_neighbor *neigh) | |
ba4eb1bc | 72 | { |
d62a17ae | 73 | /* Check if Pim Interface BFD is enabled */ |
1f3e6bf5 | 74 | if (!pim_ifp || !pim_ifp->bfd_config.enabled) |
d62a17ae | 75 | return; |
9beff0bd | 76 | |
1f3e6bf5 RZ |
77 | if (neigh->bfd_session == NULL) |
78 | neigh->bfd_session = bfd_sess_new(pim_neighbor_bfd_cb, neigh); | |
9beff0bd | 79 | |
1f3e6bf5 RZ |
80 | bfd_sess_set_timers( |
81 | neigh->bfd_session, pim_ifp->bfd_config.detection_multiplier, | |
82 | pim_ifp->bfd_config.min_rx, pim_ifp->bfd_config.min_tx); | |
ae449dc5 | 83 | #if PIM_IPV == 4 |
1f3e6bf5 | 84 | bfd_sess_set_ipv4_addrs(neigh->bfd_session, NULL, &neigh->source_addr); |
9bb93fa0 DL |
85 | #else |
86 | bfd_sess_set_ipv6_addrs(neigh->bfd_session, NULL, &neigh->source_addr); | |
87 | #endif | |
1f3e6bf5 | 88 | bfd_sess_set_interface(neigh->bfd_session, neigh->interface->name); |
096f7609 | 89 | bfd_sess_set_vrf(neigh->bfd_session, neigh->interface->vrf->vrf_id); |
745b8d4a | 90 | bfd_sess_set_profile(neigh->bfd_session, pim_ifp->bfd_config.profile); |
1f3e6bf5 | 91 | bfd_sess_install(neigh->bfd_session); |
ba4eb1bc CS |
92 | } |
93 | ||
94 | /* | |
95 | * pim_bfd_reg_dereg_all_nbr - Register/Deregister all neighbors associated | |
96 | * with a interface with BFD through | |
97 | * zebra for starting/stopping the monitoring of | |
98 | * the neighbor rechahability. | |
99 | */ | |
1f3e6bf5 | 100 | void pim_bfd_reg_dereg_all_nbr(struct interface *ifp) |
ba4eb1bc | 101 | { |
d62a17ae | 102 | struct pim_interface *pim_ifp = NULL; |
103 | struct listnode *node = NULL; | |
104 | struct pim_neighbor *neigh = NULL; | |
105 | ||
106 | pim_ifp = ifp->info; | |
107 | if (!pim_ifp) | |
1f3e6bf5 | 108 | return; |
d62a17ae | 109 | |
110 | for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, node, neigh)) { | |
1f3e6bf5 | 111 | if (pim_ifp->bfd_config.enabled) |
d62a17ae | 112 | pim_bfd_info_nbr_create(pim_ifp, neigh); |
113 | else | |
1f3e6bf5 | 114 | bfd_sess_free(&neigh->bfd_session); |
d62a17ae | 115 | } |
ba4eb1bc CS |
116 | } |
117 | ||
d62a17ae | 118 | void pim_bfd_init(void) |
ba4eb1bc | 119 | { |
1f3e6bf5 | 120 | bfd_protocol_integration_init(pim_zebra_zclient_get(), router->master); |
ba4eb1bc | 121 | } |