back to topotato report
topotato coverage report
Current view: top level - bgpd - bgp_evpn_mh.h (source / functions) Hit Total Coverage
Test: test_bgp_minimum_holdtime.py::TestBGPMinimumHoldtime Lines: 1 19 5.3 %
Date: 2023-02-24 18:37:25 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /* EVPN header for multihoming procedures
       2             :  *
       3             :  * Copyright (C) 2019 Cumulus Networks
       4             :  * Anuradha Karuppiah
       5             :  *
       6             :  * This file is part of FRRouting.
       7             :  *
       8             :  * FRRouting 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             :  * FRRouting 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             :  */
      19             : 
      20             : #ifndef _FRR_BGP_EVPN_MH_H
      21             : #define _FRR_BGP_EVPN_MH_H
      22             : 
      23             : #include "vxlan.h"
      24             : #include "bgpd.h"
      25             : #include "bgp_evpn.h"
      26             : #include "bgp_evpn_private.h"
      27             : 
      28             : #define BGP_EVPN_AD_ES_ETH_TAG 0xffffffff
      29             : #define BGP_EVPN_AD_EVI_ETH_TAG 0
      30             : 
      31             : #define BGP_EVPNES_INCONS_STR_SZ 80
      32             : #define BGP_EVPN_VTEPS_FLAG_STR_SZ (BGP_EVPN_FLAG_STR_SZ * ES_VTEP_MAX_CNT)
      33             : 
      34             : #define BGP_EVPN_CONS_CHECK_INTERVAL 60
      35             : 
      36             : #define BGP_EVPN_MH_USE_ES_L3NHG_DEF true
      37             : 
      38             : /* XXX - tune this */
      39             : #define BGP_EVPN_MAX_EVI_PER_ES_FRAG 128
      40             : 
      41             : /* An ES can result in multiple EAD-per-ES route. Each EAD fragment is
      42             :  * associated with an unique RD
      43             :  */
      44             : struct bgp_evpn_es_frag {
      45             :         /* frag is associated with a parent ES */
      46             :         struct bgp_evpn_es *es;
      47             : 
      48             :         /* Id for deriving the RD automatically for this ES fragment */
      49             :         uint16_t rd_id;
      50             :         /* RD for this ES fragment */
      51             :         struct prefix_rd prd;
      52             : 
      53             :         /* Memory used for linking bgp_evpn_es_frag to
      54             :          * bgp_evpn_es->es_frag_list
      55             :          */
      56             :         struct listnode es_listnode;
      57             : 
      58             :         /* List of ES-EVIs associated with this fragment */
      59             :         struct list *es_evi_frag_list;
      60             : };
      61             : 
      62             : /* Ethernet Segment entry -
      63             :  * - Local and remote ESs are maintained in a global RB tree,
      64             :  *   bgp_mh_info->es_rb_tree using ESI as key
      65             :  * - Local ESs are received from zebra (BGP_EVPNES_LOCAL)
      66             :  * - Remotes ESs are implicitly created (by reference) by a remote ES-EVI
      67             :  *   (BGP_EVPNES_REMOTE)
      68             :  * - An ES can be simultaneously LOCAL and REMOTE; infact all LOCAL ESs are
      69             :  *   expected to have REMOTE ES peers.
      70             :  */
      71             : struct bgp_evpn_es {
      72             :         /* Ethernet Segment Identifier */
      73             :         esi_t esi;
      74             :         char esi_str[ESI_STR_LEN];
      75             : 
      76             :         /* es flags */
      77             :         uint32_t flags;
      78             :         /* created via zebra config */
      79             : #define BGP_EVPNES_LOCAL           (1 << 0)
      80             :         /* created implicitly by a remote ES-EVI reference */
      81             : #define BGP_EVPNES_REMOTE          (1 << 1)
      82             :         /* local ES link is oper-up */
      83             : #define BGP_EVPNES_OPER_UP         (1 << 2)
      84             :         /* enable generation of EAD-EVI routes */
      85             : #define BGP_EVPNES_ADV_EVI         (1 << 3)
      86             :         /* consistency checks pending */
      87             : #define BGP_EVPNES_CONS_CHECK_PEND (1 << 4)
      88             :         /* ES is in LACP bypass mode - don't advertise EAD-ES or ESR */
      89             : #define BGP_EVPNES_BYPASS (1 << 5)
      90             :         /* bits needed for printing the flags + null */
      91             : #define BGP_EVPN_FLAG_STR_SZ 7
      92             : 
      93             :         /* memory used for adding the es to bgp->es_rb_tree */
      94             :         RB_ENTRY(bgp_evpn_es) rb_node;
      95             : 
      96             :         /* [EVPNES_LOCAL] memory used for linking the es to
      97             :          * bgp_mh_info->local_es_list
      98             :          */
      99             :         struct listnode es_listnode;
     100             : 
     101             :         /* memory used for linking the es to "processing" pending list
     102             :          * bgp_mh_info->pend_es_list
     103             :          */
     104             :         struct listnode pend_es_listnode;
     105             : 
     106             :         /* [EVPNES_LOCAL] List of RDs for this ES (bgp_evpn_es_frag) */
     107             :         struct list *es_frag_list;
     108             :         struct bgp_evpn_es_frag *es_base_frag;
     109             : 
     110             :         /* [EVPNES_LOCAL] originator ip address  */
     111             :         struct in_addr originator_ip;
     112             : 
     113             :         /* [EVPNES_LOCAL] Route table for EVPN routes for this ESI-
     114             :          * - Type-4 local and remote routes
     115             :          * - Type-1 local routes
     116             :          */
     117             :         struct bgp_table *route_table;
     118             : 
     119             :         /* list of PEs (bgp_evpn_es_vtep) attached to the ES */
     120             :         struct list *es_vtep_list;
     121             : 
     122             :         /* List of ES-EVIs associated with this ES */
     123             :         struct list *es_evi_list;
     124             : 
     125             :         /* List of ES-VRFs associated with this ES */
     126             :         struct list *es_vrf_list;
     127             : 
     128             :         /* List of MAC-IP VNI paths using this ES as destination -
     129             :          * element is bgp_path_info_extra->es_info
     130             :          * Note: Only local/zebra-added MACIP paths in the VNI
     131             :          * routing table are linked to this list
     132             :          */
     133             :         struct list *macip_evi_path_list;
     134             : 
     135             :         /* List of MAC-IP paths in the global routing table using this
     136             :          * ES as destination - data is bgp_path_info_extra->es_info
     137             :          * Note: Only non-local/imported MACIP paths in the global
     138             :          * routing table are linked to this list
     139             :          */
     140             :         struct list *macip_global_path_list;
     141             : 
     142             :         /* Number of remote VNIs referencing this ES */
     143             :         uint32_t remote_es_evi_cnt;
     144             : 
     145             :         uint32_t inconsistencies;
     146             :         /* there are one or more EVIs whose VTEP list doesn't match
     147             :          * with the ES's VTEP list
     148             :          */
     149             : #define BGP_EVPNES_INCONS_VTEP_LIST (1 << 0)
     150             : 
     151             :         /* number of es-evi entries whose VTEP list doesn't match
     152             :          * with the ES's
     153             :          */
     154             :         uint32_t incons_evi_vtep_cnt;
     155             : 
     156             :         /* preference config for BUM-DF election. advertised via the ESR. */
     157             :         uint16_t df_pref;
     158             : 
     159             :         QOBJ_FIELDS;
     160             : };
     161             : DECLARE_QOBJ_TYPE(bgp_evpn_es);
     162             : RB_HEAD(bgp_es_rb_head, bgp_evpn_es);
     163           4 : RB_PROTOTYPE(bgp_es_rb_head, bgp_evpn_es, rb_node, bgp_es_rb_cmp);
     164             : 
     165             : /* PE attached to an ES */
     166             : struct bgp_evpn_es_vtep {
     167             :         struct bgp_evpn_es *es; /* parent ES */
     168             :         struct in_addr vtep_ip;
     169             : 
     170             :         char vtep_str[INET6_ADDRSTRLEN];
     171             : 
     172             :         uint32_t flags;
     173             :         /* Rxed a Type4 route from this PE */
     174             : #define BGP_EVPNES_VTEP_ESR        (1 << 0)
     175             :         /* Active (rxed EAD-ES and EAD-EVI) and can be included as
     176             :          * a nexthop
     177             :          */
     178             : #define BGP_EVPNES_VTEP_ACTIVE (1 << 1)
     179             : 
     180             :         uint32_t evi_cnt; /* es_evis referencing this vtep as an active path */
     181             : 
     182             :         /* Algorithm and preference for DF election. Rxed via the ESR */
     183             :         uint8_t df_alg;
     184             :         uint16_t df_pref;
     185             : 
     186             :         /* memory used for adding the entry to es->es_vtep_list */
     187             :         struct listnode es_listnode;
     188             : };
     189             : 
     190             : /* ES-VRF element needed for managing L3 NHGs. It is implicitly created
     191             :  * when an ES-EVI is associated with a tenant VRF
     192             :  */
     193             : struct bgp_evpn_es_vrf {
     194             :         struct bgp_evpn_es *es;
     195             :         struct bgp *bgp_vrf;
     196             : 
     197             :         uint32_t flags;
     198             : /* NHG can only be activated if there are active VTEPs in the ES and
     199             :  * there is a valid L3-VNI associated with the VRF
     200             :  */
     201             : #define BGP_EVPNES_VRF_NHG_ACTIVE (1 << 0)
     202             : 
     203             :         /* memory used for adding the es_vrf to
     204             :          * es_vrf->bgp_vrf->es_vrf_rb_tree
     205             :          */
     206             :         RB_ENTRY(bgp_evpn_es_vrf) rb_node;
     207             : 
     208             :         /* memory used for linking the es_vrf to es_vrf->es->es_vrf_list */
     209             :         struct listnode es_listnode;
     210             : 
     211             :         uint32_t nhg_id;
     212             :         uint32_t v6_nhg_id;
     213             : 
     214             :         /* Number of ES-EVI entries associated with this ES-VRF */
     215             :         uint32_t ref_cnt;
     216             : };
     217             : 
     218             : /* ES per-EVI info
     219             :  * - ES-EVIs are maintained per-L2-VNI (vpn->es_evi_rb_tree)
     220             :  * - ES-EVIs are also linked to the parent ES (es->es_evi_list)
     221             :  * - Local ES-EVIs are created by zebra (via config). They are linked to a
     222             :  *   per-VNI list (vpn->local_es_evi_list) for quick access
     223             :  * - Remote ES-EVIs are created implicitly when a bgp_evpn_es_evi_vtep
     224             :  *   references it.
     225             :  */
     226             : struct bgp_evpn_es_evi {
     227             :         struct bgp_evpn_es *es;
     228             :         /* Only applicableif EVI_LOCAL */
     229             :         struct bgp_evpn_es_frag *es_frag;
     230             :         struct bgpevpn *vpn;
     231             : 
     232             :         /* ES-EVI flags */
     233             :         uint32_t flags;
     234             : /* local ES-EVI, created by zebra */
     235             : #define BGP_EVPNES_EVI_LOCAL            (1 << 0)
     236             : /* created via a remote VTEP imported by BGP */
     237             : #define BGP_EVPNES_EVI_REMOTE           (1 << 1)
     238             : #define BGP_EVPNES_EVI_INCONS_VTEP_LIST (1 << 2)
     239             : 
     240             :         /* memory used for adding the es_evi to es_evi->vpn->es_evi_rb_tree */
     241             :         RB_ENTRY(bgp_evpn_es_evi) rb_node;
     242             :         /* memory used for linking the es_evi to
     243             :          * es_evi->vpn->local_es_evi_list
     244             :          */
     245             :         struct listnode l2vni_listnode;
     246             :         /* memory used for linking the es_evi to
     247             :          * es_evi->es->es_evi_list
     248             :          */
     249             :         struct listnode es_listnode;
     250             : 
     251             :         /* memory used for linking the es_evi to
     252             :          * es_evi->es_frag->es_evi_frag_list
     253             :          */
     254             :         struct listnode es_frag_listnode;
     255             :         /* list of PEs (bgp_evpn_es_evi_vtep) attached to the ES for this VNI */
     256             :         struct list *es_evi_vtep_list;
     257             : 
     258             :         struct bgp_evpn_es_vrf *es_vrf;
     259             : };
     260             : 
     261             : /* PE attached to an ES for a VNI. This entry is created when an EAD-per-ES
     262             :  * or EAD-per-EVI Type1 route is imported into the VNI.
     263             :  */
     264             : struct bgp_evpn_es_evi_vtep {
     265             :         struct bgp_evpn_es_evi *es_evi; /* parent ES-EVI */
     266             :         struct in_addr vtep_ip;
     267             : 
     268             :         uint32_t flags;
     269             :         /* Rxed an EAD-per-ES route from the PE */
     270             : #define BGP_EVPN_EVI_VTEP_EAD_PER_ES  (1 << 0) /* rxed EAD-per-ES */
     271             :         /* Rxed an EAD-per-EVI route from the PE */
     272             : #define BGP_EVPN_EVI_VTEP_EAD_PER_EVI (1 << 1) /* rxed EAD-per-EVI */
     273             :         /* VTEP is active i.e. will result in the creation of an es-vtep */
     274             : #define BGP_EVPN_EVI_VTEP_ACTIVE      (1 << 2)
     275             : #define BGP_EVPN_EVI_VTEP_EAD         (BGP_EVPN_EVI_VTEP_EAD_PER_ES |\
     276             :                 BGP_EVPN_EVI_VTEP_EAD_PER_EVI)
     277             : 
     278             :         /* memory used for adding the entry to es_evi->es_evi_vtep_list */
     279             :         struct listnode es_evi_listnode;
     280             :         struct bgp_evpn_es_vtep *es_vtep;
     281             : };
     282             : 
     283             : /* A nexthop is created when a path (imported from an EVPN type-2 route)
     284             :  * is added to the VRF route table using that nexthop.
     285             :  * It is added on first pi reference and removed on last pi deref.
     286             :  */
     287             : struct bgp_evpn_nh {
     288             :         /* backpointer to the VRF */
     289             :         struct bgp *bgp_vrf;
     290             :         /* nexthop/VTEP IP */
     291             :         struct ipaddr ip;
     292             :         /* description for easy logging */
     293             :         char nh_str[INET6_ADDRSTRLEN];
     294             :         struct ethaddr rmac;
     295             :         /* pi from which we are pulling the nh RMAC */
     296             :         struct bgp_path_info *ref_pi;
     297             :         /* List of VRF paths using this nexthop */
     298             :         struct list *pi_list;
     299             :         uint8_t flags;
     300             : #define BGP_EVPN_NH_READY_FOR_ZEBRA (1 << 0)
     301             : };
     302             : 
     303             : /* multihoming information stored in bgp_master */
     304             : #define bgp_mh_info (bm->mh_info)
     305             : struct bgp_evpn_mh_info {
     306             :         /* RB tree of Ethernet segments (used for EVPN-MH)  */
     307             :         struct bgp_es_rb_head es_rb_tree;
     308             :         /* List of local ESs */
     309             :         struct list *local_es_list;
     310             :         /* List of ESs with pending/periodic processing */
     311             :         struct list *pend_es_list;
     312             :         /* periodic timer for running background consistency checks */
     313             :         struct thread *t_cons_check;
     314             : 
     315             :         /* config knobs for optimizing or interop */
     316             :         /* Generate EAD-EVI routes even if the ES is oper-down. This can be
     317             :          * enabled as an optimization to avoid a storm of updates when an ES
     318             :          * link flaps.
     319             :          */
     320             :         bool ead_evi_adv_for_down_links;
     321             :         /* Enable ES consistency checking */
     322             :         bool consistency_checking;
     323             :         /* Use L3 NHGs for host routes in symmetric IRB */
     324             :         bool host_routes_use_l3nhg;
     325             :         /* Some vendors are not generating the EAD-per-EVI route. This knob
     326             :          * can be turned off to activate a remote ES-PE when the EAD-per-ES
     327             :          * route is rxed i.e. not wait on the EAD-per-EVI route
     328             :          */
     329             :         bool ead_evi_rx;
     330             : #define BGP_EVPN_MH_EAD_EVI_RX_DEF true
     331             :         /* Skip EAD-EVI advertisements by turning off this knob */
     332             :         bool ead_evi_tx;
     333             : #define BGP_EVPN_MH_EAD_EVI_TX_DEF true
     334             :         /* If the Local ES is inactive we advertise the MAC-IP without the
     335             :          * L3 ecomm
     336             :          */
     337             :         bool suppress_l3_ecomm_on_inactive_es;
     338             :         /* Setup EVPN PE nexthops and their RMAC in bgpd */
     339             :         bool bgp_evpn_nh_setup;
     340             : 
     341             :         /* If global export-rts are configured that is used for sending
     342             :          * sending the ead-per-es route instead of the L2-VNI(s) RTs
     343             :          */
     344             :         struct list *ead_es_export_rtl;
     345             : 
     346             :         /* Number of EVIs in an ES fragment - used of EAD-per-ES route
     347             :          * construction
     348             :          */
     349             :         uint32_t evi_per_es_frag;
     350             : };
     351             : 
     352             : /****************************************************************************/
     353           0 : static inline int bgp_evpn_is_es_local(struct bgp_evpn_es *es)
     354             : {
     355           0 :         return CHECK_FLAG(es->flags, BGP_EVPNES_LOCAL) ? 1 : 0;
     356             : }
     357             : 
     358             : extern esi_t *zero_esi;
     359           0 : static inline bool bgp_evpn_is_esi_valid(esi_t *esi)
     360             : {
     361           0 :         return !!memcmp(esi, zero_esi, sizeof(esi_t));
     362             : }
     363             : 
     364           0 : static inline esi_t *bgp_evpn_attr_get_esi(struct attr *attr)
     365             : {
     366           0 :         return attr ? &attr->esi : zero_esi;
     367             : }
     368             : 
     369           0 : static inline bool bgp_evpn_attr_is_sync(struct attr *attr)
     370             : {
     371           0 :         return attr ? !!(attr->es_flags &
     372           0 :                 (ATTR_ES_PEER_PROXY | ATTR_ES_PEER_ACTIVE)) : false;
     373             : }
     374             : 
     375           0 : static inline uint32_t bgp_evpn_attr_get_sync_seq(struct attr *attr)
     376             : {
     377           0 :         return attr ?  attr->mm_sync_seqnum : 0;
     378             : }
     379             : 
     380             : static inline bool bgp_evpn_attr_is_active_on_peer(struct attr *attr)
     381             : {
     382             :         return attr ?
     383             :                 !!(attr->es_flags & ATTR_ES_PEER_ACTIVE) : false;
     384             : }
     385             : 
     386             : static inline bool bgp_evpn_attr_is_router_on_peer(struct attr *attr)
     387             : {
     388             :         return attr ?
     389             :                 !!(attr->es_flags & ATTR_ES_PEER_ROUTER) : false;
     390             : }
     391             : 
     392           0 : static inline bool bgp_evpn_attr_is_proxy(struct attr *attr)
     393             : {
     394           0 :         return attr ? !!(attr->es_flags & ATTR_ES_PROXY_ADVERT) : false;
     395             : }
     396             : 
     397           0 : static inline bool bgp_evpn_attr_is_local_es(struct attr *attr)
     398             : {
     399           0 :         return attr ? !!(attr->es_flags & ATTR_ES_IS_LOCAL) : false;
     400             : }
     401             : 
     402             : static inline uint32_t bgp_evpn_attr_get_df_pref(struct attr *attr)
     403             : {
     404             :         return (attr) ? attr->df_pref : 0;
     405             : }
     406             : 
     407           0 : static inline bool bgp_evpn_local_es_is_active(struct bgp_evpn_es *es)
     408             : {
     409           0 :         return (es->flags & BGP_EVPNES_OPER_UP)
     410           0 :                && !(es->flags & BGP_EVPNES_BYPASS);
     411             : }
     412             : 
     413             : /****************************************************************************/
     414             : extern int bgp_evpn_es_route_install_uninstall(struct bgp *bgp,
     415             :                 struct bgp_evpn_es *es, afi_t afi, safi_t safi,
     416             :                 struct prefix_evpn *evp, struct bgp_path_info *pi,
     417             :                 int install);
     418             : extern void update_type1_routes_for_evi(struct bgp *bgp, struct bgpevpn *vpn);
     419             : extern int delete_global_ead_evi_routes(struct bgp *bgp, struct bgpevpn *vpn);
     420             : extern int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es,
     421             :                                     struct bgpevpn *vpn, afi_t afi, safi_t safi,
     422             :                                     struct bgp_dest *dest, struct attr *attr,
     423             :                                     struct bgp_path_info **ri,
     424             :                                     int *route_changed);
     425             : int bgp_evpn_type1_route_process(struct peer *peer, afi_t afi, safi_t safi,
     426             :                 struct attr *attr, uint8_t *pfx, int psize,
     427             :                 uint32_t addpath_id);
     428             : int bgp_evpn_type4_route_process(struct peer *peer, afi_t afi, safi_t safi,
     429             :                 struct attr *attr, uint8_t *pfx, int psize,
     430             :                 uint32_t addpath_id);
     431             : extern int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi,
     432             :                                  struct in_addr originator_ip, bool oper_up,
     433             :                                  uint16_t df_pref, bool bypass);
     434             : extern int bgp_evpn_local_es_del(struct bgp *bgp, esi_t *esi);
     435             : extern int bgp_evpn_local_es_evi_add(struct bgp *bgp, esi_t *esi, vni_t vni);
     436             : extern int bgp_evpn_local_es_evi_del(struct bgp *bgp, esi_t *esi, vni_t vni);
     437             : extern int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn,
     438             :                 const struct prefix_evpn *p);
     439             : extern int bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn,
     440             :                 const struct prefix_evpn *p);
     441             : extern void bgp_evpn_mh_init(void);
     442             : extern void bgp_evpn_mh_finish(void);
     443             : void bgp_evpn_vni_es_init(struct bgpevpn *vpn);
     444             : void bgp_evpn_vni_es_cleanup(struct bgpevpn *vpn);
     445             : void bgp_evpn_es_show_esi(struct vty *vty, esi_t *esi, bool uj);
     446             : void bgp_evpn_es_show(struct vty *vty, bool uj, bool detail);
     447             : void bgp_evpn_es_evi_show_vni(struct vty *vty, vni_t vni,
     448             :                 bool uj, bool detail);
     449             : void bgp_evpn_es_evi_show(struct vty *vty, bool uj, bool detail);
     450             : struct bgp_evpn_es *bgp_evpn_es_find(const esi_t *esi);
     451             : extern void bgp_evpn_vrf_es_init(struct bgp *bgp_vrf);
     452             : extern bool bgp_evpn_is_esi_local_and_non_bypass(esi_t *esi);
     453             : extern void bgp_evpn_es_vrf_deref(struct bgp_evpn_es_evi *es_evi);
     454             : extern void bgp_evpn_es_vrf_ref(struct bgp_evpn_es_evi *es_evi,
     455             :                                 struct bgp *bgp_vrf);
     456             : extern void bgp_evpn_path_mh_info_free(struct bgp_path_mh_info *mh_info);
     457             : extern void bgp_evpn_path_es_link(struct bgp_path_info *pi, vni_t vni,
     458             :                                   esi_t *esi);
     459             : extern bool bgp_evpn_path_es_use_nhg(struct bgp *bgp_vrf,
     460             :                                      struct bgp_path_info *pi, uint32_t *nhg_p);
     461             : extern void bgp_evpn_es_vrf_show(struct vty *vty, bool uj,
     462             :                                  struct bgp_evpn_es *es);
     463             : extern void bgp_evpn_es_vrf_show_esi(struct vty *vty, esi_t *esi, bool uj);
     464             : extern void bgp_evpn_switch_ead_evi_rx(void);
     465             : extern bool bgp_evpn_es_add_l3_ecomm_ok(esi_t *esi);
     466             : extern void bgp_evpn_es_vrf_use_nhg(struct bgp *bgp_vrf, esi_t *esi,
     467             :                                     bool *use_l3nhg, bool *is_l3nhg_active,
     468             :                                     struct bgp_evpn_es_vrf **es_vrf_p);
     469             : extern void bgp_evpn_nh_init(struct bgp *bgp_vrf);
     470             : extern void bgp_evpn_nh_finish(struct bgp *bgp_vrf);
     471             : extern void bgp_evpn_nh_show(struct vty *vty, bool uj);
     472             : extern void bgp_evpn_path_nh_add(struct bgp *bgp_vrf, struct bgp_path_info *pi);
     473             : extern void bgp_evpn_path_nh_del(struct bgp *bgp_vrf, struct bgp_path_info *pi);
     474             : extern void bgp_evpn_mh_config_ead_export_rt(struct bgp *bgp,
     475             :                                              struct ecommunity *ecom, bool del);
     476             : 
     477             : #endif /* _FRR_BGP_EVPN_MH_H */

Generated by: LCOV version v1.16-topotato