Coverage Report

Created: 2025-07-14 06:48

/src/frr/pimd/pim_bfd.c
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
}