back to topotato report
topotato coverage report
Current view: top level - bgpd - bgp_bfd.c (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 10 263 3.8 %
Date: 2023-02-24 14:41:08 Functions: 3 19 15.8 %

          Line data    Source code
       1             : /**
       2             :  * bgp_bfd.c: BGP 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 "linklist.h"
      27             : #include "memory.h"
      28             : #include "prefix.h"
      29             : #include "thread.h"
      30             : #include "buffer.h"
      31             : #include "stream.h"
      32             : #include "vrf.h"
      33             : #include "zclient.h"
      34             : #include "bfd.h"
      35             : #include "lib/json.h"
      36             : #include "filter.h"
      37             : 
      38             : #include "bgpd/bgpd.h"
      39             : #include "bgp_fsm.h"
      40             : #include "bgpd/bgp_bfd.h"
      41             : #include "bgpd/bgp_debug.h"
      42             : #include "bgpd/bgp_vty.h"
      43             : #include "bgpd/bgp_packet.h"
      44             : 
      45         102 : DEFINE_MTYPE_STATIC(BGPD, BFD_CONFIG, "BFD configuration data");
      46             : 
      47             : extern struct zclient *zclient;
      48             : 
      49           0 : static void bfd_session_status_update(struct bfd_session_params *bsp,
      50             :                                       const struct bfd_session_status *bss,
      51             :                                       void *arg)
      52             : {
      53           0 :         struct peer *peer = arg;
      54             : 
      55           0 :         if (BGP_DEBUG(bfd, BFD_LIB))
      56           0 :                 zlog_debug("%s: neighbor %s vrf %s(%u) bfd state %s -> %s",
      57             :                            __func__, peer->conf_if ? peer->conf_if : peer->host,
      58             :                            bfd_sess_vrf(bsp), bfd_sess_vrf_id(bsp),
      59             :                            bfd_get_status_str(bss->previous_state),
      60             :                            bfd_get_status_str(bss->state));
      61             : 
      62           0 :         if (bss->state == BSS_DOWN && bss->previous_state == BSS_UP) {
      63           0 :                 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE)
      64           0 :                     && bfd_sess_cbit(bsp) && !bss->remote_cbit) {
      65           0 :                         if (BGP_DEBUG(bfd, BFD_LIB))
      66           0 :                                 zlog_debug(
      67             :                                         "%s BFD DOWN message ignored in the process of graceful restart when C bit is cleared",
      68             :                                         peer->host);
      69           0 :                         return;
      70             :                 }
      71           0 :                 peer->last_reset = PEER_DOWN_BFD_DOWN;
      72             : 
      73             :                 /* draft-ietf-idr-bfd-subcode */
      74           0 :                 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
      75           0 :                         bgp_notify_send(peer, BGP_NOTIFY_CEASE,
      76             :                                         BGP_NOTIFY_CEASE_BFD_DOWN);
      77             : 
      78           0 :                 BGP_EVENT_ADD(peer, BGP_Stop);
      79             :         }
      80             : 
      81           0 :         if (bss->state == BSS_UP && bss->previous_state != BSS_UP
      82           0 :             && !peer_established(peer)) {
      83           0 :                 if (!BGP_PEER_START_SUPPRESSED(peer)) {
      84           0 :                         bgp_fsm_nht_update(peer, true);
      85           0 :                         BGP_EVENT_ADD(peer, BGP_Start);
      86             :                 }
      87             :         }
      88             : }
      89             : 
      90           0 : void bgp_peer_config_apply(struct peer *p, struct peer_group *pg)
      91             : {
      92           0 :         struct listnode *n;
      93           0 :         struct peer *pn;
      94           0 :         struct peer *gconfig;
      95             : 
      96             :         /* When called on a group, apply to all peers. */
      97           0 :         if (CHECK_FLAG(p->sflags, PEER_STATUS_GROUP)) {
      98           0 :                 for (ALL_LIST_ELEMENTS_RO(p->group->peer, n, pn))
      99           0 :                         bgp_peer_config_apply(pn, pg);
     100             :                 return;
     101             :         }
     102             : 
     103             :         /* No group, just use current configuration. */
     104           0 :         if (pg == NULL || pg->conf->bfd_config == NULL) {
     105           0 :                 bfd_sess_set_timers(p->bfd_config->session,
     106           0 :                                     p->bfd_config->detection_multiplier,
     107             :                                     p->bfd_config->min_rx,
     108           0 :                                     p->bfd_config->min_tx);
     109           0 :                 bfd_sess_set_cbit(p->bfd_config->session, p->bfd_config->cbit);
     110           0 :                 bfd_sess_set_profile(p->bfd_config->session,
     111           0 :                                      p->bfd_config->profile);
     112           0 :                 bfd_sess_install(p->bfd_config->session);
     113           0 :                 return;
     114             :         }
     115             : 
     116             :         /*
     117             :          * Check if the group configuration was overwritten or apply group
     118             :          * configuration.
     119             :          */
     120           0 :         gconfig = pg->conf;
     121             : 
     122             :         /*
     123             :          * If using default control plane independent configuration,
     124             :          * then prefer group's (e.g. it means it wasn't manually configured).
     125             :          */
     126           0 :         if (!p->bfd_config->cbit)
     127           0 :                 bfd_sess_set_cbit(p->bfd_config->session,
     128           0 :                                   gconfig->bfd_config->cbit);
     129             :         else
     130           0 :                 bfd_sess_set_cbit(p->bfd_config->session, p->bfd_config->cbit);
     131             : 
     132             :         /* If no profile was specified in peer, then use the group profile. */
     133           0 :         if (p->bfd_config->profile[0] == 0)
     134           0 :                 bfd_sess_set_profile(p->bfd_config->session,
     135           0 :                                      gconfig->bfd_config->profile);
     136             :         else
     137           0 :                 bfd_sess_set_profile(p->bfd_config->session,
     138           0 :                                      p->bfd_config->profile);
     139             : 
     140             :         /* If no specific timers were configured, then use the group timers. */
     141           0 :         if (p->bfd_config->detection_multiplier == BFD_DEF_DETECT_MULT
     142           0 :             || p->bfd_config->min_rx == BFD_DEF_MIN_RX
     143           0 :             || p->bfd_config->min_tx == BFD_DEF_MIN_TX)
     144           0 :                 bfd_sess_set_timers(p->bfd_config->session,
     145           0 :                                     gconfig->bfd_config->detection_multiplier,
     146             :                                     gconfig->bfd_config->min_rx,
     147           0 :                                     gconfig->bfd_config->min_tx);
     148             :         else
     149           0 :                 bfd_sess_set_timers(p->bfd_config->session,
     150             :                                     p->bfd_config->detection_multiplier,
     151             :                                     p->bfd_config->min_rx,
     152             :                                     p->bfd_config->min_tx);
     153             : 
     154           0 :         bfd_sess_install(p->bfd_config->session);
     155             : }
     156             : 
     157           0 : void bgp_peer_bfd_update_source(struct peer *p)
     158             : {
     159           0 :         struct bfd_session_params *session = p->bfd_config->session;
     160           0 :         const union sockunion *source;
     161           0 :         bool changed = false;
     162           0 :         int family;
     163           0 :         union {
     164             :                 struct in_addr v4;
     165             :                 struct in6_addr v6;
     166             :         } src, dst;
     167             : 
     168             :         /* Nothing to do for groups. */
     169           0 :         if (CHECK_FLAG(p->sflags, PEER_STATUS_GROUP))
     170           0 :                 return;
     171             : 
     172             :         /* Figure out the correct source to use. */
     173           0 :         if (CHECK_FLAG(p->flags, PEER_FLAG_UPDATE_SOURCE) && p->update_source)
     174             :                 source = p->update_source;
     175             :         else
     176           0 :                 source = p->su_local;
     177             : 
     178             :         /* Update peer's source/destination addresses. */
     179           0 :         bfd_sess_addresses(session, &family, &src.v6, &dst.v6);
     180           0 :         if (family == AF_INET) {
     181           0 :                 if ((source && source->sin.sin_addr.s_addr != src.v4.s_addr)
     182           0 :                     || p->su.sin.sin_addr.s_addr != dst.v4.s_addr) {
     183           0 :                         if (BGP_DEBUG(bfd, BFD_LIB))
     184           0 :                                 zlog_debug(
     185             :                                         "%s: address [%pI4->%pI4] to [%pI4->%pI4]",
     186             :                                         __func__, &src.v4, &dst.v4,
     187             :                                         source ? &source->sin.sin_addr
     188             :                                                : &src.v4,
     189             :                                         &p->su.sin.sin_addr);
     190             : 
     191           0 :                         bfd_sess_set_ipv4_addrs(
     192             :                                 session, source ? &source->sin.sin_addr : NULL,
     193           0 :                                 &p->su.sin.sin_addr);
     194           0 :                         changed = true;
     195             :                 }
     196             :         } else {
     197           0 :                 if ((source && memcmp(&source->sin6, &src.v6, sizeof(src.v6)))
     198           0 :                     || memcmp(&p->su.sin6, &dst.v6, sizeof(dst.v6))) {
     199           0 :                         if (BGP_DEBUG(bfd, BFD_LIB))
     200           0 :                                 zlog_debug(
     201             :                                         "%s: address [%pI6->%pI6] to [%pI6->%pI6]",
     202             :                                         __func__, &src.v6, &dst.v6,
     203             :                                         source ? &source->sin6.sin6_addr
     204             :                                                : &src.v6,
     205             :                                         &p->su.sin6.sin6_addr);
     206             : 
     207           0 :                         bfd_sess_set_ipv6_addrs(session,
     208             :                                                 source ? &source->sin6.sin6_addr
     209             :                                                        : NULL,
     210           0 :                                                 &p->su.sin6.sin6_addr);
     211           0 :                         changed = true;
     212             :                 }
     213             :         }
     214             : 
     215             :         /* Update interface. */
     216           0 :         if (p->nexthop.ifp && bfd_sess_interface(session) == NULL) {
     217           0 :                 if (BGP_DEBUG(bfd, BFD_LIB))
     218           0 :                         zlog_debug("%s: interface none to %s", __func__,
     219             :                                    p->nexthop.ifp->name);
     220             : 
     221           0 :                 bfd_sess_set_interface(session, p->nexthop.ifp->name);
     222           0 :                 changed = true;
     223             :         }
     224             : 
     225             :         /*
     226             :          * Update TTL.
     227             :          *
     228             :          * Two cases:
     229             :          * - We detected that the peer is a hop away from us (remove multi hop).
     230             :          *   (this happens when `p->shared_network` is set to `true`)
     231             :          * - eBGP multi hop / TTL security changed.
     232             :          */
     233           0 :         if (!PEER_IS_MULTIHOP(p) && bfd_sess_hop_count(session) > 1) {
     234           0 :                 if (BGP_DEBUG(bfd, BFD_LIB))
     235           0 :                         zlog_debug("%s: TTL %d to 1", __func__,
     236             :                                    bfd_sess_hop_count(session));
     237             : 
     238           0 :                 bfd_sess_set_hop_count(session, 1);
     239           0 :                 changed = true;
     240             :         }
     241           0 :         if (PEER_IS_MULTIHOP(p) && p->ttl != bfd_sess_hop_count(session)) {
     242           0 :                 if (BGP_DEBUG(bfd, BFD_LIB))
     243           0 :                         zlog_debug("%s: TTL %d to %d", __func__,
     244             :                                    bfd_sess_hop_count(session), p->ttl);
     245             : 
     246           0 :                 bfd_sess_set_hop_count(session, p->ttl);
     247           0 :                 changed = true;
     248             :         }
     249             : 
     250             :         /* Update VRF. */
     251           0 :         if (bfd_sess_vrf_id(session) != p->bgp->vrf_id) {
     252           0 :                 if (BGP_DEBUG(bfd, BFD_LIB))
     253           0 :                         zlog_debug(
     254             :                                 "%s: VRF %s(%d) to %s(%d)", __func__,
     255             :                                 bfd_sess_vrf(session), bfd_sess_vrf_id(session),
     256             :                                 vrf_id_to_name(p->bgp->vrf_id), p->bgp->vrf_id);
     257             : 
     258           0 :                 bfd_sess_set_vrf(session, p->bgp->vrf_id);
     259           0 :                 changed = true;
     260             :         }
     261             : 
     262           0 :         if (changed)
     263           0 :                 bfd_sess_install(session);
     264             : }
     265             : 
     266             : /**
     267             :  * Reset BFD configuration data structure to its defaults settings.
     268             :  */
     269           0 : static void bgp_peer_bfd_reset(struct peer *p)
     270             : {
     271             :         /* Set defaults. */
     272           0 :         p->bfd_config->detection_multiplier = BFD_DEF_DETECT_MULT;
     273           0 :         p->bfd_config->min_rx = BFD_DEF_MIN_RX;
     274           0 :         p->bfd_config->min_tx = BFD_DEF_MIN_TX;
     275           0 :         p->bfd_config->cbit = false;
     276           0 :         p->bfd_config->profile[0] = 0;
     277             : }
     278             : 
     279           0 : void bgp_peer_configure_bfd(struct peer *p, bool manual)
     280             : {
     281             :         /* Groups should not call this. */
     282           0 :         assert(!CHECK_FLAG(p->sflags, PEER_STATUS_GROUP));
     283             : 
     284             :         /* Already configured, skip it. */
     285           0 :         if (p->bfd_config) {
     286             :                 /* If manually active update flag. */
     287           0 :                 if (!p->bfd_config->manual)
     288           0 :                         p->bfd_config->manual = manual;
     289             : 
     290           0 :                 return;
     291             :         }
     292             : 
     293             :         /* Allocate memory for configuration overrides. */
     294           0 :         p->bfd_config = XCALLOC(MTYPE_BFD_CONFIG, sizeof(*p->bfd_config));
     295           0 :         p->bfd_config->manual = manual;
     296             : 
     297             :         /* Create new session and assign callback. */
     298           0 :         p->bfd_config->session = bfd_sess_new(bfd_session_status_update, p);
     299           0 :         bgp_peer_bfd_reset(p);
     300             : 
     301             :         /* Configure session with basic BGP peer data. */
     302           0 :         if (p->su.sa.sa_family == AF_INET)
     303           0 :                 bfd_sess_set_ipv4_addrs(p->bfd_config->session,
     304           0 :                                         p->su_local ? &p->su_local->sin.sin_addr
     305             :                                                     : NULL,
     306           0 :                                         &p->su.sin.sin_addr);
     307             :         else
     308           0 :                 bfd_sess_set_ipv6_addrs(
     309             :                         p->bfd_config->session,
     310           0 :                         p->su_local ? &p->su_local->sin6.sin6_addr : NULL,
     311           0 :                         &p->su.sin6.sin6_addr);
     312             : 
     313           0 :         bfd_sess_set_vrf(p->bfd_config->session, p->bgp->vrf_id);
     314           0 :         bfd_sess_set_hop_count(p->bfd_config->session,
     315           0 :                                PEER_IS_MULTIHOP(p) ? p->ttl : 1);
     316             : 
     317           0 :         if (p->nexthop.ifp)
     318           0 :                 bfd_sess_set_interface(p->bfd_config->session,
     319           0 :                                        p->nexthop.ifp->name);
     320             : }
     321             : 
     322           0 : static void bgp_peer_remove_bfd(struct peer *p)
     323             : {
     324             :         /* Groups should not call this. */
     325           0 :         assert(!CHECK_FLAG(p->sflags, PEER_STATUS_GROUP));
     326             : 
     327             :         /*
     328             :          * Peer configuration was removed, however we must check if there
     329             :          * is still a group configuration to keep this running.
     330             :          */
     331           0 :         if (p->group && p->group->conf->bfd_config) {
     332           0 :                 p->bfd_config->manual = false;
     333           0 :                 bgp_peer_bfd_reset(p);
     334           0 :                 bgp_peer_config_apply(p, p->group);
     335           0 :                 return;
     336             :         }
     337             : 
     338           0 :         if (p->bfd_config)
     339           0 :                 bfd_sess_free(&p->bfd_config->session);
     340             : 
     341           0 :         XFREE(MTYPE_BFD_CONFIG, p->bfd_config);
     342             : }
     343             : 
     344           0 : static void bgp_group_configure_bfd(struct peer *p)
     345             : {
     346           0 :         struct listnode *n;
     347           0 :         struct peer *pn;
     348             : 
     349             :         /* Peers should not call this. */
     350           0 :         assert(CHECK_FLAG(p->sflags, PEER_STATUS_GROUP));
     351             : 
     352             :         /* Already allocated: do nothing. */
     353           0 :         if (p->bfd_config)
     354             :                 return;
     355             : 
     356           0 :         p->bfd_config = XCALLOC(MTYPE_BFD_CONFIG, sizeof(*p->bfd_config));
     357             : 
     358             :         /* Set defaults. */
     359           0 :         p->bfd_config->detection_multiplier = BFD_DEF_DETECT_MULT;
     360           0 :         p->bfd_config->min_rx = BFD_DEF_MIN_RX;
     361           0 :         p->bfd_config->min_tx = BFD_DEF_MIN_TX;
     362             : 
     363           0 :         for (ALL_LIST_ELEMENTS_RO(p->group->peer, n, pn))
     364           0 :                 bgp_peer_configure_bfd(pn, false);
     365             : }
     366             : 
     367           0 : static void bgp_group_remove_bfd(struct peer *p)
     368             : {
     369           0 :         struct listnode *n;
     370           0 :         struct peer *pn;
     371             : 
     372             :         /* Peers should not call this. */
     373           0 :         assert(CHECK_FLAG(p->sflags, PEER_STATUS_GROUP));
     374             : 
     375             :         /* Already freed: do nothing. */
     376           0 :         if (p->bfd_config == NULL)
     377             :                 return;
     378             : 
     379             :         /* Free configuration and point to `NULL`. */
     380           0 :         XFREE(MTYPE_BFD_CONFIG, p->bfd_config);
     381             : 
     382             :         /* Now that it is `NULL` recalculate configuration for all peers. */
     383           0 :         for (ALL_LIST_ELEMENTS_RO(p->group->peer, n, pn)) {
     384           0 :                 if (pn->bfd_config->manual)
     385           0 :                         bgp_peer_config_apply(pn, NULL);
     386             :                 else
     387           0 :                         bgp_peer_remove_bfd(pn);
     388             :         }
     389             : }
     390             : 
     391           0 : void bgp_peer_remove_bfd_config(struct peer *p)
     392             : {
     393           0 :         if (CHECK_FLAG(p->sflags, PEER_STATUS_GROUP))
     394           0 :                 bgp_group_remove_bfd(p);
     395             :         else
     396           0 :                 bgp_peer_remove_bfd(p);
     397           0 : }
     398             : 
     399             : /*
     400             :  * bgp_bfd_peer_config_write - Write the peer BFD configuration.
     401             :  */
     402           0 : void bgp_bfd_peer_config_write(struct vty *vty, const struct peer *peer,
     403             :                                const char *addr)
     404             : {
     405             :         /*
     406             :          * Always show group BFD configuration, but peer only when explicitly
     407             :          * configured.
     408             :          */
     409           0 :         if ((!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)
     410           0 :              && peer->bfd_config->manual)
     411           0 :             || CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
     412             : #if HAVE_BFDD > 0
     413           0 :                 vty_out(vty, " neighbor %s bfd\n", addr);
     414             : #else
     415             :                 vty_out(vty, " neighbor %s bfd %d %d %d\n", addr,
     416             :                         peer->bfd_config->detection_multiplier,
     417             :                         peer->bfd_config->min_rx, peer->bfd_config->min_tx);
     418             : #endif /* HAVE_BFDD */
     419             :         }
     420             : 
     421           0 :         if (peer->bfd_config->profile[0])
     422           0 :                 vty_out(vty, " neighbor %s bfd profile %s\n", addr,
     423           0 :                         peer->bfd_config->profile);
     424             : 
     425           0 :         if (peer->bfd_config->cbit)
     426           0 :                 vty_out(vty, " neighbor %s bfd check-control-plane-failure\n",
     427             :                         addr);
     428           0 : }
     429             : 
     430             : /*
     431             :  * bgp_bfd_show_info - Show the peer BFD information.
     432             :  */
     433           0 : void bgp_bfd_show_info(struct vty *vty, const struct peer *peer,
     434             :                        json_object *json_neigh)
     435             : {
     436           0 :         bfd_sess_show(vty, json_neigh, peer->bfd_config->session);
     437           0 : }
     438             : 
     439           0 : DEFUN (neighbor_bfd,
     440             :        neighbor_bfd_cmd,
     441             :        "neighbor <A.B.C.D|X:X::X:X|WORD> bfd",
     442             :        NEIGHBOR_STR
     443             :        NEIGHBOR_ADDR_STR2
     444             :        "Enables BFD support\n")
     445             : {
     446           0 :         int idx_peer = 1;
     447           0 :         struct peer *peer;
     448             : 
     449           0 :         peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
     450           0 :         if (!peer)
     451             :                 return CMD_WARNING_CONFIG_FAILED;
     452             : 
     453           0 :         if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
     454           0 :                 bgp_group_configure_bfd(peer);
     455             :         else
     456           0 :                 bgp_peer_configure_bfd(peer, true);
     457             : 
     458           0 :         bgp_peer_config_apply(peer, peer->group);
     459             : 
     460           0 :         return CMD_SUCCESS;
     461             : }
     462             : 
     463             : #if HAVE_BFDD > 0
     464           0 : DEFUN_HIDDEN(
     465             : #else
     466             : DEFUN(
     467             : #endif /* HAVE_BFDD */
     468             :        neighbor_bfd_param,
     469             :        neighbor_bfd_param_cmd,
     470             :        "neighbor <A.B.C.D|X:X::X:X|WORD> bfd (2-255) (50-60000) (50-60000)",
     471             :        NEIGHBOR_STR
     472             :        NEIGHBOR_ADDR_STR2
     473             :        "Enables BFD support\n"
     474             :        "Detect Multiplier\n"
     475             :        "Required min receive interval\n"
     476             :        "Desired min transmit interval\n")
     477             : {
     478           0 :         int idx_peer = 1;
     479           0 :         int idx_number_1 = 3;
     480           0 :         int idx_number_2 = 4;
     481           0 :         int idx_number_3 = 5;
     482           0 :         long detection_multiplier, min_rx, min_tx;
     483           0 :         struct peer *peer;
     484             : 
     485           0 :         peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
     486           0 :         if (!peer)
     487             :                 return CMD_WARNING_CONFIG_FAILED;
     488             : 
     489           0 :         detection_multiplier = strtol(argv[idx_number_1]->arg, NULL, 10);
     490           0 :         min_rx = strtol(argv[idx_number_2]->arg, NULL, 10);
     491           0 :         min_tx = strtol(argv[idx_number_3]->arg, NULL, 10);
     492             : 
     493           0 :         if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
     494           0 :                 bgp_group_configure_bfd(peer);
     495             :         else
     496           0 :                 bgp_peer_configure_bfd(peer, true);
     497             : 
     498           0 :         peer->bfd_config->detection_multiplier = detection_multiplier;
     499           0 :         peer->bfd_config->min_rx = min_rx;
     500           0 :         peer->bfd_config->min_tx = min_tx;
     501           0 :         bgp_peer_config_apply(peer, peer->group);
     502             : 
     503           0 :         return CMD_SUCCESS;
     504             : }
     505             : 
     506           0 : DEFUN (neighbor_bfd_check_controlplane_failure,
     507             :        neighbor_bfd_check_controlplane_failure_cmd,
     508             :        "[no] neighbor <A.B.C.D|X:X::X:X|WORD> bfd check-control-plane-failure",
     509             :        NO_STR
     510             :        NEIGHBOR_STR
     511             :        NEIGHBOR_ADDR_STR2
     512             :        "BFD support\n"
     513             :        "Link dataplane status with BGP controlplane\n")
     514             : {
     515           0 :         const char *no = strmatch(argv[0]->text, "no") ? "no" : NULL;
     516           0 :         int idx_peer = 0;
     517           0 :         struct peer *peer;
     518             : 
     519           0 :         if (no)
     520             :                 idx_peer = 2;
     521             :         else
     522             :                 idx_peer = 1;
     523           0 :         peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
     524           0 :         if (!peer)
     525             :                 return CMD_WARNING_CONFIG_FAILED;
     526             : 
     527           0 :         if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
     528           0 :                 bgp_group_configure_bfd(peer);
     529             :         else
     530           0 :                 bgp_peer_configure_bfd(peer, true);
     531             : 
     532           0 :         peer->bfd_config->cbit = no == NULL;
     533           0 :         bgp_peer_config_apply(peer, peer->group);
     534             : 
     535           0 :         return CMD_SUCCESS;
     536             :  }
     537             : 
     538           0 : DEFUN (no_neighbor_bfd,
     539             :        no_neighbor_bfd_cmd,
     540             : #if HAVE_BFDD > 0
     541             :        "no neighbor <A.B.C.D|X:X::X:X|WORD> bfd",
     542             : #else
     543             :        "no neighbor <A.B.C.D|X:X::X:X|WORD> bfd [(2-255) (50-60000) (50-60000)]",
     544             : #endif /* HAVE_BFDD */
     545             :        NO_STR
     546             :        NEIGHBOR_STR
     547             :        NEIGHBOR_ADDR_STR2
     548             :        "Disables BFD support\n"
     549             : #if HAVE_BFDD == 0
     550             :        "Detect Multiplier\n"
     551             :        "Required min receive interval\n"
     552             :        "Desired min transmit interval\n"
     553             : #endif /* !HAVE_BFDD */
     554             : )
     555             : {
     556           0 :         int idx_peer = 2;
     557           0 :         struct peer *peer;
     558             : 
     559           0 :         peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
     560           0 :         if (!peer)
     561             :                 return CMD_WARNING_CONFIG_FAILED;
     562             : 
     563           0 :         if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
     564           0 :                 bgp_group_remove_bfd(peer);
     565             :         else
     566           0 :                 bgp_peer_remove_bfd(peer);
     567             : 
     568             :         return CMD_SUCCESS;
     569             : }
     570             : 
     571             : #if HAVE_BFDD > 0
     572           0 : DEFUN(neighbor_bfd_profile, neighbor_bfd_profile_cmd,
     573             :       "neighbor <A.B.C.D|X:X::X:X|WORD> bfd profile BFDPROF",
     574             :       NEIGHBOR_STR
     575             :       NEIGHBOR_ADDR_STR2
     576             :       "BFD integration\n"
     577             :       BFD_PROFILE_STR
     578             :       BFD_PROFILE_NAME_STR)
     579             : {
     580           0 :         int idx_peer = 1, idx_prof = 4;
     581           0 :         struct peer *peer;
     582             : 
     583           0 :         peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
     584           0 :         if (!peer)
     585             :                 return CMD_WARNING_CONFIG_FAILED;
     586             : 
     587           0 :         if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
     588           0 :                 bgp_group_configure_bfd(peer);
     589             :         else
     590           0 :                 bgp_peer_configure_bfd(peer, true);
     591             : 
     592           0 :         strlcpy(peer->bfd_config->profile, argv[idx_prof]->arg,
     593             :                 sizeof(peer->bfd_config->profile));
     594           0 :         bgp_peer_config_apply(peer, peer->group);
     595             : 
     596           0 :         return CMD_SUCCESS;
     597             : }
     598             : 
     599           0 : DEFUN(no_neighbor_bfd_profile, no_neighbor_bfd_profile_cmd,
     600             :       "no neighbor <A.B.C.D|X:X::X:X|WORD> bfd profile [BFDPROF]",
     601             :       NO_STR
     602             :       NEIGHBOR_STR
     603             :       NEIGHBOR_ADDR_STR2
     604             :       "BFD integration\n"
     605             :       BFD_PROFILE_STR
     606             :       BFD_PROFILE_NAME_STR)
     607             : {
     608           0 :         int idx_peer = 2;
     609           0 :         struct peer *peer;
     610             : 
     611           0 :         peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
     612           0 :         if (!peer)
     613             :                 return CMD_WARNING_CONFIG_FAILED;
     614             : 
     615           0 :         if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
     616           0 :                 bgp_group_configure_bfd(peer);
     617             :         else
     618           0 :                 bgp_peer_configure_bfd(peer, true);
     619             : 
     620           0 :         peer->bfd_config->profile[0] = 0;
     621           0 :         bgp_peer_config_apply(peer, peer->group);
     622             : 
     623           0 :         return CMD_SUCCESS;
     624             : }
     625             : #endif /* HAVE_BFDD */
     626             : 
     627          34 : void bgp_bfd_init(struct thread_master *tm)
     628             : {
     629             :         /* Initialize BFD client functions */
     630          34 :         bfd_protocol_integration_init(zclient, tm);
     631             : 
     632             :         /* "neighbor bfd" commands. */
     633          34 :         install_element(BGP_NODE, &neighbor_bfd_cmd);
     634          34 :         install_element(BGP_NODE, &neighbor_bfd_param_cmd);
     635          34 :         install_element(BGP_NODE, &neighbor_bfd_check_controlplane_failure_cmd);
     636          34 :         install_element(BGP_NODE, &no_neighbor_bfd_cmd);
     637             : 
     638             : #if HAVE_BFDD > 0
     639          34 :         install_element(BGP_NODE, &neighbor_bfd_profile_cmd);
     640          34 :         install_element(BGP_NODE, &no_neighbor_bfd_profile_cmd);
     641             : #endif /* HAVE_BFDD */
     642          34 : }

Generated by: LCOV version v1.16-topotato