Line | Count | Source (jump to first uncovered line) |
1 | | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | | /* |
3 | | * pim_bfd.c: PIM BFD handling routines |
4 | | * |
5 | | * Copyright (C) 2017 Cumulus Networks, Inc. |
6 | | * Chirag Shah |
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 | | |
16 | | #include "pim_instance.h" |
17 | | #include "pim_neighbor.h" |
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 | | */ |
28 | | void pim_bfd_write_config(struct vty *vty, struct interface *ifp) |
29 | 0 | { |
30 | 0 | struct pim_interface *pim_ifp = ifp->info; |
31 | |
|
32 | 0 | if (!pim_ifp || !pim_ifp->bfd_config.enabled) |
33 | 0 | return; |
34 | | |
35 | | #if HAVE_BFDD == 0 |
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) |
39 | | vty_out(vty, " " PIM_AF_NAME " pim bfd %d %d %d\n", |
40 | | pim_ifp->bfd_config.detection_multiplier, |
41 | | pim_ifp->bfd_config.min_rx, pim_ifp->bfd_config.min_tx); |
42 | | else |
43 | | #endif /* ! HAVE_BFDD */ |
44 | 0 | vty_out(vty, " " PIM_AF_NAME " pim bfd\n"); |
45 | |
|
46 | 0 | if (pim_ifp->bfd_config.profile) |
47 | 0 | vty_out(vty, " " PIM_AF_NAME " pim bfd profile %s\n", |
48 | 0 | pim_ifp->bfd_config.profile); |
49 | 0 | } |
50 | | |
51 | | static void pim_neighbor_bfd_cb(struct bfd_session_params *bsp, |
52 | | const struct bfd_session_status *bss, void *arg) |
53 | 0 | { |
54 | 0 | struct pim_neighbor *nbr = arg; |
55 | |
|
56 | 0 | if (PIM_DEBUG_PIM_TRACE) { |
57 | 0 | zlog_debug("%s: status %s old_status %s", __func__, |
58 | 0 | bfd_get_status_str(bss->state), |
59 | 0 | bfd_get_status_str(bss->previous_state)); |
60 | 0 | } |
61 | |
|
62 | 0 | if (bss->state == BFD_STATUS_DOWN |
63 | 0 | && bss->previous_state == BFD_STATUS_UP) |
64 | 0 | pim_neighbor_delete(nbr->interface, nbr, "BFD Session Expired"); |
65 | 0 | } |
66 | | |
67 | | /* |
68 | | * pim_bfd_info_nbr_create - Create/update BFD information for a neighbor. |
69 | | */ |
70 | | void pim_bfd_info_nbr_create(struct pim_interface *pim_ifp, |
71 | | struct pim_neighbor *neigh) |
72 | 299 | { |
73 | | /* Check if Pim Interface BFD is enabled */ |
74 | 299 | if (!pim_ifp || !pim_ifp->bfd_config.enabled) |
75 | 299 | return; |
76 | | |
77 | 0 | if (neigh->bfd_session == NULL) |
78 | 0 | neigh->bfd_session = bfd_sess_new(pim_neighbor_bfd_cb, neigh); |
79 | |
|
80 | 0 | bfd_sess_set_timers( |
81 | 0 | neigh->bfd_session, pim_ifp->bfd_config.detection_multiplier, |
82 | 0 | pim_ifp->bfd_config.min_rx, pim_ifp->bfd_config.min_tx); |
83 | 0 | #if PIM_IPV == 4 |
84 | 0 | bfd_sess_set_ipv4_addrs(neigh->bfd_session, NULL, &neigh->source_addr); |
85 | | #else |
86 | | bfd_sess_set_ipv6_addrs(neigh->bfd_session, NULL, &neigh->source_addr); |
87 | | #endif |
88 | 0 | bfd_sess_set_interface(neigh->bfd_session, neigh->interface->name); |
89 | 0 | bfd_sess_set_vrf(neigh->bfd_session, neigh->interface->vrf->vrf_id); |
90 | 0 | bfd_sess_set_profile(neigh->bfd_session, pim_ifp->bfd_config.profile); |
91 | 0 | bfd_sess_install(neigh->bfd_session); |
92 | 0 | } |
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 | | */ |
100 | | void pim_bfd_reg_dereg_all_nbr(struct interface *ifp) |
101 | 0 | { |
102 | 0 | struct pim_interface *pim_ifp = NULL; |
103 | 0 | struct listnode *node = NULL; |
104 | 0 | struct pim_neighbor *neigh = NULL; |
105 | |
|
106 | 0 | pim_ifp = ifp->info; |
107 | 0 | if (!pim_ifp) |
108 | 0 | return; |
109 | | |
110 | 0 | for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, node, neigh)) { |
111 | 0 | if (pim_ifp->bfd_config.enabled) |
112 | 0 | pim_bfd_info_nbr_create(pim_ifp, neigh); |
113 | 0 | else |
114 | 0 | bfd_sess_free(&neigh->bfd_session); |
115 | 0 | } |
116 | 0 | } |
117 | | |
118 | | void pim_bfd_init(void) |
119 | 1 | { |
120 | 1 | bfd_protocol_integration_init(pim_zebra_zclient_get(), router->master); |
121 | 1 | } |