back to topotato report
topotato coverage report
Current view: top level - bgpd - bgp_mplsvpn.h (source / functions) Hit Total Coverage
Test: test_exabgp_demo.py::ExaBGPDemo Lines: 16 108 14.8 %
Date: 2023-02-24 18:37:55 Functions: 3 6 50.0 %

          Line data    Source code
       1             : /* MPLS-VPN
       2             :  * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
       3             :  *
       4             :  * This file is part of GxNU Zebra.
       5             :  *
       6             :  * GNU Zebra is free software; you can redistribute it and/or modify it
       7             :  * under the terms of the GNU General Public License as published by the
       8             :  * Free Software Foundation; either version 2, or (at your option) any
       9             :  * later version.
      10             :  *
      11             :  * GNU Zebra is distributed in the hope that it will be useful, but
      12             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License along
      17             :  * with this program; see the file COPYING; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #ifndef _QUAGGA_BGP_MPLSVPN_H
      22             : #define _QUAGGA_BGP_MPLSVPN_H
      23             : 
      24             : #include "bgpd/bgp_attr.h"
      25             : #include "bgpd/bgp_route.h"
      26             : #include "bgpd/bgp_rd.h"
      27             : #include "bgpd/bgp_zebra.h"
      28             : #include "bgpd/bgp_vty.h"
      29             : 
      30             : #define MPLS_LABEL_IS_SPECIAL(label) ((label) <= MPLS_LABEL_EXTENSION)
      31             : #define MPLS_LABEL_IS_NULL(label)                                              \
      32             :         ((label) == MPLS_LABEL_IPV4_EXPLICIT_NULL                              \
      33             :          || (label) == MPLS_LABEL_IPV6_EXPLICIT_NULL                           \
      34             :          || (label) == MPLS_LABEL_IMPLICIT_NULL)
      35             : 
      36             : #define BGP_VPNVX_HELP_STR BGP_AF_STR BGP_AF_STR
      37             : 
      38             : #define V4_HEADER                                                              \
      39             :         "   Network          Next Hop            Metric LocPrf Weight Path\n"
      40             : #define V4_HEADER_TAG "   Network          Next Hop      In tag/Out tag\n"
      41             : #define V4_HEADER_OVERLAY                                                      \
      42             :         "   Network          Next Hop      EthTag    Overlay Index   RouterMac\n"
      43             : 
      44             : #define BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH 20
      45             : 
      46             : extern void bgp_mplsvpn_init(void);
      47             : extern int bgp_nlri_parse_vpn(struct peer *, struct attr *, struct bgp_nlri *);
      48             : extern uint32_t decode_label(mpls_label_t *);
      49             : extern void encode_label(mpls_label_t, mpls_label_t *);
      50             : 
      51             : extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
      52             :                                      int *index, afi_t *afi);
      53             : extern int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
      54             :                              enum bgp_show_type type, void *output_arg,
      55             :                              int tags, bool use_json);
      56             : 
      57             : extern void vpn_leak_from_vrf_update(struct bgp *to_bgp, struct bgp *from_bgp,
      58             :                                      struct bgp_path_info *path_vrf);
      59             : 
      60             : extern void vpn_leak_from_vrf_withdraw(struct bgp *to_bgp, struct bgp *from_bgp,
      61             :                                        struct bgp_path_info *path_vrf);
      62             : 
      63             : extern void vpn_leak_from_vrf_withdraw_all(struct bgp *to_bgp,
      64             :                                            struct bgp *from_bgp, afi_t afi);
      65             : 
      66             : extern void vpn_leak_from_vrf_update_all(struct bgp *to_bgp,
      67             :                                          struct bgp *from_bgp, afi_t afi);
      68             : 
      69             : extern void vpn_leak_to_vrf_withdraw_all(struct bgp *to_bgp, afi_t afi);
      70             : 
      71             : extern void vpn_leak_to_vrf_update_all(struct bgp *to_bgp, struct bgp *from_bgp,
      72             :                                        afi_t afi);
      73             : 
      74             : extern bool vpn_leak_to_vrf_update(struct bgp *from_bgp,
      75             :                                    struct bgp_path_info *path_vpn,
      76             :                                    struct prefix_rd *prd);
      77             : 
      78             : extern void vpn_leak_to_vrf_withdraw(struct bgp_path_info *path_vpn);
      79             : 
      80             : extern void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi);
      81             : extern void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi);
      82             : extern void vpn_leak_zebra_vrf_sid_update(struct bgp *bgp, afi_t afi);
      83             : extern void vpn_leak_zebra_vrf_sid_update_per_af(struct bgp *bgp, afi_t afi);
      84             : extern void vpn_leak_zebra_vrf_sid_update_per_vrf(struct bgp *bgp);
      85             : extern void vpn_leak_zebra_vrf_sid_withdraw(struct bgp *bgp, afi_t afi);
      86             : extern void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp *bgp, afi_t afi);
      87             : extern void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp *bgp);
      88             : extern int vpn_leak_label_callback(mpls_label_t label, void *lblid, bool alloc);
      89             : extern void ensure_vrf_tovpn_sid(struct bgp *vpn, struct bgp *vrf, afi_t afi);
      90             : extern void delete_vrf_tovpn_sid(struct bgp *vpn, struct bgp *vrf, afi_t afi);
      91             : extern void delete_vrf_tovpn_sid_per_af(struct bgp *vpn, struct bgp *vrf,
      92             :                                         afi_t afi);
      93             : extern void delete_vrf_tovpn_sid_per_vrf(struct bgp *vpn, struct bgp *vrf);
      94             : extern void ensure_vrf_tovpn_sid_per_af(struct bgp *vpn, struct bgp *vrf,
      95             :                                         afi_t afi);
      96             : extern void ensure_vrf_tovpn_sid_per_vrf(struct bgp *vpn, struct bgp *vrf);
      97             : extern void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset,
      98             :                           uint8_t size);
      99             : extern void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
     100             :                                 afi_t afi, safi_t safi);
     101             : void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
     102             :                            afi_t afi, safi_t safi);
     103             : 
     104             : static inline bool is_bgp_vrf_mplsvpn(struct bgp *bgp)
     105             : {
     106             :         afi_t afi;
     107             : 
     108             :         if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
     109             :                 for (afi = 0; afi < AFI_MAX; ++afi) {
     110             :                         if (CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
     111             :                                        BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)
     112             :                             || CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
     113             :                                           BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT))
     114             :                                 return true;
     115             :                 }
     116             :         return false;
     117             : }
     118             : 
     119          11 : static inline int vpn_leak_to_vpn_active(struct bgp *bgp_vrf, afi_t afi,
     120             :                                          const char **pmsg)
     121             : {
     122          11 :         if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF
     123             :                 && bgp_vrf->inst_type != BGP_INSTANCE_TYPE_DEFAULT) {
     124             : 
     125           0 :                 if (pmsg)
     126           0 :                         *pmsg = "source bgp instance neither vrf nor default";
     127           0 :                 return 0;
     128             :         }
     129             : 
     130             :         /* Is vrf configured to export to vpn? */
     131          11 :         if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
     132             :                         BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)
     133             :             && !CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
     134             :                            BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
     135          11 :                 if (pmsg)
     136           1 :                         *pmsg = "export not set";
     137          11 :                 return 0;
     138             :         }
     139             : 
     140             :         /* Is there an RT list set? */
     141           0 :         if (!bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN]) {
     142           0 :                 if (pmsg)
     143           0 :                         *pmsg = "rtlist tovpn not defined";
     144           0 :                 return 0;
     145             :         }
     146             : 
     147             :         /* Is there an RD set? */
     148           0 :         if (!CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
     149             :                         BGP_VPN_POLICY_TOVPN_RD_SET)) {
     150           0 :                 if (pmsg)
     151           0 :                         *pmsg = "rd not defined";
     152           0 :                 return 0;
     153             :         }
     154             : 
     155             :         /* Is a route-map specified, but not defined? */
     156           0 :         if (bgp_vrf->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN] &&
     157           0 :                 !bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
     158           0 :                 if (pmsg)
     159           0 :                         *pmsg = "route-map tovpn named but not defined";
     160           0 :                 return 0;
     161             :         }
     162             : 
     163             :         /* Is there an "auto" export label that isn't allocated yet? */
     164           0 :         if (CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
     165           0 :                 BGP_VPN_POLICY_TOVPN_LABEL_AUTO) &&
     166           0 :                 (bgp_vrf->vpn_policy[afi].tovpn_label == MPLS_LABEL_NONE)) {
     167             : 
     168           0 :                 if (pmsg)
     169           0 :                         *pmsg = "auto label not allocated";
     170           0 :                 return 0;
     171             :         }
     172             : 
     173             :         return 1;
     174             : }
     175             : 
     176           0 : static inline int vpn_leak_from_vpn_active(struct bgp *bgp_vrf, afi_t afi,
     177             :                                            const char **pmsg)
     178             : {
     179           0 :         if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF
     180             :                 && bgp_vrf->inst_type != BGP_INSTANCE_TYPE_DEFAULT) {
     181             : 
     182           0 :                 if (pmsg)
     183           0 :                         *pmsg = "destination bgp instance neither vrf nor default";
     184           0 :                 return 0;
     185             :         }
     186             : 
     187           0 :         if (bgp_vrf->vrf_id == VRF_UNKNOWN) {
     188           0 :                 if (pmsg)
     189           0 :                         *pmsg = "destination bgp instance vrf is VRF_UNKNOWN";
     190           0 :                 return 0;
     191             :         }
     192             : 
     193             :         /* Is vrf configured to import from vpn? */
     194           0 :         if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
     195             :                         BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)
     196             :             && !CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
     197             :                            BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
     198           0 :                 if (pmsg)
     199           0 :                         *pmsg = "import not set";
     200           0 :                 return 0;
     201             :         }
     202             : 
     203             :         /* Is there an RT list set? */
     204           0 :         if (!bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN]) {
     205           0 :                 if (pmsg)
     206           0 :                         *pmsg = "rtlist fromvpn not defined";
     207           0 :                 return 0;
     208             :         }
     209             : 
     210             :         /* Is a route-map specified, but not defined? */
     211           0 :         if (bgp_vrf->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN] &&
     212           0 :                 !bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
     213           0 :                 if (pmsg)
     214           0 :                         *pmsg = "route-map fromvpn named but not defined";
     215           0 :                 return 0;
     216             :         }
     217             :         return 1;
     218             : }
     219             : 
     220           2 : static inline void vpn_leak_prechange(enum vpn_policy_direction direction,
     221             :                                       afi_t afi, struct bgp *bgp_vpn,
     222             :                                       struct bgp *bgp_vrf)
     223             : {
     224             :         /* Detect when default bgp instance is not (yet) defined by config */
     225           2 :         if (!bgp_vpn)
     226             :                 return;
     227             : 
     228           2 :         if ((direction == BGP_VPN_POLICY_DIR_FROMVPN) &&
     229           0 :                 vpn_leak_from_vpn_active(bgp_vrf, afi, NULL)) {
     230             : 
     231           0 :                 vpn_leak_to_vrf_withdraw_all(bgp_vrf, afi);
     232             :         }
     233           4 :         if ((direction == BGP_VPN_POLICY_DIR_TOVPN) &&
     234           2 :                 vpn_leak_to_vpn_active(bgp_vrf, afi, NULL)) {
     235             : 
     236           0 :                 vpn_leak_from_vrf_withdraw_all(bgp_vpn, bgp_vrf, afi);
     237             :         }
     238             : }
     239             : 
     240           0 : static inline void vpn_leak_postchange(enum vpn_policy_direction direction,
     241             :                                        afi_t afi, struct bgp *bgp_vpn,
     242             :                                        struct bgp *bgp_vrf)
     243             : {
     244             :         /* Detect when default bgp instance is not (yet) defined by config */
     245           0 :         if (!bgp_vpn)
     246             :                 return;
     247             : 
     248           0 :         if (direction == BGP_VPN_POLICY_DIR_FROMVPN) {
     249             :                 /* trigger a flush to re-sync with ADJ-RIB-in */
     250           0 :                 if (!CHECK_FLAG(bgp_vpn->af_flags[afi][SAFI_MPLS_VPN],
     251             :                                 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL))
     252           0 :                         bgp_clear_soft_in(bgp_vpn, afi, SAFI_MPLS_VPN);
     253             :                 else
     254           0 :                         vpn_leak_to_vrf_update_all(bgp_vrf, bgp_vpn, afi);
     255             :         }
     256           0 :         if (direction == BGP_VPN_POLICY_DIR_TOVPN) {
     257             : 
     258           0 :                 if (bgp_vrf->vpn_policy[afi].tovpn_label !=
     259             :                         bgp_vrf->vpn_policy[afi]
     260           0 :                                .tovpn_zebra_vrf_label_last_sent) {
     261           0 :                         vpn_leak_zebra_vrf_label_update(bgp_vrf, afi);
     262             :                 }
     263             : 
     264           0 :                 if (bgp_vrf->vpn_policy[afi].tovpn_sid_index == 0 &&
     265           0 :                     !CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
     266           0 :                                 BGP_VPN_POLICY_TOVPN_SID_AUTO) &&
     267           0 :                     bgp_vrf->tovpn_sid_index == 0 &&
     268           0 :                     !CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_TOVPN_SID_AUTO))
     269           0 :                         delete_vrf_tovpn_sid(bgp_vpn, bgp_vrf, afi);
     270             : 
     271           0 :                 if (!bgp_vrf->vpn_policy[afi].tovpn_sid && !bgp_vrf->tovpn_sid)
     272           0 :                         ensure_vrf_tovpn_sid(bgp_vpn, bgp_vrf, afi);
     273             : 
     274           0 :                 if ((!bgp_vrf->vpn_policy[afi].tovpn_sid &&
     275           0 :                      bgp_vrf->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent) ||
     276           0 :                     (!bgp_vrf->tovpn_sid &&
     277           0 :                      bgp_vrf->tovpn_zebra_vrf_sid_last_sent))
     278           0 :                         vpn_leak_zebra_vrf_sid_withdraw(bgp_vrf, afi);
     279             : 
     280           0 :                 if (bgp_vrf->vpn_policy[afi].tovpn_sid) {
     281           0 :                         if (sid_diff(bgp_vrf->vpn_policy[afi].tovpn_sid,
     282             :                                      bgp_vrf->vpn_policy[afi]
     283           0 :                                              .tovpn_zebra_vrf_sid_last_sent)) {
     284           0 :                                 vpn_leak_zebra_vrf_sid_update(bgp_vrf, afi);
     285             :                         }
     286           0 :                 } else if (bgp_vrf->tovpn_sid) {
     287           0 :                         if (sid_diff(bgp_vrf->tovpn_sid,
     288           0 :                                      bgp_vrf->tovpn_zebra_vrf_sid_last_sent)) {
     289           0 :                                 vpn_leak_zebra_vrf_sid_update(bgp_vrf, afi);
     290             :                         }
     291             :                 }
     292             : 
     293           0 :                 vpn_leak_from_vrf_update_all(bgp_vpn, bgp_vrf, afi);
     294             :         }
     295             : }
     296             : 
     297             : /* Flag if the route is injectable into VPN. This would be either a
     298             :  * non-imported route or a non-VPN imported route.
     299             :  */
     300           1 : static inline bool is_route_injectable_into_vpn(struct bgp_path_info *pi)
     301             : {
     302           1 :         struct bgp_path_info *parent_pi;
     303           1 :         struct bgp_table *table;
     304           1 :         struct bgp_dest *dest;
     305             : 
     306           1 :         if (pi->sub_type != BGP_ROUTE_IMPORTED ||
     307           0 :             !pi->extra ||
     308           0 :             !pi->extra->parent)
     309             :                 return true;
     310             : 
     311           0 :         parent_pi = (struct bgp_path_info *)pi->extra->parent;
     312           0 :         dest = parent_pi->net;
     313           0 :         if (!dest)
     314             :                 return true;
     315           0 :         table = bgp_dest_table(dest);
     316           0 :         if (table &&
     317           0 :             (table->afi == AFI_IP || table->afi == AFI_IP6) &&
     318           0 :             table->safi == SAFI_MPLS_VPN)
     319           0 :                 return false;
     320             :         return true;
     321             : }
     322             : 
     323             : /* Flag if the route path's family is VPN. */
     324           0 : static inline bool is_pi_family_vpn(struct bgp_path_info *pi)
     325             : {
     326           0 :         return (is_pi_family_matching(pi, AFI_IP, SAFI_MPLS_VPN) ||
     327           0 :                 is_pi_family_matching(pi, AFI_IP6, SAFI_MPLS_VPN));
     328             : }
     329             : 
     330             : extern void vpn_policy_routemap_event(const char *rmap_name);
     331             : 
     332             : extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey);
     333             : 
     334             : extern void vpn_leak_postchange_all(void);
     335             : extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
     336             :                                         bool is_config);
     337             : extern void bgp_vpn_leak_unimport(struct bgp *from_bgp);
     338             : extern void bgp_vpn_leak_export(struct bgp *from_bgp);
     339             : 
     340             : #endif /* _QUAGGA_BGP_MPLSVPN_H */

Generated by: LCOV version v1.16-topotato