back to topotato report
topotato coverage report
Current view: top level - bgpd - bgp_evpn_private.h (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 0 236 0.0 %
Date: 2023-02-24 14:41:08 Functions: 0 21 0.0 %

          Line data    Source code
       1             : /* BGP EVPN internal definitions
       2             :  * Copyright (C) 2017 Cumulus Networks, Inc.
       3             :  *
       4             :  * This file is part of FRR.
       5             :  *
       6             :  * FRR 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             :  * FRR 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
      17             :  * along with FRR; see the file COPYING.  If not, write to the Free
      18             :  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
      19             :  * 02111-1307, USA.
      20             :  */
      21             : 
      22             : #ifndef _BGP_EVPN_PRIVATE_H
      23             : #define _BGP_EVPN_PRIVATE_H
      24             : 
      25             : #include "vxlan.h"
      26             : #include "zebra.h"
      27             : 
      28             : #include "bgpd/bgpd.h"
      29             : #include "bgpd/bgp_ecommunity.h"
      30             : 
      31             : #define RT_ADDRSTRLEN 28
      32             : 
      33             : /* EVPN prefix lengths. This represents the sizeof struct evpn_addr
      34             :  * in bits  */
      35             : #define EVPN_ROUTE_PREFIXLEN (sizeof(struct evpn_addr) * 8)
      36             : 
      37             : /* EVPN route RD buffer length */
      38             : #define BGP_EVPN_PREFIX_RD_LEN 100
      39             : 
      40             : /* packet sizes for EVPN routes */
      41             : /* Type-1 route should be 25 bytes
      42             :  *  RD (8), ESI (10), eth-tag (4), vni (3)
      43             :  */
      44             : #define BGP_EVPN_TYPE1_PSIZE 25
      45             : /* Type-4 route should be either 23 or 35 bytes
      46             :  *  RD (8), ESI (10), ip-len (1), ip (4 or 16)
      47             :  */
      48             : #define BGP_EVPN_TYPE4_V4_PSIZE 23
      49             : #define BGP_EVPN_TYPE4_V6_PSIZE 34
      50             : 
      51             : RB_HEAD(bgp_es_evi_rb_head, bgp_evpn_es_evi);
      52           0 : RB_PROTOTYPE(bgp_es_evi_rb_head, bgp_evpn_es_evi, rb_node,
      53             :                 bgp_es_evi_rb_cmp);
      54             : /*
      55             :  * Hash table of EVIs. Right now, the only type of EVI supported is with
      56             :  * VxLAN encapsulation, hence each EVI corresponds to a L2 VNI.
      57             :  * The VNIs are not "created" through BGP but through some other interface
      58             :  * on the system. This table stores VNIs that BGP comes to know as present
      59             :  * on the system (through interaction with zebra) as well as pre-configured
      60             :  * VNIs (which need to be defined in the system to become "live").
      61             :  */
      62             : struct bgpevpn {
      63             :         vni_t vni;
      64             :         vrf_id_t tenant_vrf_id;
      65             :         ifindex_t svi_ifindex;
      66             :         uint32_t flags;
      67             : #define VNI_FLAG_CFGD              0x1  /* VNI is user configured */
      68             : #define VNI_FLAG_LIVE              0x2  /* VNI is "live" */
      69             : #define VNI_FLAG_RD_CFGD           0x4  /* RD is user configured. */
      70             : #define VNI_FLAG_IMPRT_CFGD        0x8  /* Import RT is user configured */
      71             : #define VNI_FLAG_EXPRT_CFGD        0x10 /* Export RT is user configured */
      72             : #define VNI_FLAG_USE_TWO_LABELS    0x20 /* Attach both L2-VNI and L3-VNI if
      73             :                                            needed for this VPN */
      74             : 
      75             :         struct bgp *bgp_vrf; /* back pointer to the vrf instance */
      76             : 
      77             :                                            /* Flag to indicate if we are
      78             :                                             * advertising the g/w mac ip for
      79             :                                             * this VNI*/
      80             :         uint8_t advertise_gw_macip;
      81             : 
      82             :         /* Flag to indicate if we are
      83             :          * advertising subnet for this VNI */
      84             :         uint8_t advertise_subnet;
      85             : 
      86             :         /* Flag to indicate if we are advertising the svi mac ip for this VNI*/
      87             :         uint8_t advertise_svi_macip;
      88             : 
      89             :         /* Id for deriving the RD
      90             :          * automatically for this VNI */
      91             :         uint16_t rd_id;
      92             : 
      93             :         /* RD for this VNI. */
      94             :         struct prefix_rd prd;
      95             : 
      96             :         /* Route type 3 field */
      97             :         struct in_addr originator_ip;
      98             : 
      99             :         /* PIM-SM MDT group for BUM flooding */
     100             :         struct in_addr mcast_grp;
     101             : 
     102             :         /* Import and Export RTs. */
     103             :         struct list *import_rtl;
     104             :         struct list *export_rtl;
     105             : 
     106             :         /*
     107             :          * EVPN route that uses gateway IP overlay index as its nexthop
     108             :          * needs to do a recursive lookup.
     109             :          * A remote MAC/IP entry should be present for the gateway IP.
     110             :          * Maintain a hash of the addresses received via remote MAC/IP routes
     111             :          * for efficient gateway IP recursive lookup in this EVI
     112             :          */
     113             :         struct hash *remote_ip_hash;
     114             : 
     115             :         /* Route tables for EVPN routes for
     116             :          * this VNI. */
     117             :         struct bgp_table *ip_table;
     118             :         struct bgp_table *mac_table;
     119             : 
     120             :         /* RB tree of ES-EVIs */
     121             :         struct bgp_es_evi_rb_head es_evi_rb_tree;
     122             : 
     123             :         /* List of local ESs */
     124             :         struct list *local_es_evi_list;
     125             : 
     126             :         QOBJ_FIELDS;
     127             : };
     128             : 
     129             : DECLARE_QOBJ_TYPE(bgpevpn);
     130             : 
     131             : /* Mapping of Import RT to VNIs.
     132             :  * The Import RTs of all VNIs are maintained in a hash table with each
     133             :  * RT linking to all VNIs that will import routes matching this RT.
     134             :  */
     135             : struct irt_node {
     136             :         /* RT */
     137             :         struct ecommunity_val rt;
     138             : 
     139             :         /* List of VNIs importing routes matching this RT. */
     140             :         struct list *vnis;
     141             : };
     142             : 
     143             : /* Mapping of Import RT to VRFs.
     144             :  * The Import RTs of all VRFss are maintained in a hash table with each
     145             :  * RT linking to all VRFs that will import routes matching this RT.
     146             :  */
     147             : struct vrf_irt_node {
     148             :         /* RT */
     149             :         struct ecommunity_val rt;
     150             : 
     151             :         /* List of VNIs importing routes matching this RT. */
     152             :         struct list *vrfs;
     153             : };
     154             : 
     155             : 
     156             : #define RT_TYPE_IMPORT 1
     157             : #define RT_TYPE_EXPORT 2
     158             : #define RT_TYPE_BOTH   3
     159             : 
     160             : #define EVPN_DAD_DEFAULT_TIME 180 /* secs */
     161             : #define EVPN_DAD_DEFAULT_MAX_MOVES 5 /* default from RFC 7432 */
     162             : #define EVPN_DAD_DEFAULT_AUTO_RECOVERY_TIME 1800 /* secs */
     163             : 
     164             : struct bgp_evpn_info {
     165             :         /* enable disable dup detect */
     166             :         bool dup_addr_detect;
     167             : 
     168             :         /* Detection time(M) */
     169             :         int dad_time;
     170             :         /* Detection max moves(N) */
     171             :         uint32_t dad_max_moves;
     172             :         /* Permanent freeze */
     173             :         bool dad_freeze;
     174             :         /* Recovery time */
     175             :         uint32_t dad_freeze_time;
     176             : 
     177             :         /* EVPN enable - advertise svi macip routes */
     178             :         int advertise_svi_macip;
     179             : 
     180             :         /* PIP feature knob */
     181             :         bool advertise_pip;
     182             :         /* PIP IP (sys ip) */
     183             :         struct in_addr pip_ip;
     184             :         struct in_addr pip_ip_static;
     185             :         /* PIP MAC (sys MAC) */
     186             :         struct ethaddr pip_rmac;
     187             :         struct ethaddr pip_rmac_static;
     188             :         struct ethaddr pip_rmac_zebra;
     189             :         bool is_anycast_mac;
     190             : };
     191             : 
     192             : /* This structure defines an entry in remote_ip_hash */
     193             : struct evpn_remote_ip {
     194             :         struct ipaddr addr;
     195             :         struct list *macip_path_list;
     196             : };
     197             : 
     198             : /*
     199             :  * Wrapper struct for l3 RT's
     200             :  */
     201             : struct vrf_route_target {
     202             :         /* flags based on config to determine how RTs are handled */
     203             :         uint8_t flags;
     204             : #define BGP_VRF_RT_AUTO (1 << 0)
     205             : #define BGP_VRF_RT_WILD (1 << 1)
     206             : 
     207             :         struct ecommunity *ecom;
     208             : };
     209             : 
     210           0 : static inline int is_vrf_rd_configured(struct bgp *bgp_vrf)
     211             : {
     212           0 :         return (CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_RD_CFGD));
     213             : }
     214             : 
     215           0 : static inline int bgp_evpn_vrf_rd_matches_existing(struct bgp *bgp_vrf,
     216             :                                                    struct prefix_rd *prd)
     217             : {
     218           0 :         return (memcmp(&bgp_vrf->vrf_prd.val, prd->val, ECOMMUNITY_SIZE) == 0);
     219             : }
     220             : 
     221           0 : static inline vni_t bgpevpn_get_l3vni(struct bgpevpn *vpn)
     222             : {
     223           0 :         return vpn->bgp_vrf ? vpn->bgp_vrf->l3vni : 0;
     224             : }
     225             : 
     226             : static inline void bgpevpn_get_rmac(struct bgpevpn *vpn, struct ethaddr *rmac)
     227             : {
     228             :         memset(rmac, 0, sizeof(struct ethaddr));
     229             :         if (!vpn->bgp_vrf)
     230             :                 return;
     231             :         memcpy(rmac, &vpn->bgp_vrf->rmac, sizeof(struct ethaddr));
     232             : }
     233             : 
     234           0 : static inline struct list *bgpevpn_get_vrf_export_rtl(struct bgpevpn *vpn)
     235             : {
     236           0 :         if (!vpn->bgp_vrf)
     237             :                 return NULL;
     238             : 
     239           0 :         return vpn->bgp_vrf->vrf_export_rtl;
     240             : }
     241             : 
     242             : static inline struct list *bgpevpn_get_vrf_import_rtl(struct bgpevpn *vpn)
     243             : {
     244             :         if (!vpn->bgp_vrf)
     245             :                 return NULL;
     246             : 
     247             :         return vpn->bgp_vrf->vrf_import_rtl;
     248             : }
     249             : 
     250             : extern void bgp_evpn_es_evi_vrf_ref(struct bgpevpn *vpn);
     251             : extern void bgp_evpn_es_evi_vrf_deref(struct bgpevpn *vpn);
     252             : 
     253           0 : static inline void bgpevpn_unlink_from_l3vni(struct bgpevpn *vpn)
     254             : {
     255             :         /* bail if vpn is not associated to bgp_vrf */
     256           0 :         if (!vpn->bgp_vrf)
     257             :                 return;
     258             : 
     259           0 :         UNSET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS);
     260           0 :         listnode_delete(vpn->bgp_vrf->l2vnis, vpn);
     261             : 
     262           0 :         bgp_evpn_es_evi_vrf_deref(vpn);
     263             : 
     264             :         /* remove the backpointer to the vrf instance */
     265           0 :         bgp_unlock(vpn->bgp_vrf);
     266           0 :         vpn->bgp_vrf = NULL;
     267             : }
     268             : 
     269           0 : static inline void bgpevpn_link_to_l3vni(struct bgpevpn *vpn)
     270             : {
     271           0 :         struct bgp *bgp_vrf = NULL;
     272             : 
     273             :         /* bail if vpn is already associated to vrf */
     274           0 :         if (vpn->bgp_vrf)
     275             :                 return;
     276             : 
     277           0 :         bgp_vrf = bgp_lookup_by_vrf_id(vpn->tenant_vrf_id);
     278           0 :         if (!bgp_vrf)
     279             :                 return;
     280             : 
     281             :         /* associate the vpn to the bgp_vrf instance */
     282           0 :         vpn->bgp_vrf = bgp_lock(bgp_vrf);
     283           0 :         listnode_add_sort(bgp_vrf->l2vnis, vpn);
     284             : 
     285             :         /*
     286             :          * If L3VNI is configured,
     287             :          * check if we are advertising two labels for this vpn
     288             :          */
     289           0 :         if (bgp_vrf->l3vni &&
     290           0 :             !CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY))
     291           0 :                 SET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS);
     292             : 
     293           0 :         bgp_evpn_es_evi_vrf_ref(vpn);
     294             : }
     295             : 
     296           0 : static inline int is_vni_configured(struct bgpevpn *vpn)
     297             : {
     298           0 :         return (CHECK_FLAG(vpn->flags, VNI_FLAG_CFGD));
     299             : }
     300             : 
     301           0 : static inline int is_vni_live(struct bgpevpn *vpn)
     302             : {
     303           0 :         return (CHECK_FLAG(vpn->flags, VNI_FLAG_LIVE));
     304             : }
     305             : 
     306           0 : static inline int is_l3vni_live(struct bgp *bgp_vrf)
     307             : {
     308           0 :         return (bgp_vrf->l3vni && bgp_vrf->l3vni_svi_ifindex);
     309             : }
     310             : 
     311           0 : static inline int is_rd_configured(struct bgpevpn *vpn)
     312             : {
     313           0 :         return (CHECK_FLAG(vpn->flags, VNI_FLAG_RD_CFGD));
     314             : }
     315             : 
     316           0 : static inline int bgp_evpn_rd_matches_existing(struct bgpevpn *vpn,
     317             :                                                struct prefix_rd *prd)
     318             : {
     319           0 :         return (memcmp(&vpn->prd.val, prd->val, ECOMMUNITY_SIZE) == 0);
     320             : }
     321             : 
     322           0 : static inline int is_import_rt_configured(struct bgpevpn *vpn)
     323             : {
     324           0 :         return (CHECK_FLAG(vpn->flags, VNI_FLAG_IMPRT_CFGD));
     325             : }
     326             : 
     327           0 : static inline int is_export_rt_configured(struct bgpevpn *vpn)
     328             : {
     329           0 :         return (CHECK_FLAG(vpn->flags, VNI_FLAG_EXPRT_CFGD));
     330             : }
     331             : 
     332           0 : static inline void encode_es_rt_extcomm(struct ecommunity_val *eval,
     333             :                                         struct ethaddr *mac)
     334             : {
     335           0 :         memset(eval, 0, sizeof(struct ecommunity_val));
     336           0 :         eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
     337           0 :         eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ES_IMPORT_RT;
     338           0 :         memcpy(&eval->val[2], mac, ETH_ALEN);
     339           0 : }
     340             : 
     341           0 : static inline void encode_df_elect_extcomm(struct ecommunity_val *eval,
     342             :                                            uint16_t pref)
     343             : {
     344           0 :         memset(eval, 0, sizeof(*eval));
     345           0 :         eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
     346           0 :         eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_DF_ELECTION;
     347           0 :         eval->val[2] = EVPN_MH_DF_ALG_PREF;
     348           0 :         eval->val[6] = (pref >> 8) & 0xff;
     349           0 :         eval->val[7] = pref & 0xff;
     350           0 : }
     351             : 
     352           0 : static inline void encode_esi_label_extcomm(struct ecommunity_val *eval,
     353             :                                         bool single_active)
     354             : {
     355           0 :         memset(eval, 0, sizeof(struct ecommunity_val));
     356           0 :         eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
     357           0 :         eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ESI_LABEL;
     358           0 :         if (single_active)
     359             :                 eval->val[2] |= (1 << 0);
     360             : }
     361             : 
     362           0 : static inline void encode_rmac_extcomm(struct ecommunity_val *eval,
     363             :                                        struct ethaddr *rmac)
     364             : {
     365           0 :         memset(eval, 0, sizeof(*eval));
     366           0 :         eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
     367           0 :         eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC;
     368           0 :         memcpy(&eval->val[2], rmac, ETH_ALEN);
     369           0 : }
     370             : 
     371           0 : static inline void encode_default_gw_extcomm(struct ecommunity_val *eval)
     372             : {
     373           0 :         memset(eval, 0, sizeof(*eval));
     374           0 :         eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE;
     375           0 :         eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_DEF_GW;
     376             : }
     377             : 
     378           0 : static inline void encode_mac_mobility_extcomm(int static_mac, uint32_t seq,
     379             :                                                struct ecommunity_val *eval)
     380             : {
     381           0 :         memset(eval, 0, sizeof(*eval));
     382           0 :         eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
     383           0 :         eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY;
     384           0 :         if (static_mac)
     385           0 :                 eval->val[2] = ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY;
     386           0 :         eval->val[4] = (seq >> 24) & 0xff;
     387           0 :         eval->val[5] = (seq >> 16) & 0xff;
     388           0 :         eval->val[6] = (seq >> 8) & 0xff;
     389           0 :         eval->val[7] = seq & 0xff;
     390           0 : }
     391             : 
     392           0 : static inline void encode_na_flag_extcomm(struct ecommunity_val *eval,
     393             :                                           uint8_t na_flag, bool proxy)
     394             : {
     395           0 :         memset(eval, 0, sizeof(*eval));
     396           0 :         eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
     397           0 :         eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ND;
     398           0 :         if (na_flag)
     399           0 :                 eval->val[2] |= ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG;
     400           0 :         if (proxy)
     401           0 :                 eval->val[2] |= ECOMMUNITY_EVPN_SUBTYPE_PROXY_FLAG;
     402           0 : }
     403             : 
     404           0 : static inline void ip_prefix_from_type5_prefix(const struct prefix_evpn *evp,
     405             :                                                struct prefix *ip)
     406             : {
     407           0 :         memset(ip, 0, sizeof(struct prefix));
     408           0 :         if (is_evpn_prefix_ipaddr_v4(evp)) {
     409           0 :                 ip->family = AF_INET;
     410           0 :                 ip->prefixlen = evp->prefix.prefix_addr.ip_prefix_length;
     411           0 :                 memcpy(&(ip->u.prefix4), &(evp->prefix.prefix_addr.ip.ip),
     412             :                        IPV4_MAX_BYTELEN);
     413           0 :         } else if (is_evpn_prefix_ipaddr_v6(evp)) {
     414           0 :                 ip->family = AF_INET6;
     415           0 :                 ip->prefixlen = evp->prefix.prefix_addr.ip_prefix_length;
     416           0 :                 memcpy(&(ip->u.prefix6), &(evp->prefix.prefix_addr.ip.ip),
     417             :                        IPV6_MAX_BYTELEN);
     418             :         }
     419           0 : }
     420             : 
     421           0 : static inline int is_evpn_prefix_default(const struct prefix *evp)
     422             : {
     423           0 :         if (evp->family != AF_EVPN)
     424             :                 return 0;
     425             : 
     426           0 :         return ((evp->u.prefix_evpn.prefix_addr.ip_prefix_length  == 0) ?
     427           0 :                 1 : 0);
     428             : }
     429             : 
     430           0 : static inline void ip_prefix_from_type2_prefix(const struct prefix_evpn *evp,
     431             :                                                struct prefix *ip)
     432             : {
     433           0 :         memset(ip, 0, sizeof(struct prefix));
     434           0 :         if (is_evpn_prefix_ipaddr_v4(evp)) {
     435           0 :                 ip->family = AF_INET;
     436           0 :                 ip->prefixlen = IPV4_MAX_BITLEN;
     437           0 :                 memcpy(&(ip->u.prefix4), &(evp->prefix.macip_addr.ip.ip),
     438             :                        IPV4_MAX_BYTELEN);
     439           0 :         } else if (is_evpn_prefix_ipaddr_v6(evp)) {
     440           0 :                 ip->family = AF_INET6;
     441           0 :                 ip->prefixlen = IPV6_MAX_BITLEN;
     442           0 :                 memcpy(&(ip->u.prefix6), &(evp->prefix.macip_addr.ip.ip),
     443             :                        IPV6_MAX_BYTELEN);
     444             :         }
     445           0 : }
     446             : 
     447           0 : static inline void ip_prefix_from_evpn_prefix(const struct prefix_evpn *evp,
     448             :                                               struct prefix *ip)
     449             : {
     450           0 :         if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
     451           0 :                 ip_prefix_from_type2_prefix(evp, ip);
     452           0 :         else if (evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE)
     453           0 :                 ip_prefix_from_type5_prefix(evp, ip);
     454           0 : }
     455             : 
     456           0 : static inline void build_evpn_type2_prefix(struct prefix_evpn *p,
     457             :                                            struct ethaddr *mac,
     458             :                                            struct ipaddr *ip)
     459             : {
     460           0 :         memset(p, 0, sizeof(struct prefix_evpn));
     461           0 :         p->family = AF_EVPN;
     462           0 :         p->prefixlen = EVPN_ROUTE_PREFIXLEN;
     463           0 :         p->prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
     464           0 :         memcpy(&p->prefix.macip_addr.mac.octet, mac->octet, ETH_ALEN);
     465           0 :         p->prefix.macip_addr.ip.ipa_type = IPADDR_NONE;
     466           0 :         memcpy(&p->prefix.macip_addr.ip, ip, sizeof(*ip));
     467           0 : }
     468             : 
     469             : static inline void
     470           0 : build_type5_prefix_from_ip_prefix(struct prefix_evpn *evp,
     471             :                                   const struct prefix *ip_prefix)
     472             : {
     473           0 :         struct ipaddr ip;
     474             : 
     475           0 :         memset(&ip, 0, sizeof(struct ipaddr));
     476           0 :         if (ip_prefix->family == AF_INET) {
     477           0 :                 ip.ipa_type = IPADDR_V4;
     478           0 :                 memcpy(&ip.ipaddr_v4, &ip_prefix->u.prefix4,
     479             :                        sizeof(struct in_addr));
     480             :         } else {
     481           0 :                 ip.ipa_type = IPADDR_V6;
     482           0 :                 memcpy(&ip.ipaddr_v6, &ip_prefix->u.prefix6,
     483             :                        sizeof(struct in6_addr));
     484             :         }
     485             : 
     486           0 :         memset(evp, 0, sizeof(struct prefix_evpn));
     487           0 :         evp->family = AF_EVPN;
     488           0 :         evp->prefixlen = EVPN_ROUTE_PREFIXLEN;
     489           0 :         evp->prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE;
     490           0 :         evp->prefix.prefix_addr.ip_prefix_length = ip_prefix->prefixlen;
     491           0 :         evp->prefix.prefix_addr.ip.ipa_type = ip.ipa_type;
     492           0 :         memcpy(&evp->prefix.prefix_addr.ip, &ip, sizeof(struct ipaddr));
     493           0 : }
     494             : 
     495           0 : static inline void build_evpn_type3_prefix(struct prefix_evpn *p,
     496             :                                            struct in_addr originator_ip)
     497             : {
     498           0 :         memset(p, 0, sizeof(struct prefix_evpn));
     499           0 :         p->family = AF_EVPN;
     500           0 :         p->prefixlen = EVPN_ROUTE_PREFIXLEN;
     501           0 :         p->prefix.route_type = BGP_EVPN_IMET_ROUTE;
     502           0 :         p->prefix.imet_addr.ip.ipa_type = IPADDR_V4;
     503           0 :         p->prefix.imet_addr.ip.ipaddr_v4 = originator_ip;
     504           0 : }
     505             : 
     506           0 : static inline void build_evpn_type4_prefix(struct prefix_evpn *p,
     507             :                                            esi_t *esi,
     508             :                                            struct in_addr originator_ip)
     509             : {
     510           0 :         memset(p, 0, sizeof(struct prefix_evpn));
     511           0 :         p->family = AF_EVPN;
     512           0 :         p->prefixlen = EVPN_ROUTE_PREFIXLEN;
     513           0 :         p->prefix.route_type = BGP_EVPN_ES_ROUTE;
     514           0 :         p->prefix.es_addr.ip_prefix_length = IPV4_MAX_BITLEN;
     515           0 :         p->prefix.es_addr.ip.ipa_type = IPADDR_V4;
     516           0 :         p->prefix.es_addr.ip.ipaddr_v4 = originator_ip;
     517           0 :         memcpy(&p->prefix.es_addr.esi, esi, sizeof(esi_t));
     518           0 : }
     519             : 
     520           0 : static inline void build_evpn_type1_prefix(struct prefix_evpn *p,
     521             :                 uint32_t eth_tag,
     522             :                 esi_t *esi,
     523             :                 struct in_addr originator_ip)
     524             : {
     525           0 :         memset(p, 0, sizeof(struct prefix_evpn));
     526           0 :         p->family = AF_EVPN;
     527           0 :         p->prefixlen = EVPN_ROUTE_PREFIXLEN;
     528           0 :         p->prefix.route_type = BGP_EVPN_AD_ROUTE;
     529           0 :         p->prefix.ead_addr.eth_tag = eth_tag;
     530           0 :         p->prefix.ead_addr.ip.ipa_type = IPADDR_V4;
     531           0 :         p->prefix.ead_addr.ip.ipaddr_v4 = originator_ip;
     532           0 :         memcpy(&p->prefix.ead_addr.esi, esi, sizeof(esi_t));
     533           0 : }
     534             : 
     535           0 : static inline void evpn_type1_prefix_global_copy(struct prefix_evpn *global_p,
     536             :                 const struct prefix_evpn *vni_p)
     537             : {
     538           0 :         memcpy(global_p, vni_p, sizeof(*global_p));
     539           0 :         global_p->prefix.ead_addr.ip.ipa_type = 0;
     540           0 :         global_p->prefix.ead_addr.ip.ipaddr_v4.s_addr = INADDR_ANY;
     541           0 :         global_p->prefix.ead_addr.frag_id = 0;
     542             : }
     543             : 
     544             : /* EAD prefix in the global table doesn't include the VTEP-IP so
     545             :  * we need to create a different copy for the VNI
     546             :  */
     547             : static inline struct prefix_evpn *
     548           0 : evpn_type1_prefix_vni_ip_copy(struct prefix_evpn *vni_p,
     549             :                               const struct prefix_evpn *global_p,
     550             :                               struct in_addr originator_ip)
     551             : {
     552           0 :         memcpy(vni_p, global_p, sizeof(*vni_p));
     553           0 :         vni_p->prefix.ead_addr.ip.ipa_type = IPADDR_V4;
     554           0 :         vni_p->prefix.ead_addr.ip.ipaddr_v4 = originator_ip;
     555             : 
     556           0 :         return vni_p;
     557             : }
     558             : 
     559           0 : static inline void evpn_type2_prefix_global_copy(
     560             :         struct prefix_evpn *global_p, const struct prefix_evpn *vni_p,
     561             :         const struct ethaddr *mac, const struct ipaddr *ip)
     562             : {
     563           0 :         memcpy(global_p, vni_p, sizeof(*global_p));
     564             : 
     565           0 :         if (mac)
     566           0 :                 global_p->prefix.macip_addr.mac = *mac;
     567             : 
     568           0 :         if (ip)
     569           0 :                 global_p->prefix.macip_addr.ip = *ip;
     570           0 : }
     571             : 
     572             : static inline void
     573           0 : evpn_type2_prefix_vni_ip_copy(struct prefix_evpn *vni_p,
     574             :                               const struct prefix_evpn *global_p)
     575             : {
     576           0 :         memcpy(vni_p, global_p, sizeof(*vni_p));
     577           0 :         memset(&vni_p->prefix.macip_addr.mac, 0, sizeof(struct ethaddr));
     578           0 : }
     579             : 
     580             : static inline void
     581           0 : evpn_type2_prefix_vni_mac_copy(struct prefix_evpn *vni_p,
     582             :                                const struct prefix_evpn *global_p)
     583             : {
     584           0 :         memcpy(vni_p, global_p, sizeof(*vni_p));
     585           0 :         memset(&vni_p->prefix.macip_addr.ip, 0, sizeof(struct ipaddr));
     586           0 : }
     587             : 
     588             : /* Get MAC of path_info prefix */
     589             : static inline struct ethaddr *
     590           0 : evpn_type2_path_info_get_mac(const struct bgp_path_info *local_pi)
     591             : {
     592           0 :         assert(local_pi->extra);
     593           0 :         return &local_pi->extra->vni_info.mac;
     594             : }
     595             : 
     596             : /* Get IP of path_info prefix */
     597             : static inline struct ipaddr *
     598           0 : evpn_type2_path_info_get_ip(const struct bgp_path_info *local_pi)
     599             : {
     600           0 :         assert(local_pi->extra);
     601           0 :         return &local_pi->extra->vni_info.ip;
     602             : }
     603             : 
     604             : /* Set MAC of path_info prefix */
     605           0 : static inline void evpn_type2_path_info_set_mac(struct bgp_path_info *local_pi,
     606             :                                                 const struct ethaddr mac)
     607             : {
     608           0 :         assert(local_pi->extra);
     609           0 :         local_pi->extra->vni_info.mac = mac;
     610           0 : }
     611             : 
     612             : /* Set IP of path_info prefix */
     613           0 : static inline void evpn_type2_path_info_set_ip(struct bgp_path_info *local_pi,
     614             :                                                const struct ipaddr ip)
     615             : {
     616           0 :         assert(local_pi->extra);
     617           0 :         local_pi->extra->vni_info.ip = ip;
     618           0 : }
     619             : 
     620             : /* Is the IP empty for the RT's dest? */
     621           0 : static inline bool is_evpn_type2_dest_ipaddr_none(const struct bgp_dest *dest)
     622             : {
     623           0 :         const struct prefix_evpn *evp =
     624           0 :                 (const struct prefix_evpn *)bgp_dest_get_prefix(dest);
     625             : 
     626           0 :         assert(evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE);
     627           0 :         return is_evpn_prefix_ipaddr_none(evp);
     628             : }
     629             : 
     630           0 : static inline int evpn_default_originate_set(struct bgp *bgp, afi_t afi,
     631             :                                              safi_t safi)
     632             : {
     633           0 :         if (afi == AFI_IP &&
     634           0 :             CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
     635             :                        BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4))
     636             :                 return 1;
     637           0 :         else if (afi == AFI_IP6 &&
     638           0 :                  CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
     639             :                             BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6))
     640           0 :                 return 1;
     641             :         return 0;
     642             : }
     643             : 
     644           0 : static inline void es_get_system_mac(esi_t *esi,
     645             :                                      struct ethaddr *mac)
     646             : {
     647             :         /*
     648             :          * for type-1 and type-3 ESIs,
     649             :          * the system mac starts at val[1]
     650             :          */
     651           0 :         memcpy(mac, &esi->val[1], ETH_ALEN);
     652             : }
     653             : 
     654           0 : static inline bool bgp_evpn_is_svi_macip_enabled(struct bgpevpn *vpn)
     655             : {
     656           0 :         struct bgp *bgp_evpn = NULL;
     657             : 
     658           0 :         bgp_evpn = bgp_get_evpn();
     659             : 
     660           0 :         return (bgp_evpn->evpn_info->advertise_svi_macip ||
     661           0 :                 vpn->advertise_svi_macip);
     662             : }
     663             : 
     664           0 : static inline bool bgp_evpn_is_path_local(struct bgp *bgp,
     665             :                 struct bgp_path_info *pi)
     666             : {
     667           0 :         return (pi->peer == bgp->peer_self
     668             :                         && pi->type == ZEBRA_ROUTE_BGP
     669           0 :                         && pi->sub_type == BGP_ROUTE_STATIC);
     670             : }
     671             : 
     672             : extern struct zclient *zclient;
     673             : 
     674             : extern void bgp_evpn_install_uninstall_default_route(struct bgp *bgp_vrf,
     675             :                                                      afi_t afi, safi_t safi,
     676             :                                                      bool add);
     677             : extern void evpn_rt_delete_auto(struct bgp *bgp, vni_t vni, struct list *rtl,
     678             :                                 bool is_l3);
     679             : extern void bgp_evpn_configure_export_rt_for_vrf(struct bgp *bgp_vrf,
     680             :                                                  struct ecommunity *ecomadd);
     681             : extern void bgp_evpn_configure_export_auto_rt_for_vrf(struct bgp *bgp_vrf);
     682             : extern void bgp_evpn_unconfigure_export_rt_for_vrf(struct bgp *bgp_vrf,
     683             :                                                    struct ecommunity *ecomdel);
     684             : extern void bgp_evpn_unconfigure_export_auto_rt_for_vrf(struct bgp *bgp_vrf);
     685             : extern void bgp_evpn_configure_import_rt_for_vrf(struct bgp *bgp_vrf,
     686             :                                                  struct ecommunity *ecomadd,
     687             :                                                  bool is_wildcard);
     688             : extern void bgp_evpn_configure_import_auto_rt_for_vrf(struct bgp *bgp_vrf);
     689             : extern void bgp_evpn_unconfigure_import_rt_for_vrf(struct bgp *bgp_vrf,
     690             :                                                    struct ecommunity *ecomdel);
     691             : extern void bgp_evpn_unconfigure_import_auto_rt_for_vrf(struct bgp *bgp_vrf);
     692             : extern int bgp_evpn_handle_export_rt_change(struct bgp *bgp,
     693             :                                             struct bgpevpn *vpn);
     694             : extern void bgp_evpn_handle_autort_change(struct bgp *bgp);
     695             : extern void bgp_evpn_handle_vrf_rd_change(struct bgp *bgp_vrf, int withdraw);
     696             : extern void bgp_evpn_handle_rd_change(struct bgp *bgp, struct bgpevpn *vpn,
     697             :                                       int withdraw);
     698             : extern int bgp_evpn_install_routes(struct bgp *bgp, struct bgpevpn *vpn);
     699             : extern int bgp_evpn_uninstall_routes(struct bgp *bgp, struct bgpevpn *vpn);
     700             : extern void bgp_evpn_map_vrf_to_its_rts(struct bgp *bgp_vrf);
     701             : extern void bgp_evpn_unmap_vrf_from_its_rts(struct bgp *bgp_vrf);
     702             : extern void bgp_evpn_map_vni_to_its_rts(struct bgp *bgp, struct bgpevpn *vpn);
     703             : extern void bgp_evpn_unmap_vni_from_its_rts(struct bgp *bgp,
     704             :                                             struct bgpevpn *vpn);
     705             : extern void bgp_evpn_derive_auto_rt_import(struct bgp *bgp,
     706             :                                            struct bgpevpn *vpn);
     707             : extern void bgp_evpn_derive_auto_rt_export(struct bgp *bgp,
     708             :                                            struct bgpevpn *vpn);
     709             : extern void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn);
     710             : extern void bgp_evpn_derive_auto_rd_for_vrf(struct bgp *bgp);
     711             : extern struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni);
     712             : extern struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
     713             :                 struct in_addr originator_ip,
     714             :                 vrf_id_t tenant_vrf_id,
     715             :                 struct in_addr mcast_grp,
     716             :                 ifindex_t svi_ifindex);
     717             : extern void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn);
     718             : extern bool bgp_evpn_lookup_l3vni_l2vni_table(vni_t vni);
     719             : extern int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn);
     720             : extern void delete_evpn_route_entry(struct bgp *bgp, afi_t afi, safi_t safi,
     721             :                                     struct bgp_dest *dest,
     722             :                                     struct bgp_path_info **pi);
     723             : int vni_list_cmp(void *p1, void *p2);
     724             : extern int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
     725             :                                      struct bgp_dest *dest);
     726             : extern struct bgp_dest *
     727             : bgp_evpn_global_node_get(struct bgp_table *table, afi_t afi, safi_t safi,
     728             :                          const struct prefix_evpn *evp, struct prefix_rd *prd,
     729             :                          const struct bgp_path_info *local_pi);
     730             : extern struct bgp_dest *
     731             : bgp_evpn_global_node_lookup(struct bgp_table *table, afi_t afi, safi_t safi,
     732             :                             const struct prefix_evpn *evp,
     733             :                             struct prefix_rd *prd,
     734             :                             const struct bgp_path_info *local_pi);
     735             : extern struct bgp_dest *
     736             : bgp_evpn_vni_ip_node_get(struct bgp_table *const table,
     737             :                          const struct prefix_evpn *evp,
     738             :                          const struct bgp_path_info *parent_pi);
     739             : extern struct bgp_dest *
     740             : bgp_evpn_vni_ip_node_lookup(const struct bgp_table *const table,
     741             :                             const struct prefix_evpn *evp,
     742             :                             const struct bgp_path_info *parent_pi);
     743             : extern struct bgp_dest *
     744             : bgp_evpn_vni_mac_node_get(struct bgp_table *const table,
     745             :                           const struct prefix_evpn *evp,
     746             :                           const struct bgp_path_info *parent_pi);
     747             : extern struct bgp_dest *
     748             : bgp_evpn_vni_mac_node_lookup(const struct bgp_table *const table,
     749             :                              const struct prefix_evpn *evp,
     750             :                              const struct bgp_path_info *parent_pi);
     751             : extern struct bgp_dest *
     752             : bgp_evpn_vni_node_get(struct bgpevpn *vpn, const struct prefix_evpn *p,
     753             :                       const struct bgp_path_info *parent_pi);
     754             : extern struct bgp_dest *
     755             : bgp_evpn_vni_node_lookup(const struct bgpevpn *vpn, const struct prefix_evpn *p,
     756             :                          const struct bgp_path_info *parent_pi);
     757             : 
     758             : extern void bgp_evpn_import_route_in_vrfs(struct bgp_path_info *pi, int import);
     759             : extern void bgp_evpn_update_type2_route_entry(struct bgp *bgp,
     760             :                                               struct bgpevpn *vpn,
     761             :                                               struct bgp_node *rn,
     762             :                                               struct bgp_path_info *local_pi,
     763             :                                               const char *caller);
     764             : extern int bgp_evpn_route_entry_install_if_vrf_match(struct bgp *bgp_vrf,
     765             :                                                      struct bgp_path_info *pi,
     766             :                                                      int install);
     767             : extern void bgp_evpn_import_type2_route(struct bgp_path_info *pi, int import);
     768             : extern void bgp_evpn_xxport_delete_ecomm(void *val);
     769             : extern int bgp_evpn_route_target_cmp(struct ecommunity *ecom1,
     770             :                                      struct ecommunity *ecom2);
     771             : #endif /* _BGP_EVPN_PRIVATE_H */

Generated by: LCOV version v1.16-topotato