back to topotato report
topotato coverage report
Current view: top level - ospfd - ospf_bfd.c (source / functions) Hit Total Coverage
Test: test_ospf_topo1.py::OSPFTopo1Test Lines: 15 134 11.2 %
Date: 2023-02-24 18:38:32 Functions: 4 16 25.0 %

          Line data    Source code
       1             : /**
       2             :  * ospf_bfd.c: OSPF BFD handling routines
       3             :  *
       4             :  * @copyright Copyright (C) 2015 Cumulus Networks, Inc.
       5             :  *
       6             :  * This file is part of GNU Zebra.
       7             :  *
       8             :  * GNU Zebra is free software; you can redistribute it and/or modify it
       9             :  * under the terms of the GNU General Public License as published by the
      10             :  * Free Software Foundation; either version 2, or (at your option) any
      11             :  * later version.
      12             :  *
      13             :  * GNU Zebra is distributed in the hope that it will be useful, but
      14             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU General Public License along
      19             :  * with this program; see the file COPYING; if not, write to the Free Software
      20             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      21             :  */
      22             : 
      23             : #include <zebra.h>
      24             : 
      25             : #include "command.h"
      26             : #include "json.h"
      27             : #include "linklist.h"
      28             : #include "memory.h"
      29             : #include "prefix.h"
      30             : #include "thread.h"
      31             : #include "buffer.h"
      32             : #include "stream.h"
      33             : #include "zclient.h"
      34             : #include "vty.h"
      35             : #include "table.h"
      36             : #include "bfd.h"
      37             : #include "ospfd.h"
      38             : #include "ospf_asbr.h"
      39             : #include "ospf_lsa.h"
      40             : #include "ospf_lsdb.h"
      41             : #include "ospf_neighbor.h"
      42             : #include "ospf_interface.h"
      43             : #include "ospf_nsm.h"
      44             : #include "ospf_bfd.h"
      45             : #include "ospf_dump.h"
      46             : #include "ospf_vty.h"
      47             : 
      48          12 : DEFINE_MTYPE_STATIC(OSPFD, BFD_CONFIG, "BFD configuration data");
      49             : 
      50             : /*
      51             :  * ospf_bfd_trigger_event - Neighbor is registered/deregistered with BFD when
      52             :  *                          neighbor state is changed to/from 2way.
      53             :  */
      54           0 : void ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state, int state)
      55             : {
      56           0 :         if ((old_state < NSM_TwoWay) && (state >= NSM_TwoWay))
      57           0 :                 bfd_sess_install(nbr->bfd_session);
      58           0 :         else if ((old_state >= NSM_TwoWay) && (state < NSM_TwoWay))
      59           0 :                 bfd_sess_uninstall(nbr->bfd_session);
      60           0 : }
      61             : 
      62           0 : static void ospf_bfd_session_change(struct bfd_session_params *bsp,
      63             :                                     const struct bfd_session_status *bss,
      64             :                                     void *arg)
      65             : {
      66           0 :         struct ospf_neighbor *nbr = arg;
      67             : 
      68             :         /* BFD peer went down. */
      69           0 :         if (bss->state == BFD_STATUS_DOWN
      70           0 :             && bss->previous_state == BFD_STATUS_UP) {
      71           0 :                 if (IS_DEBUG_OSPF(bfd, BFD_LIB))
      72           0 :                         zlog_debug("%s: NSM[%s:%pI4]: BFD Down", __func__,
      73             :                                    IF_NAME(nbr->oi), &nbr->address.u.prefix4);
      74             : 
      75           0 :                 OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer);
      76             :         }
      77             : 
      78             :         /* BFD peer went up. */
      79           0 :         if (bss->state == BSS_UP && bss->previous_state == BSS_DOWN)
      80           0 :                 if (IS_DEBUG_OSPF(bfd, BFD_LIB))
      81           0 :                         zlog_debug("%s: NSM[%s:%pI4]: BFD Up", __func__,
      82             :                                    IF_NAME(nbr->oi), &nbr->address.u.prefix4);
      83           0 : }
      84             : 
      85           8 : void ospf_neighbor_bfd_apply(struct ospf_neighbor *nbr)
      86             : {
      87           8 :         struct ospf_interface *oi = nbr->oi;
      88           8 :         struct ospf_if_params *oip = IF_DEF_PARAMS(oi->ifp);
      89             : 
      90             :         /* BFD configuration was removed. */
      91           8 :         if (oip->bfd_config == NULL) {
      92           8 :                 bfd_sess_free(&nbr->bfd_session);
      93           8 :                 return;
      94             :         }
      95             : 
      96             :         /* New BFD session. */
      97           0 :         if (nbr->bfd_session == NULL) {
      98           0 :                 nbr->bfd_session = bfd_sess_new(ospf_bfd_session_change, nbr);
      99           0 :                 bfd_sess_set_ipv4_addrs(nbr->bfd_session, NULL, &nbr->src);
     100           0 :                 bfd_sess_set_interface(nbr->bfd_session, oi->ifp->name);
     101           0 :                 bfd_sess_set_vrf(nbr->bfd_session, oi->ospf->vrf_id);
     102             :         }
     103             : 
     104             :         /* Set new configuration. */
     105           0 :         bfd_sess_set_timers(nbr->bfd_session,
     106           0 :                             oip->bfd_config->detection_multiplier,
     107           0 :                             oip->bfd_config->min_rx, oip->bfd_config->min_tx);
     108           0 :         bfd_sess_set_profile(nbr->bfd_session, oip->bfd_config->profile);
     109             : 
     110             :         /* Don't start sessions on down OSPF sessions. */
     111           0 :         if (nbr->state < NSM_TwoWay)
     112             :                 return;
     113             : 
     114           0 :         bfd_sess_install(nbr->bfd_session);
     115             : }
     116             : 
     117           0 : static void ospf_interface_bfd_apply(struct interface *ifp)
     118             : {
     119           0 :         struct ospf_interface *oi;
     120           0 :         struct route_table *nbrs;
     121           0 :         struct ospf_neighbor *nbr;
     122           0 :         struct route_node *irn;
     123           0 :         struct route_node *nrn;
     124             : 
     125             :         /* Iterate over all interfaces and set neighbors BFD session. */
     126           0 :         for (irn = route_top(IF_OIFS(ifp)); irn; irn = route_next(irn)) {
     127           0 :                 if ((oi = irn->info) == NULL)
     128           0 :                         continue;
     129           0 :                 if ((nbrs = oi->nbrs) == NULL)
     130           0 :                         continue;
     131           0 :                 for (nrn = route_top(nbrs); nrn; nrn = route_next(nrn)) {
     132           0 :                         if ((nbr = nrn->info) == NULL || nbr == oi->nbr_self)
     133           0 :                                 continue;
     134             : 
     135           0 :                         ospf_neighbor_bfd_apply(nbr);
     136             :                 }
     137             :         }
     138           0 : }
     139             : 
     140           0 : static void ospf_interface_enable_bfd(struct interface *ifp)
     141             : {
     142           0 :         struct ospf_if_params *oip = IF_DEF_PARAMS(ifp);
     143             : 
     144           0 :         if (oip->bfd_config)
     145             :                 return;
     146             : 
     147             :         /* Allocate memory for configurations and set defaults. */
     148           0 :         oip->bfd_config = XCALLOC(MTYPE_BFD_CONFIG, sizeof(*oip->bfd_config));
     149           0 :         oip->bfd_config->detection_multiplier = BFD_DEF_DETECT_MULT;
     150           0 :         oip->bfd_config->min_rx = BFD_DEF_MIN_RX;
     151           0 :         oip->bfd_config->min_tx = BFD_DEF_MIN_TX;
     152             : }
     153             : 
     154           0 : void ospf_interface_disable_bfd(struct interface *ifp,
     155             :                                 struct ospf_if_params *oip)
     156             : {
     157           0 :         XFREE(MTYPE_BFD_CONFIG, oip->bfd_config);
     158           0 :         ospf_interface_bfd_apply(ifp);
     159           0 : }
     160             : 
     161             : /*
     162             :  * ospf_bfd_write_config - Write the interface BFD configuration.
     163             :  */
     164           0 : void ospf_bfd_write_config(struct vty *vty, const struct ospf_if_params *params
     165             :                            __attribute__((unused)))
     166             : {
     167             : #if HAVE_BFDD == 0
     168             :         if (params->bfd_config->detection_multiplier != BFD_DEF_DETECT_MULT
     169             :             || params->bfd_config->min_rx != BFD_DEF_MIN_RX
     170             :             || params->bfd_config->min_tx != BFD_DEF_MIN_TX)
     171             :                 vty_out(vty, " ip ospf bfd %d %d %d\n",
     172             :                         params->bfd_config->detection_multiplier,
     173             :                         params->bfd_config->min_rx, params->bfd_config->min_tx);
     174             :         else
     175             : #endif /* ! HAVE_BFDD */
     176           0 :                 vty_out(vty, " ip ospf bfd\n");
     177             : 
     178           0 :         if (params->bfd_config->profile[0])
     179           0 :                 vty_out(vty, " ip ospf bfd profile %s\n",
     180           0 :                         params->bfd_config->profile);
     181           0 : }
     182             : 
     183           0 : void ospf_interface_bfd_show(struct vty *vty, const struct interface *ifp,
     184             :                              struct json_object *json)
     185             : {
     186           0 :         struct ospf_if_params *params = IF_DEF_PARAMS(ifp);
     187           0 :         struct bfd_configuration *bfd_config = params->bfd_config;
     188           0 :         struct json_object *json_bfd;
     189             : 
     190           0 :         if (bfd_config == NULL)
     191             :                 return;
     192             : 
     193           0 :         if (json) {
     194           0 :                 json_bfd = json_object_new_object();
     195           0 :                 json_object_int_add(json_bfd, "detectionMultiplier",
     196           0 :                                     bfd_config->detection_multiplier);
     197           0 :                 json_object_int_add(json_bfd, "rxMinInterval",
     198           0 :                                     bfd_config->min_rx);
     199           0 :                 json_object_int_add(json_bfd, "txMinInterval",
     200           0 :                                     bfd_config->min_tx);
     201           0 :                 json_object_object_add(json, "peerBfdInfo", json_bfd);
     202             :         } else
     203           0 :                 vty_out(vty,
     204             :                         "  BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n",
     205           0 :                         bfd_config->detection_multiplier, bfd_config->min_rx,
     206             :                         bfd_config->min_tx);
     207             : }
     208             : 
     209           0 : DEFUN (ip_ospf_bfd,
     210             :        ip_ospf_bfd_cmd,
     211             :        "ip ospf bfd",
     212             :        "IP Information\n"
     213             :        "OSPF interface commands\n"
     214             :        "Enables BFD support\n")
     215             : {
     216           0 :         VTY_DECLVAR_CONTEXT(interface, ifp);
     217           0 :         ospf_interface_enable_bfd(ifp);
     218           0 :         ospf_interface_bfd_apply(ifp);
     219           0 :         return CMD_SUCCESS;
     220             : }
     221             : 
     222             : #if HAVE_BFDD > 0
     223           0 : DEFUN_HIDDEN(
     224             : #else
     225             : DEFUN(
     226             : #endif /* HAVE_BFDD */
     227             :        ip_ospf_bfd_param,
     228             :        ip_ospf_bfd_param_cmd,
     229             :        "ip ospf bfd (2-255) (50-60000) (50-60000)",
     230             :        "IP Information\n"
     231             :        "OSPF interface commands\n"
     232             :        "Enables BFD support\n"
     233             :        "Detect Multiplier\n"
     234             :        "Required min receive interval\n"
     235             :        "Desired min transmit interval\n")
     236             : {
     237           0 :         VTY_DECLVAR_CONTEXT(interface, ifp);
     238           0 :         struct ospf_if_params *params;
     239           0 :         int idx_number = 3;
     240           0 :         int idx_number_2 = 4;
     241           0 :         int idx_number_3 = 5;
     242             : 
     243           0 :         ospf_interface_enable_bfd(ifp);
     244             : 
     245           0 :         params = IF_DEF_PARAMS(ifp);
     246           0 :         params->bfd_config->detection_multiplier =
     247           0 :                 strtol(argv[idx_number]->arg, NULL, 10);
     248           0 :         params->bfd_config->min_rx = strtol(argv[idx_number_2]->arg, NULL, 10);
     249           0 :         params->bfd_config->min_tx = strtol(argv[idx_number_3]->arg, NULL, 10);
     250             : 
     251           0 :         ospf_interface_bfd_apply(ifp);
     252             : 
     253           0 :         return CMD_SUCCESS;
     254             : }
     255             : 
     256           0 : DEFUN (ip_ospf_bfd_prof,
     257             :        ip_ospf_bfd_prof_cmd,
     258             :        "ip ospf bfd profile BFDPROF",
     259             :        "IP Information\n"
     260             :        "OSPF interface commands\n"
     261             :        "Enables BFD support\n"
     262             :        BFD_PROFILE_STR
     263             :        BFD_PROFILE_NAME_STR)
     264             : {
     265           0 :         VTY_DECLVAR_CONTEXT(interface, ifp);
     266           0 :         struct ospf_if_params *params;
     267           0 :         int idx_prof = 4;
     268             : 
     269           0 :         params = IF_DEF_PARAMS(ifp);
     270           0 :         if (!params->bfd_config) {
     271           0 :                 vty_out(vty, "ip ospf bfd has not been set\n");
     272           0 :                 return CMD_WARNING;
     273             :         }
     274             : 
     275           0 :         strlcpy(params->bfd_config->profile, argv[idx_prof]->arg,
     276             :                 sizeof(params->bfd_config->profile));
     277           0 :         ospf_interface_bfd_apply(ifp);
     278             : 
     279           0 :         return CMD_SUCCESS;
     280             : }
     281             : 
     282           0 : DEFUN (no_ip_ospf_bfd_prof,
     283             :        no_ip_ospf_bfd_prof_cmd,
     284             :        "no ip ospf bfd profile [BFDPROF]",
     285             :        NO_STR
     286             :        "IP Information\n"
     287             :        "OSPF interface commands\n"
     288             :        "Enables BFD support\n"
     289             :        BFD_PROFILE_STR
     290             :        BFD_PROFILE_NAME_STR)
     291             : {
     292           0 :         VTY_DECLVAR_CONTEXT(interface, ifp);
     293           0 :         struct ospf_if_params *params;
     294             : 
     295           0 :         params = IF_DEF_PARAMS(ifp);
     296           0 :         if (!params->bfd_config)
     297             :                 return CMD_SUCCESS;
     298             : 
     299           0 :         params->bfd_config->profile[0] = 0;
     300           0 :         ospf_interface_bfd_apply(ifp);
     301             : 
     302           0 :         return CMD_SUCCESS;
     303             : }
     304             : 
     305           0 : DEFUN (no_ip_ospf_bfd,
     306             :        no_ip_ospf_bfd_cmd,
     307             : #if HAVE_BFDD > 0
     308             :        "no ip ospf bfd",
     309             : #else
     310             :        "no ip ospf bfd [(2-255) (50-60000) (50-60000)]",
     311             : #endif /* HAVE_BFDD */
     312             :        NO_STR
     313             :        "IP Information\n"
     314             :        "OSPF interface commands\n"
     315             :        "Disables BFD support\n"
     316             : #if HAVE_BFDD == 0
     317             :        "Detect Multiplier\n"
     318             :        "Required min receive interval\n"
     319             :        "Desired min transmit interval\n"
     320             : #endif /* !HAVE_BFDD */
     321             : )
     322             : {
     323           0 :         VTY_DECLVAR_CONTEXT(interface, ifp);
     324           0 :         ospf_interface_disable_bfd(ifp, IF_DEF_PARAMS(ifp));
     325           0 :         return CMD_SUCCESS;
     326             : }
     327             : 
     328           4 : void ospf_bfd_init(struct thread_master *tm)
     329             : {
     330           4 :         bfd_protocol_integration_init(zclient, tm);
     331             : 
     332             :         /* Install BFD command */
     333           4 :         install_element(INTERFACE_NODE, &ip_ospf_bfd_cmd);
     334           4 :         install_element(INTERFACE_NODE, &ip_ospf_bfd_param_cmd);
     335           4 :         install_element(INTERFACE_NODE, &ip_ospf_bfd_prof_cmd);
     336           4 :         install_element(INTERFACE_NODE, &no_ip_ospf_bfd_prof_cmd);
     337           4 :         install_element(INTERFACE_NODE, &no_ip_ospf_bfd_cmd);
     338           4 : }

Generated by: LCOV version v1.16-topotato