1 /* Ethernet-VPN Packet and vty Processing File
2 * Copyright (C) 2016 6WIND
3 * Copyright (C) 2017 Cumulus Networks, Inc.
5 * This file is part of FRR.
7 * FRRouting is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * FRRouting is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "bgpd/bgp_attr_evpn.h"
35 #include "bgpd/bgpd.h"
36 #include "bgpd/bgp_table.h"
37 #include "bgpd/bgp_route.h"
38 #include "bgpd/bgp_attr.h"
39 #include "bgpd/bgp_mplsvpn.h"
40 #include "bgpd/bgp_label.h"
41 #include "bgpd/bgp_evpn.h"
42 #include "bgpd/bgp_evpn_private.h"
43 #include "bgpd/bgp_ecommunity.h"
44 #include "bgpd/bgp_encap_types.h"
45 #include "bgpd/bgp_debug.h"
46 #include "bgpd/bgp_errors.h"
47 #include "bgpd/bgp_aspath.h"
48 #include "bgpd/bgp_zebra.h"
49 #include "bgpd/bgp_nexthop.h"
52 * Definitions and external declarations.
54 extern struct zclient
*zclient
;
56 DEFINE_QOBJ_TYPE(bgpevpn
)
57 DEFINE_QOBJ_TYPE(evpnes
)
61 * Static function declarations
63 static void delete_evpn_route_entry(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
65 struct bgp_path_info
**pi
);
66 static int delete_all_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
);
72 /* compare two IPV4 VTEP IPs */
73 static int evpn_vtep_ip_cmp(void *p1
, void *p2
)
75 const struct in_addr
*ip1
= p1
;
76 const struct in_addr
*ip2
= p2
;
78 return ip1
->s_addr
- ip2
->s_addr
;
82 * Make hash key for ESI.
84 static unsigned int esi_hash_keymake(void *p
)
86 struct evpnes
*pes
= p
;
87 const void *pnt
= (void *)pes
->esi
.val
;
89 return jhash(pnt
, ESI_BYTES
, 0xa5a5a55a);
95 static bool esi_cmp(const void *p1
, const void *p2
)
97 const struct evpnes
*pes1
= p1
;
98 const struct evpnes
*pes2
= p2
;
100 if (pes1
== NULL
&& pes2
== NULL
)
103 if (pes1
== NULL
|| pes2
== NULL
)
106 return (memcmp(pes1
->esi
.val
, pes2
->esi
.val
, ESI_BYTES
) == 0);
112 static unsigned int vni_hash_key_make(void *p
)
114 struct bgpevpn
*vpn
= p
;
115 return (jhash_1word(vpn
->vni
, 0));
119 * Comparison function for vni hash
121 static bool vni_hash_cmp(const void *p1
, const void *p2
)
123 const struct bgpevpn
*vpn1
= p1
;
124 const struct bgpevpn
*vpn2
= p2
;
130 return (vpn1
->vni
== vpn2
->vni
);
133 static int vni_list_cmp(void *p1
, void *p2
)
135 const struct bgpevpn
*vpn1
= p1
;
136 const struct bgpevpn
*vpn2
= p2
;
138 return vpn1
->vni
- vpn2
->vni
;
142 * Make vrf import route target hash key.
144 static unsigned int vrf_import_rt_hash_key_make(void *p
)
146 struct vrf_irt_node
*irt
= p
;
147 char *pnt
= irt
->rt
.val
;
149 return jhash(pnt
, 8, 0x5abc1234);
153 * Comparison function for vrf import rt hash
155 static bool vrf_import_rt_hash_cmp(const void *p1
, const void *p2
)
157 const struct vrf_irt_node
*irt1
= p1
;
158 const struct vrf_irt_node
*irt2
= p2
;
160 if (irt1
== NULL
&& irt2
== NULL
)
163 if (irt1
== NULL
|| irt2
== NULL
)
166 return (memcmp(irt1
->rt
.val
, irt2
->rt
.val
, ECOMMUNITY_SIZE
) == 0);
170 * Create a new vrf import_rt in default instance
172 static struct vrf_irt_node
*vrf_import_rt_new(struct ecommunity_val
*rt
)
174 struct bgp
*bgp_def
= NULL
;
175 struct vrf_irt_node
*irt
;
177 bgp_def
= bgp_get_default();
179 flog_err(EC_BGP_NO_DFLT
,
180 "vrf import rt new - def instance not created yet");
184 irt
= XCALLOC(MTYPE_BGP_EVPN_VRF_IMPORT_RT
,
185 sizeof(struct vrf_irt_node
));
190 irt
->vrfs
= list_new();
193 if (!hash_get(bgp_def
->vrf_import_rt_hash
, irt
, hash_alloc_intern
)) {
194 XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT
, irt
);
202 * Free the vrf import rt node
204 static void vrf_import_rt_free(struct vrf_irt_node
*irt
)
206 struct bgp
*bgp_def
= NULL
;
208 bgp_def
= bgp_get_default();
210 flog_err(EC_BGP_NO_DFLT
,
211 "vrf import rt free - def instance not created yet");
215 hash_release(bgp_def
->vrf_import_rt_hash
, irt
);
216 list_delete(&irt
->vrfs
);
217 XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT
, irt
);
221 * Function to lookup Import RT node - used to map a RT to set of
222 * VNIs importing routes with that RT.
224 static struct vrf_irt_node
*lookup_vrf_import_rt(struct ecommunity_val
*rt
)
226 struct bgp
*bgp_def
= NULL
;
227 struct vrf_irt_node
*irt
;
228 struct vrf_irt_node tmp
;
230 bgp_def
= bgp_get_default();
232 flog_err(EC_BGP_NO_DFLT
,
233 "vrf import rt lookup - def instance not created yet");
237 memset(&tmp
, 0, sizeof(struct vrf_irt_node
));
238 memcpy(&tmp
.rt
, rt
, ECOMMUNITY_SIZE
);
239 irt
= hash_lookup(bgp_def
->vrf_import_rt_hash
, &tmp
);
244 * Is specified VRF present on the RT's list of "importing" VRFs?
246 static int is_vrf_present_in_irt_vrfs(struct list
*vrfs
, struct bgp
*bgp_vrf
)
248 struct listnode
*node
= NULL
, *nnode
= NULL
;
249 struct bgp
*tmp_bgp_vrf
= NULL
;
251 for (ALL_LIST_ELEMENTS(vrfs
, node
, nnode
, tmp_bgp_vrf
)) {
252 if (tmp_bgp_vrf
== bgp_vrf
)
259 * Make import route target hash key.
261 static unsigned int import_rt_hash_key_make(void *p
)
263 struct irt_node
*irt
= p
;
264 char *pnt
= irt
->rt
.val
;
266 return jhash(pnt
, 8, 0xdeadbeef);
270 * Comparison function for import rt hash
272 static bool import_rt_hash_cmp(const void *p1
, const void *p2
)
274 const struct irt_node
*irt1
= p1
;
275 const struct irt_node
*irt2
= p2
;
277 if (irt1
== NULL
&& irt2
== NULL
)
280 if (irt1
== NULL
|| irt2
== NULL
)
283 return (memcmp(irt1
->rt
.val
, irt2
->rt
.val
, ECOMMUNITY_SIZE
) == 0);
287 * Create a new import_rt
289 static struct irt_node
*import_rt_new(struct bgp
*bgp
,
290 struct ecommunity_val
*rt
)
292 struct irt_node
*irt
;
297 irt
= XCALLOC(MTYPE_BGP_EVPN_IMPORT_RT
, sizeof(struct irt_node
));
302 irt
->vnis
= list_new();
305 if (!hash_get(bgp
->import_rt_hash
, irt
, hash_alloc_intern
)) {
306 XFREE(MTYPE_BGP_EVPN_IMPORT_RT
, irt
);
314 * Free the import rt node
316 static void import_rt_free(struct bgp
*bgp
, struct irt_node
*irt
)
318 hash_release(bgp
->import_rt_hash
, irt
);
319 list_delete(&irt
->vnis
);
320 XFREE(MTYPE_BGP_EVPN_IMPORT_RT
, irt
);
324 * Function to lookup Import RT node - used to map a RT to set of
325 * VNIs importing routes with that RT.
327 static struct irt_node
*lookup_import_rt(struct bgp
*bgp
,
328 struct ecommunity_val
*rt
)
330 struct irt_node
*irt
;
333 memset(&tmp
, 0, sizeof(struct irt_node
));
334 memcpy(&tmp
.rt
, rt
, ECOMMUNITY_SIZE
);
335 irt
= hash_lookup(bgp
->import_rt_hash
, &tmp
);
340 * Is specified VNI present on the RT's list of "importing" VNIs?
342 static int is_vni_present_in_irt_vnis(struct list
*vnis
, struct bgpevpn
*vpn
)
344 struct listnode
*node
, *nnode
;
345 struct bgpevpn
*tmp_vpn
;
347 for (ALL_LIST_ELEMENTS(vnis
, node
, nnode
, tmp_vpn
)) {
356 * Compare Route Targets.
358 static int evpn_route_target_cmp(struct ecommunity
*ecom1
,
359 struct ecommunity
*ecom2
)
367 if (!ecom1
&& !ecom2
)
370 if (ecom1
->str
&& !ecom2
->str
)
373 if (!ecom1
->str
&& ecom2
->str
)
376 if (!ecom1
->str
&& !ecom2
->str
)
379 return strcmp(ecom1
->str
, ecom2
->str
);
382 static void evpn_xxport_delete_ecomm(void *val
)
384 struct ecommunity
*ecomm
= val
;
385 ecommunity_free(&ecomm
);
389 * Mask off global-admin field of specified extended community (RT),
390 * just retain the local-admin field.
392 static inline void mask_ecom_global_admin(struct ecommunity_val
*dst
,
393 struct ecommunity_val
*src
)
399 if (type
== ECOMMUNITY_ENCODE_AS
) {
400 dst
->val
[2] = dst
->val
[3] = 0;
401 } else if (type
== ECOMMUNITY_ENCODE_AS4
402 || type
== ECOMMUNITY_ENCODE_IP
) {
403 dst
->val
[2] = dst
->val
[3] = 0;
404 dst
->val
[4] = dst
->val
[5] = 0;
409 * Map one RT to specified VRF.
410 * bgp_vrf = BGP vrf instance
412 static void map_vrf_to_rt(struct bgp
*bgp_vrf
, struct ecommunity_val
*eval
)
414 struct vrf_irt_node
*irt
= NULL
;
415 struct ecommunity_val eval_tmp
;
417 /* If using "automatic" RT,
418 * we only care about the local-admin sub-field.
419 * This is to facilitate using L3VNI(VRF-VNI)
420 * as the RT for EBGP peering too.
422 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
423 if (!CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_IMPORT_RT_CFGD
))
424 mask_ecom_global_admin(&eval_tmp
, eval
);
426 irt
= lookup_vrf_import_rt(&eval_tmp
);
427 if (irt
&& is_vrf_present_in_irt_vrfs(irt
->vrfs
, bgp_vrf
))
428 /* Already mapped. */
432 irt
= vrf_import_rt_new(&eval_tmp
);
434 /* Add VRF to the list for this RT. */
435 listnode_add(irt
->vrfs
, bgp_vrf
);
439 * Unmap specified VRF from specified RT. If there are no other
440 * VRFs for this RT, then the RT hash is deleted.
441 * bgp_vrf: BGP VRF specific instance
443 static void unmap_vrf_from_rt(struct bgp
*bgp_vrf
, struct vrf_irt_node
*irt
)
445 /* Delete VRF from list for this RT. */
446 listnode_delete(irt
->vrfs
, bgp_vrf
);
447 if (!listnode_head(irt
->vrfs
)) {
448 vrf_import_rt_free(irt
);
453 * Map one RT to specified VNI.
455 static void map_vni_to_rt(struct bgp
*bgp
, struct bgpevpn
*vpn
,
456 struct ecommunity_val
*eval
)
458 struct irt_node
*irt
;
459 struct ecommunity_val eval_tmp
;
461 /* If using "automatic" RT, we only care about the local-admin
463 * This is to facilitate using VNI as the RT for EBGP peering too.
465 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
466 if (!is_import_rt_configured(vpn
))
467 mask_ecom_global_admin(&eval_tmp
, eval
);
469 irt
= lookup_import_rt(bgp
, &eval_tmp
);
471 if (is_vni_present_in_irt_vnis(irt
->vnis
, vpn
))
472 /* Already mapped. */
476 irt
= import_rt_new(bgp
, &eval_tmp
);
480 /* Add VNI to the hash list for this RT. */
481 listnode_add(irt
->vnis
, vpn
);
485 * Unmap specified VNI from specified RT. If there are no other
486 * VNIs for this RT, then the RT hash is deleted.
488 static void unmap_vni_from_rt(struct bgp
*bgp
, struct bgpevpn
*vpn
,
489 struct irt_node
*irt
)
491 /* Delete VNI from hash list for this RT. */
492 listnode_delete(irt
->vnis
, vpn
);
493 if (!listnode_head(irt
->vnis
)) {
494 import_rt_free(bgp
, irt
);
499 * Create RT extended community automatically from passed information:
500 * of the form AS:VNI.
501 * NOTE: We use only the lower 16 bits of the AS. This is sufficient as
502 * the need is to get a RT value that will be unique across different
503 * VNIs but the same across routers (in the same AS) for a particular
506 static void form_auto_rt(struct bgp
*bgp
, vni_t vni
, struct list
*rtl
)
508 struct ecommunity_val eval
;
509 struct ecommunity
*ecomadd
;
511 if (bgp
->advertise_autort_rfc8365
)
512 vni
|= EVPN_AUTORT_VXLAN
;
513 encode_route_target_as((bgp
->as
& 0xFFFF), vni
, &eval
);
515 ecomadd
= ecommunity_new();
516 ecommunity_add_val(ecomadd
, &eval
);
517 listnode_add_sort(rtl
, ecomadd
);
521 * Derive RD and RT for a VNI automatically. Invoked at the time of
524 static void derive_rd_rt_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
526 bgp_evpn_derive_auto_rd(bgp
, vpn
);
527 bgp_evpn_derive_auto_rt_import(bgp
, vpn
);
528 bgp_evpn_derive_auto_rt_export(bgp
, vpn
);
532 * Convert nexthop (remote VTEP IP) into an IPv6 address.
534 static void evpn_convert_nexthop_to_ipv6(struct attr
*attr
)
536 if (BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
538 ipv4_to_ipv4_mapped_ipv6(&attr
->mp_nexthop_global
, attr
->nexthop
);
539 attr
->mp_nexthop_len
= IPV6_MAX_BYTELEN
;
543 * Add (update) or delete MACIP from zebra.
545 static int bgp_zebra_send_remote_macip(struct bgp
*bgp
, struct bgpevpn
*vpn
,
546 struct prefix_evpn
*p
,
547 struct in_addr remote_vtep_ip
, int add
,
548 uint8_t flags
, uint32_t seq
)
552 char buf1
[ETHER_ADDR_STRLEN
];
553 char buf2
[INET6_ADDRSTRLEN
];
554 char buf3
[INET6_ADDRSTRLEN
];
557 if (!zclient
|| zclient
->sock
< 0)
560 /* Don't try to register if Zebra doesn't know of this instance. */
561 if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
562 if (BGP_DEBUG(zebra
, ZEBRA
))
563 zlog_debug("%s: No zebra instance to talk to, not installing remote macip",
564 __PRETTY_FUNCTION__
);
570 zclient_create_header(
571 s
, add
? ZEBRA_REMOTE_MACIP_ADD
: ZEBRA_REMOTE_MACIP_DEL
,
573 stream_putl(s
, vpn
->vni
);
574 stream_put(s
, &p
->prefix
.macip_addr
.mac
.octet
, ETH_ALEN
); /* Mac Addr */
575 /* IP address length and IP address, if any. */
576 if (is_evpn_prefix_ipaddr_none(p
))
579 ipa_len
= is_evpn_prefix_ipaddr_v4(p
) ? IPV4_MAX_BYTELEN
581 stream_putl(s
, ipa_len
);
582 stream_put(s
, &p
->prefix
.macip_addr
.ip
.ip
.addr
, ipa_len
);
584 stream_put_in_addr(s
, &remote_vtep_ip
);
586 /* TX flags - MAC sticky status and/or gateway mac */
587 /* Also TX the sequence number of the best route. */
589 stream_putc(s
, flags
);
593 stream_putw_at(s
, 0, stream_get_endp(s
));
595 if (bgp_debug_zebra(NULL
))
597 "Tx %s MACIP, VNI %u MAC %s IP %s flags 0x%x seq %u remote VTEP %s",
598 add
? "ADD" : "DEL", vpn
->vni
,
599 prefix_mac2str(&p
->prefix
.macip_addr
.mac
,
601 ipaddr2str(&p
->prefix
.macip_addr
.ip
,
602 buf3
, sizeof(buf3
)), flags
, seq
,
603 inet_ntop(AF_INET
, &remote_vtep_ip
, buf2
,
606 return zclient_send_message(zclient
);
610 * Add (update) or delete remote VTEP from zebra.
612 static int bgp_zebra_send_remote_vtep(struct bgp
*bgp
, struct bgpevpn
*vpn
,
613 struct prefix_evpn
*p
, int add
)
618 if (!zclient
|| zclient
->sock
< 0)
621 /* Don't try to register if Zebra doesn't know of this instance. */
622 if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
623 if (BGP_DEBUG(zebra
, ZEBRA
))
624 zlog_debug("%s: No zebra instance to talk to, not installing remote vtep",
625 __PRETTY_FUNCTION__
);
632 zclient_create_header(
633 s
, add
? ZEBRA_REMOTE_VTEP_ADD
: ZEBRA_REMOTE_VTEP_DEL
,
635 stream_putl(s
, vpn
->vni
);
636 if (is_evpn_prefix_ipaddr_v4(p
))
637 stream_put_in_addr(s
, &p
->prefix
.imet_addr
.ip
.ipaddr_v4
);
638 else if (is_evpn_prefix_ipaddr_v6(p
)) {
641 "Bad remote IP when trying to %s remote VTEP for VNI %u",
642 add
? "ADD" : "DEL", vpn
->vni
);
646 stream_putw_at(s
, 0, stream_get_endp(s
));
648 if (bgp_debug_zebra(NULL
))
649 zlog_debug("Tx %s Remote VTEP, VNI %u remote VTEP %s",
650 add
? "ADD" : "DEL", vpn
->vni
,
651 inet_ntoa(p
->prefix
.imet_addr
.ip
.ipaddr_v4
));
653 return zclient_send_message(zclient
);
657 * Build extended community for EVPN ES (type-4) route
659 static void build_evpn_type4_route_extcomm(struct evpnes
*es
,
662 struct ecommunity ecom_encap
;
663 struct ecommunity ecom_es_rt
;
664 struct ecommunity_val eval
;
665 struct ecommunity_val eval_es_rt
;
666 bgp_encap_types tnl_type
;
670 tnl_type
= BGP_ENCAP_TYPE_VXLAN
;
671 memset(&ecom_encap
, 0, sizeof(ecom_encap
));
672 encode_encap_extcomm(tnl_type
, &eval
);
674 ecom_encap
.val
= (uint8_t *)eval
.val
;
675 attr
->ecommunity
= ecommunity_dup(&ecom_encap
);
678 memset(&mac
, 0, sizeof(struct ethaddr
));
679 memset(&ecom_es_rt
, 0, sizeof(ecom_es_rt
));
680 es_get_system_mac(&es
->esi
, &mac
);
681 encode_es_rt_extcomm(&eval_es_rt
, &mac
);
683 ecom_es_rt
.val
= (uint8_t *)eval_es_rt
.val
;
685 ecommunity_merge(attr
->ecommunity
, &ecom_es_rt
);
687 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
);
691 * Build extended communities for EVPN prefix route.
693 static void build_evpn_type5_route_extcomm(struct bgp
*bgp_vrf
,
696 struct ecommunity ecom_encap
;
697 struct ecommunity ecom_rmac
;
698 struct ecommunity_val eval
;
699 struct ecommunity_val eval_rmac
;
700 bgp_encap_types tnl_type
;
701 struct listnode
*node
, *nnode
;
702 struct ecommunity
*ecom
;
703 struct list
*vrf_export_rtl
= NULL
;
706 tnl_type
= BGP_ENCAP_TYPE_VXLAN
;
707 memset(&ecom_encap
, 0, sizeof(ecom_encap
));
708 encode_encap_extcomm(tnl_type
, &eval
);
710 ecom_encap
.val
= (uint8_t *)eval
.val
;
713 attr
->ecommunity
= ecommunity_dup(&ecom_encap
);
715 /* Add the export RTs for L3VNI/VRF */
716 vrf_export_rtl
= bgp_vrf
->vrf_export_rtl
;
717 for (ALL_LIST_ELEMENTS(vrf_export_rtl
, node
, nnode
, ecom
))
719 ecommunity_merge(attr
->ecommunity
, ecom
);
721 /* add the router mac extended community */
722 if (!is_zero_mac(&attr
->rmac
)) {
723 memset(&ecom_rmac
, 0, sizeof(ecom_rmac
));
724 encode_rmac_extcomm(&eval_rmac
, &attr
->rmac
);
726 ecom_rmac
.val
= (uint8_t *)eval_rmac
.val
;
728 ecommunity_merge(attr
->ecommunity
, &ecom_rmac
);
731 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
);
735 * Build extended communities for EVPN route.
736 * This function is applicable for type-2 and type-3 routes. The layer-2 RT
737 * and ENCAP extended communities are applicable for all routes.
738 * The default gateway extended community and MAC mobility (sticky) extended
739 * community are added as needed based on passed settings - only for type-2
740 * routes. Likewise, the layer-3 RT and Router MAC extended communities are
741 * added, if present, based on passed settings - only for non-link-local
744 static void build_evpn_route_extcomm(struct bgpevpn
*vpn
, struct attr
*attr
,
747 struct ecommunity ecom_encap
;
748 struct ecommunity ecom_sticky
;
749 struct ecommunity ecom_default_gw
;
750 struct ecommunity ecom_rmac
;
751 struct ecommunity ecom_na
;
752 struct ecommunity_val eval
;
753 struct ecommunity_val eval_sticky
;
754 struct ecommunity_val eval_default_gw
;
755 struct ecommunity_val eval_rmac
;
756 struct ecommunity_val eval_na
;
758 bgp_encap_types tnl_type
;
759 struct listnode
*node
, *nnode
;
760 struct ecommunity
*ecom
;
762 struct list
*vrf_export_rtl
= NULL
;
765 tnl_type
= BGP_ENCAP_TYPE_VXLAN
;
766 memset(&ecom_encap
, 0, sizeof(ecom_encap
));
767 encode_encap_extcomm(tnl_type
, &eval
);
769 ecom_encap
.val
= (uint8_t *)eval
.val
;
772 attr
->ecommunity
= ecommunity_dup(&ecom_encap
);
774 /* Add the export RTs for L2VNI */
775 for (ALL_LIST_ELEMENTS(vpn
->export_rtl
, node
, nnode
, ecom
))
776 attr
->ecommunity
= ecommunity_merge(attr
->ecommunity
, ecom
);
778 /* Add the export RTs for L3VNI if told to - caller determines
779 * when this should be done.
782 vrf_export_rtl
= bgpevpn_get_vrf_export_rtl(vpn
);
783 if (vrf_export_rtl
&& !list_isempty(vrf_export_rtl
)) {
784 for (ALL_LIST_ELEMENTS(vrf_export_rtl
, node
, nnode
,
786 attr
->ecommunity
= ecommunity_merge(
787 attr
->ecommunity
, ecom
);
791 /* Add MAC mobility (sticky) if needed. */
794 memset(&ecom_sticky
, 0, sizeof(ecom_sticky
));
795 encode_mac_mobility_extcomm(1, seqnum
, &eval_sticky
);
796 ecom_sticky
.size
= 1;
797 ecom_sticky
.val
= (uint8_t *)eval_sticky
.val
;
799 ecommunity_merge(attr
->ecommunity
, &ecom_sticky
);
802 /* Add RMAC, if told to. */
804 memset(&ecom_rmac
, 0, sizeof(ecom_rmac
));
805 encode_rmac_extcomm(&eval_rmac
, &attr
->rmac
);
807 ecom_rmac
.val
= (uint8_t *)eval_rmac
.val
;
809 ecommunity_merge(attr
->ecommunity
, &ecom_rmac
);
812 /* Add default gateway, if needed. */
813 if (attr
->default_gw
) {
814 memset(&ecom_default_gw
, 0, sizeof(ecom_default_gw
));
815 encode_default_gw_extcomm(&eval_default_gw
);
816 ecom_default_gw
.size
= 1;
817 ecom_default_gw
.val
= (uint8_t *)eval_default_gw
.val
;
819 ecommunity_merge(attr
->ecommunity
, &ecom_default_gw
);
822 if (attr
->router_flag
) {
823 memset(&ecom_na
, 0, sizeof(ecom_na
));
824 encode_na_flag_extcomm(&eval_na
, attr
->router_flag
);
826 ecom_na
.val
= (uint8_t *)eval_na
.val
;
827 attr
->ecommunity
= ecommunity_merge(attr
->ecommunity
,
831 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
);
835 * Add MAC mobility extended community to attribute.
837 static void add_mac_mobility_to_attr(uint32_t seq_num
, struct attr
*attr
)
839 struct ecommunity ecom_tmp
;
840 struct ecommunity_val eval
;
841 uint8_t *ecom_val_ptr
;
848 encode_mac_mobility_extcomm(0, seq_num
, &eval
);
850 /* Find current MM ecommunity */
853 if (attr
->ecommunity
) {
854 for (i
= 0; i
< attr
->ecommunity
->size
; i
++) {
855 pnt
= attr
->ecommunity
->val
+ (i
* 8);
859 if (type
== ECOMMUNITY_ENCODE_EVPN
861 == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY
) {
862 ecom_val_ptr
= (uint8_t *)(attr
->ecommunity
->val
869 /* Update the existing MM ecommunity */
871 memcpy(ecom_val_ptr
, eval
.val
, sizeof(char) * ECOMMUNITY_SIZE
);
873 /* Add MM to existing */
875 memset(&ecom_tmp
, 0, sizeof(ecom_tmp
));
877 ecom_tmp
.val
= (uint8_t *)eval
.val
;
879 if (attr
->ecommunity
)
881 ecommunity_merge(attr
->ecommunity
, &ecom_tmp
);
883 attr
->ecommunity
= ecommunity_dup(&ecom_tmp
);
887 /* Install EVPN route into zebra. */
888 static int evpn_zebra_install(struct bgp
*bgp
, struct bgpevpn
*vpn
,
889 struct prefix_evpn
*p
,
890 struct in_addr remote_vtep_ip
, uint8_t flags
,
895 if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
)
896 ret
= bgp_zebra_send_remote_macip(bgp
, vpn
, p
, remote_vtep_ip
,
899 ret
= bgp_zebra_send_remote_vtep(bgp
, vpn
, p
, 1);
904 /* Uninstall EVPN route from zebra. */
905 static int evpn_zebra_uninstall(struct bgp
*bgp
, struct bgpevpn
*vpn
,
906 struct prefix_evpn
*p
,
907 struct in_addr remote_vtep_ip
)
911 if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
)
912 ret
= bgp_zebra_send_remote_macip(bgp
, vpn
, p
, remote_vtep_ip
,
915 ret
= bgp_zebra_send_remote_vtep(bgp
, vpn
, p
, 0);
921 * Due to MAC mobility, the prior "local" best route has been supplanted
922 * by a "remote" best route. The prior route has to be deleted and withdrawn
925 static void evpn_delete_old_local_route(struct bgp
*bgp
, struct bgpevpn
*vpn
,
927 struct bgp_path_info
*old_local
)
929 struct bgp_node
*global_rn
;
930 struct bgp_path_info
*pi
;
931 afi_t afi
= AFI_L2VPN
;
932 safi_t safi
= SAFI_EVPN
;
934 /* Locate route node in the global EVPN routing table. Note that
935 * this table is a 2-level tree (RD-level + Prefix-level) similar to
938 global_rn
= bgp_afi_node_lookup(bgp
->rib
[afi
][safi
], afi
, safi
,
939 (struct prefix
*)&rn
->p
, &vpn
->prd
);
941 /* Delete route entry in the global EVPN table. */
942 delete_evpn_route_entry(bgp
, afi
, safi
, global_rn
, &pi
);
944 /* Schedule for processing - withdraws to peers happen from
948 bgp_process(bgp
, global_rn
, afi
, safi
);
949 bgp_unlock_node(global_rn
);
952 /* Delete route entry in the VNI route table, caller to remove. */
953 bgp_path_info_delete(rn
, old_local
);
956 static struct in_addr
*es_vtep_new(struct in_addr vtep
)
960 ip
= XCALLOC(MTYPE_BGP_EVPN_ES_VTEP
, sizeof(struct in_addr
));
964 ip
->s_addr
= vtep
.s_addr
;
968 static void es_vtep_free(struct in_addr
*ip
)
970 XFREE(MTYPE_BGP_EVPN_ES_VTEP
, ip
);
973 /* check if VTEP is already part of the list */
974 static int is_vtep_present_in_list(struct list
*list
,
977 struct listnode
*node
= NULL
;
980 for (ALL_LIST_ELEMENTS_RO(list
, node
, tmp
)) {
981 if (tmp
->s_addr
== vtep
.s_addr
)
988 * Best path for ES route was changed,
989 * update the list of VTEPs for this ES
991 static int evpn_es_install_vtep(struct bgp
*bgp
,
993 struct prefix_evpn
*p
,
994 struct in_addr rvtep
)
996 struct in_addr
*vtep_ip
;
998 if (is_vtep_present_in_list(es
->vtep_list
, rvtep
))
1002 vtep_ip
= es_vtep_new(rvtep
);
1004 listnode_add_sort(es
->vtep_list
, vtep_ip
);
1009 * Best path for ES route was changed,
1010 * update the list of VTEPs for this ES
1012 static int evpn_es_uninstall_vtep(struct bgp
*bgp
,
1014 struct prefix_evpn
*p
,
1015 struct in_addr rvtep
)
1017 struct listnode
*node
, *nnode
, *node_to_del
= NULL
;
1018 struct in_addr
*tmp
;
1020 for (ALL_LIST_ELEMENTS(es
->vtep_list
, node
, nnode
, tmp
)) {
1021 if (tmp
->s_addr
== rvtep
.s_addr
) {
1028 list_delete_node(es
->vtep_list
, node_to_del
);
1034 * Calculate the best path for a ES(type-4) route.
1036 static int evpn_es_route_select_install(struct bgp
*bgp
,
1038 struct bgp_node
*rn
)
1041 afi_t afi
= AFI_L2VPN
;
1042 safi_t safi
= SAFI_EVPN
;
1043 struct bgp_path_info
*old_select
; /* old best */
1044 struct bgp_path_info
*new_select
; /* new best */
1045 struct bgp_path_info_pair old_and_new
;
1047 /* Compute the best path. */
1048 bgp_best_selection(bgp
, rn
, &bgp
->maxpaths
[afi
][safi
],
1049 &old_and_new
, afi
, safi
);
1050 old_select
= old_and_new
.old
;
1051 new_select
= old_and_new
.new;
1054 * If the best path hasn't changed - see if something needs to be
1057 if (old_select
&& old_select
== new_select
1058 && old_select
->type
== ZEBRA_ROUTE_BGP
1059 && old_select
->sub_type
== BGP_ROUTE_IMPORTED
1060 && !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
)
1061 && !CHECK_FLAG(old_select
->flags
, BGP_PATH_ATTR_CHANGED
)
1062 && !bgp
->addpath_tx_used
[afi
][safi
]) {
1063 if (bgp_zebra_has_route_changed(rn
, old_select
)) {
1064 ret
= evpn_es_install_vtep(bgp
, es
,
1065 (struct prefix_evpn
*)&rn
->p
,
1066 old_select
->attr
->nexthop
);
1068 UNSET_FLAG(old_select
->flags
, BGP_PATH_MULTIPATH_CHG
);
1069 bgp_zebra_clear_route_change_flags(rn
);
1073 /* If the user did a "clear" this flag will be set */
1074 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
1077 * bestpath has changed; update relevant fields and install or uninstall
1078 * into the zebra RIB.
1080 if (old_select
|| new_select
)
1081 bgp_bump_version(rn
);
1084 bgp_path_info_unset_flag(rn
, old_select
, BGP_PATH_SELECTED
);
1086 bgp_path_info_set_flag(rn
, new_select
, BGP_PATH_SELECTED
);
1087 bgp_path_info_unset_flag(rn
, new_select
, BGP_PATH_ATTR_CHANGED
);
1088 UNSET_FLAG(new_select
->flags
, BGP_PATH_MULTIPATH_CHG
);
1091 if (new_select
&& new_select
->type
== ZEBRA_ROUTE_BGP
1092 && new_select
->sub_type
== BGP_ROUTE_IMPORTED
) {
1093 ret
= evpn_es_install_vtep(bgp
, es
,
1094 (struct prefix_evpn
*)&rn
->p
,
1095 new_select
->attr
->nexthop
);
1097 if (old_select
&& old_select
->type
== ZEBRA_ROUTE_BGP
1098 && old_select
->sub_type
== BGP_ROUTE_IMPORTED
)
1099 ret
= evpn_es_uninstall_vtep(
1100 bgp
, es
, (struct prefix_evpn
*)&rn
->p
,
1101 old_select
->attr
->nexthop
);
1104 /* Clear any route change flags. */
1105 bgp_zebra_clear_route_change_flags(rn
);
1107 /* Reap old select bgp_path_info, if it has been removed */
1108 if (old_select
&& CHECK_FLAG(old_select
->flags
, BGP_PATH_REMOVED
))
1109 bgp_path_info_reap(rn
, old_select
);
1115 * Calculate the best path for an EVPN route. Install/update best path in zebra,
1118 static int evpn_route_select_install(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1119 struct bgp_node
*rn
)
1121 struct bgp_path_info
*old_select
, *new_select
;
1122 struct bgp_path_info_pair old_and_new
;
1123 struct prefix_evpn
*evp
;
1124 afi_t afi
= AFI_L2VPN
;
1125 safi_t safi
= SAFI_EVPN
;
1129 /* Compute the best path. */
1130 bgp_best_selection(bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
,
1132 old_select
= old_and_new
.old
;
1133 new_select
= old_and_new
.new;
1135 evp
= (struct prefix_evpn
*)&rn
->p
;
1136 /* If the best path hasn't changed - see if there is still something to
1140 if (old_select
&& old_select
== new_select
1141 && old_select
->type
== ZEBRA_ROUTE_BGP
1142 && old_select
->sub_type
== BGP_ROUTE_IMPORTED
1143 && !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
)
1144 && !CHECK_FLAG(old_select
->flags
, BGP_PATH_ATTR_CHANGED
)
1145 && !bgp
->addpath_tx_used
[afi
][safi
]) {
1146 if (bgp_zebra_has_route_changed(rn
, old_select
)) {
1147 if (old_select
->attr
->sticky
)
1148 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
1149 if (old_select
->attr
->default_gw
)
1150 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
1151 if (is_evpn_prefix_ipaddr_v6(evp
) &&
1152 old_select
->attr
->router_flag
)
1153 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_ROUTER_FLAG
);
1155 ret
= evpn_zebra_install(
1156 bgp
, vpn
, (struct prefix_evpn
*)&rn
->p
,
1157 old_select
->attr
->nexthop
, flags
,
1158 mac_mobility_seqnum(old_select
->attr
));
1160 UNSET_FLAG(old_select
->flags
, BGP_PATH_MULTIPATH_CHG
);
1161 bgp_zebra_clear_route_change_flags(rn
);
1165 /* If the user did a "clear" this flag will be set */
1166 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
1168 /* bestpath has changed; update relevant fields and install or uninstall
1169 * into the zebra RIB.
1171 if (old_select
|| new_select
)
1172 bgp_bump_version(rn
);
1175 bgp_path_info_unset_flag(rn
, old_select
, BGP_PATH_SELECTED
);
1177 bgp_path_info_set_flag(rn
, new_select
, BGP_PATH_SELECTED
);
1178 bgp_path_info_unset_flag(rn
, new_select
, BGP_PATH_ATTR_CHANGED
);
1179 UNSET_FLAG(new_select
->flags
, BGP_PATH_MULTIPATH_CHG
);
1182 if (new_select
&& new_select
->type
== ZEBRA_ROUTE_BGP
1183 && new_select
->sub_type
== BGP_ROUTE_IMPORTED
) {
1185 if (new_select
->attr
->sticky
)
1186 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
1187 if (new_select
->attr
->default_gw
)
1188 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
1189 if (is_evpn_prefix_ipaddr_v6(evp
) &&
1190 new_select
->attr
->router_flag
)
1191 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_ROUTER_FLAG
);
1193 ret
= evpn_zebra_install(bgp
, vpn
, (struct prefix_evpn
*)&rn
->p
,
1194 new_select
->attr
->nexthop
, flags
,
1195 mac_mobility_seqnum(new_select
->attr
));
1196 /* If an old best existed and it was a "local" route, the only
1198 * it would be supplanted is due to MAC mobility procedures. So,
1200 * need to do an implicit delete and withdraw that route from
1203 if (old_select
&& old_select
->peer
== bgp
->peer_self
1204 && old_select
->type
== ZEBRA_ROUTE_BGP
1205 && old_select
->sub_type
== BGP_ROUTE_STATIC
)
1206 evpn_delete_old_local_route(bgp
, vpn
, rn
, old_select
);
1208 if (old_select
&& old_select
->type
== ZEBRA_ROUTE_BGP
1209 && old_select
->sub_type
== BGP_ROUTE_IMPORTED
)
1210 ret
= evpn_zebra_uninstall(bgp
, vpn
,
1211 (struct prefix_evpn
*)&rn
->p
,
1212 old_select
->attr
->nexthop
);
1215 /* Clear any route change flags. */
1216 bgp_zebra_clear_route_change_flags(rn
);
1218 /* Reap old select bgp_path_info, if it has been removed */
1219 if (old_select
&& CHECK_FLAG(old_select
->flags
, BGP_PATH_REMOVED
))
1220 bgp_path_info_reap(rn
, old_select
);
1226 * Return true if the local ri for this rn is of type gateway mac
1228 static int evpn_route_is_def_gw(struct bgp
*bgp
, struct bgp_node
*rn
)
1230 struct bgp_path_info
*tmp_pi
= NULL
;
1231 struct bgp_path_info
*local_pi
= NULL
;
1234 for (tmp_pi
= rn
->info
; tmp_pi
; tmp_pi
= tmp_pi
->next
) {
1235 if (tmp_pi
->peer
== bgp
->peer_self
1236 && tmp_pi
->type
== ZEBRA_ROUTE_BGP
1237 && tmp_pi
->sub_type
== BGP_ROUTE_STATIC
)
1244 return local_pi
->attr
->default_gw
;
1249 * Return true if the local ri for this rn has sticky set
1251 static int evpn_route_is_sticky(struct bgp
*bgp
, struct bgp_node
*rn
)
1253 struct bgp_path_info
*tmp_pi
;
1254 struct bgp_path_info
*local_pi
;
1257 for (tmp_pi
= rn
->info
; tmp_pi
; tmp_pi
= tmp_pi
->next
) {
1258 if (tmp_pi
->peer
== bgp
->peer_self
1259 && tmp_pi
->type
== ZEBRA_ROUTE_BGP
1260 && tmp_pi
->sub_type
== BGP_ROUTE_STATIC
)
1267 return local_pi
->attr
->sticky
;
1271 * create or update EVPN type4 route entry.
1272 * This could be in the ES table or the global table.
1273 * TODO: handle remote ES (type4) routes as well
1275 static int update_evpn_type4_route_entry(struct bgp
*bgp
, struct evpnes
*es
,
1276 afi_t afi
, safi_t safi
,
1277 struct bgp_node
*rn
, struct attr
*attr
,
1278 int add
, struct bgp_path_info
**ri
,
1281 char buf
[ESI_STR_LEN
];
1282 char buf1
[INET6_ADDRSTRLEN
];
1283 struct bgp_path_info
*tmp_pi
= NULL
;
1284 struct bgp_path_info
*local_pi
= NULL
; /* local route entry if any */
1285 struct bgp_path_info
*remote_pi
= NULL
; /* remote route entry if any */
1286 struct attr
*attr_new
= NULL
;
1287 struct prefix_evpn
*evp
= NULL
;
1291 evp
= (struct prefix_evpn
*)&rn
->p
;
1293 /* locate the local and remote entries if any */
1294 for (tmp_pi
= rn
->info
; tmp_pi
; tmp_pi
= tmp_pi
->next
) {
1295 if (tmp_pi
->peer
== bgp
->peer_self
1296 && tmp_pi
->type
== ZEBRA_ROUTE_BGP
1297 && tmp_pi
->sub_type
== BGP_ROUTE_STATIC
)
1299 if (tmp_pi
->type
== ZEBRA_ROUTE_BGP
1300 && tmp_pi
->sub_type
== BGP_ROUTE_IMPORTED
1301 && CHECK_FLAG(tmp_pi
->flags
, BGP_PATH_VALID
))
1305 /* we don't expect to see a remote_pi at this point.
1306 * An ES route has esi + vtep_ip as the key,
1307 * We shouldn't see the same route from any other vtep.
1312 "%u ERROR: local es route for ESI: %s Vtep %s also learnt from remote",
1314 esi_to_str(&evp
->prefix
.es_addr
.esi
, buf
, sizeof(buf
)),
1315 ipaddr2str(&es
->originator_ip
, buf1
, sizeof(buf1
)));
1319 if (!local_pi
&& !add
)
1322 /* create or update the entry */
1325 /* Add or update attribute to hash */
1326 attr_new
= bgp_attr_intern(attr
);
1328 /* Create new route with its attribute. */
1329 tmp_pi
= info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0,
1330 bgp
->peer_self
, attr_new
, rn
);
1331 SET_FLAG(tmp_pi
->flags
, BGP_PATH_VALID
);
1333 /* add the newly created path to the route-node */
1334 bgp_path_info_add(rn
, tmp_pi
);
1337 if (attrhash_cmp(tmp_pi
->attr
, attr
)
1338 && !CHECK_FLAG(tmp_pi
->flags
, BGP_PATH_REMOVED
))
1341 /* The attribute has changed.
1342 * Add (or update) attribute to hash. */
1343 attr_new
= bgp_attr_intern(attr
);
1344 bgp_path_info_set_flag(rn
, tmp_pi
,
1345 BGP_PATH_ATTR_CHANGED
);
1347 /* Restore route, if needed. */
1348 if (CHECK_FLAG(tmp_pi
->flags
, BGP_PATH_REMOVED
))
1349 bgp_path_info_restore(rn
, tmp_pi
);
1351 /* Unintern existing, set to new. */
1352 bgp_attr_unintern(&tmp_pi
->attr
);
1353 tmp_pi
->attr
= attr_new
;
1354 tmp_pi
->uptime
= bgp_clock();
1358 /* Return back the route entry. */
1363 /* update evpn es (type-4) route */
1364 static int update_evpn_type4_route(struct bgp
*bgp
,
1366 struct prefix_evpn
*p
)
1369 int route_changed
= 0;
1370 char buf
[ESI_STR_LEN
];
1371 char buf1
[INET6_ADDRSTRLEN
];
1372 afi_t afi
= AFI_L2VPN
;
1373 safi_t safi
= SAFI_EVPN
;
1375 struct attr
*attr_new
= NULL
;
1376 struct bgp_node
*rn
= NULL
;
1377 struct bgp_path_info
*pi
= NULL
;
1379 memset(&attr
, 0, sizeof(struct attr
));
1381 /* Build path-attribute for this route. */
1382 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
1383 attr
.nexthop
= es
->originator_ip
.ipaddr_v4
;
1384 attr
.mp_nexthop_global_in
= es
->originator_ip
.ipaddr_v4
;
1385 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1387 /* Set up extended community. */
1388 build_evpn_type4_route_extcomm(es
, &attr
);
1390 /* First, create (or fetch) route node within the ESI. */
1391 /* NOTE: There is no RD here. */
1392 rn
= bgp_node_get(es
->route_table
, (struct prefix
*)p
);
1394 /* Create or update route entry. */
1395 ret
= update_evpn_type4_route_entry(bgp
, es
, afi
, safi
, rn
, &attr
, 1,
1396 &pi
, &route_changed
);
1398 flog_err(EC_BGP_ES_INVALID
,
1399 "%u ERROR: Failed to updated ES route ESI: %s VTEP %s",
1401 esi_to_str(&p
->prefix
.es_addr
.esi
, buf
, sizeof(buf
)),
1402 ipaddr2str(&es
->originator_ip
, buf1
, sizeof(buf1
)));
1406 attr_new
= pi
->attr
;
1408 /* Perform route selection;
1409 * this is just to set the flags correctly
1410 * as local route in the ES always wins.
1412 evpn_es_route_select_install(bgp
, es
, rn
);
1413 bgp_unlock_node(rn
);
1415 /* If this is a new route or some attribute has changed, export the
1416 * route to the global table. The route will be advertised to peers
1417 * from there. Note that this table is a 2-level tree (RD-level +
1418 * Prefix-level) similar to L3VPN routes.
1420 if (route_changed
) {
1421 struct bgp_path_info
*global_pi
;
1423 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
1424 (struct prefix
*)p
, &es
->prd
);
1425 update_evpn_type4_route_entry(bgp
, es
, afi
, safi
, rn
, attr_new
,
1426 1, &global_pi
, &route_changed
);
1428 /* Schedule for processing and unlock node. */
1429 bgp_process(bgp
, rn
, afi
, safi
);
1430 bgp_unlock_node(rn
);
1433 /* Unintern temporary. */
1434 aspath_unintern(&attr
.aspath
);
1438 static int update_evpn_type5_route_entry(struct bgp
*bgp_def
,
1439 struct bgp
*bgp_vrf
, afi_t afi
,
1440 safi_t safi
, struct bgp_node
*rn
,
1441 struct attr
*attr
, int *route_changed
)
1443 struct attr
*attr_new
= NULL
;
1444 struct bgp_path_info
*pi
= NULL
;
1445 mpls_label_t label
= MPLS_INVALID_LABEL
;
1446 struct bgp_path_info
*local_pi
= NULL
;
1447 struct bgp_path_info
*tmp_pi
= NULL
;
1450 /* locate the local route entry if any */
1451 for (tmp_pi
= rn
->info
; tmp_pi
; tmp_pi
= tmp_pi
->next
) {
1452 if (tmp_pi
->peer
== bgp_def
->peer_self
1453 && tmp_pi
->type
== ZEBRA_ROUTE_BGP
1454 && tmp_pi
->sub_type
== BGP_ROUTE_STATIC
)
1459 * create a new route entry if one doesn't exist.
1460 * Otherwise see if route attr has changed
1464 /* route has changed as this is the first entry */
1467 /* Add (or update) attribute to hash. */
1468 attr_new
= bgp_attr_intern(attr
);
1470 /* create the route info from attribute */
1471 pi
= info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0,
1472 bgp_def
->peer_self
, attr_new
, rn
);
1473 SET_FLAG(pi
->flags
, BGP_PATH_VALID
);
1475 /* Type-5 routes advertise the L3-VNI */
1476 bgp_path_info_extra_get(pi
);
1477 vni2label(bgp_vrf
->l3vni
, &label
);
1478 memcpy(&pi
->extra
->label
, &label
, sizeof(label
));
1479 pi
->extra
->num_labels
= 1;
1481 /* add the route entry to route node*/
1482 bgp_path_info_add(rn
, pi
);
1486 if (!attrhash_cmp(tmp_pi
->attr
, attr
)) {
1488 /* attribute changed */
1491 /* The attribute has changed. */
1492 /* Add (or update) attribute to hash. */
1493 attr_new
= bgp_attr_intern(attr
);
1494 bgp_path_info_set_flag(rn
, tmp_pi
,
1495 BGP_PATH_ATTR_CHANGED
);
1497 /* Restore route, if needed. */
1498 if (CHECK_FLAG(tmp_pi
->flags
, BGP_PATH_REMOVED
))
1499 bgp_path_info_restore(rn
, tmp_pi
);
1501 /* Unintern existing, set to new. */
1502 bgp_attr_unintern(&tmp_pi
->attr
);
1503 tmp_pi
->attr
= attr_new
;
1504 tmp_pi
->uptime
= bgp_clock();
1510 /* update evpn type-5 route entry */
1511 static int update_evpn_type5_route(struct bgp
*bgp_vrf
, struct prefix_evpn
*evp
,
1512 struct attr
*src_attr
)
1514 afi_t afi
= AFI_L2VPN
;
1515 safi_t safi
= SAFI_EVPN
;
1517 struct bgp_node
*rn
= NULL
;
1518 struct bgp
*bgp_def
= NULL
;
1519 int route_changed
= 0;
1521 bgp_def
= bgp_get_default();
1525 /* Build path attribute for this route - use the source attr, if
1526 * present, else treat as locally originated.
1529 bgp_attr_dup(&attr
, src_attr
);
1531 memset(&attr
, 0, sizeof(struct attr
));
1532 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
1534 /* Set nexthop to ourselves and fill in the Router MAC. */
1535 attr
.nexthop
= bgp_vrf
->originator_ip
;
1536 attr
.mp_nexthop_global_in
= bgp_vrf
->originator_ip
;
1537 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1538 memcpy(&attr
.rmac
, &bgp_vrf
->rmac
, sizeof(struct ethaddr
));
1540 /* Setup RT and encap extended community */
1541 build_evpn_type5_route_extcomm(bgp_vrf
, &attr
);
1543 /* get the route node in global table */
1544 rn
= bgp_afi_node_get(bgp_def
->rib
[afi
][safi
], afi
, safi
,
1545 (struct prefix
*)evp
, &bgp_vrf
->vrf_prd
);
1548 /* create or update the route entry within the route node */
1549 update_evpn_type5_route_entry(bgp_def
, bgp_vrf
, afi
, safi
, rn
, &attr
,
1552 /* schedule for processing and unlock node */
1553 if (route_changed
) {
1554 bgp_process(bgp_def
, rn
, afi
, safi
);
1555 bgp_unlock_node(rn
);
1558 /* uninten temporary */
1560 aspath_unintern(&attr
.aspath
);
1565 * Create or update EVPN route entry. This could be in the VNI route table
1566 * or the global route table.
1568 static int update_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1569 afi_t afi
, safi_t safi
, struct bgp_node
*rn
,
1570 struct attr
*attr
, int add
,
1571 struct bgp_path_info
**pi
, uint8_t flags
,
1574 struct bgp_path_info
*tmp_pi
;
1575 struct bgp_path_info
*local_pi
;
1576 struct attr
*attr_new
;
1577 mpls_label_t label
[BGP_MAX_LABELS
];
1578 uint32_t num_labels
= 1;
1579 int route_change
= 1;
1581 struct prefix_evpn
*evp
;
1584 evp
= (struct prefix_evpn
*)&rn
->p
;
1585 memset(&label
, 0, sizeof(label
));
1587 /* See if this is an update of an existing route, or a new add. */
1589 for (tmp_pi
= rn
->info
; tmp_pi
; tmp_pi
= tmp_pi
->next
) {
1590 if (tmp_pi
->peer
== bgp
->peer_self
1591 && tmp_pi
->type
== ZEBRA_ROUTE_BGP
1592 && tmp_pi
->sub_type
== BGP_ROUTE_STATIC
)
1596 /* If route doesn't exist already, create a new one, if told to.
1597 * Otherwise act based on whether the attributes of the route have
1600 if (!local_pi
&& !add
)
1603 /* For non-GW MACs, update MAC mobility seq number, if needed. */
1604 if (seq
&& !CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
))
1605 add_mac_mobility_to_attr(seq
, attr
);
1608 /* Add (or update) attribute to hash. */
1609 attr_new
= bgp_attr_intern(attr
);
1611 /* Extract MAC mobility sequence number, if any. */
1612 attr_new
->mm_seqnum
=
1613 bgp_attr_mac_mobility_seqnum(attr_new
, &sticky
);
1614 attr_new
->sticky
= sticky
;
1616 /* Create new route with its attribute. */
1617 tmp_pi
= info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0,
1618 bgp
->peer_self
, attr_new
, rn
);
1619 SET_FLAG(tmp_pi
->flags
, BGP_PATH_VALID
);
1620 bgp_path_info_extra_get(tmp_pi
);
1622 /* The VNI goes into the 'label' field of the route */
1623 vni2label(vpn
->vni
, &label
[0]);
1625 /* Type-2 routes may carry a second VNI - the L3-VNI.
1626 * Only attach second label if we are advertising two labels for
1629 if (evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
1630 && CHECK_FLAG(vpn
->flags
, VNI_FLAG_USE_TWO_LABELS
)) {
1633 l3vni
= bgpevpn_get_l3vni(vpn
);
1635 vni2label(l3vni
, &label
[1]);
1640 memcpy(&tmp_pi
->extra
->label
, label
, sizeof(label
));
1641 tmp_pi
->extra
->num_labels
= num_labels
;
1642 bgp_path_info_add(rn
, tmp_pi
);
1645 if (attrhash_cmp(tmp_pi
->attr
, attr
)
1646 && !CHECK_FLAG(tmp_pi
->flags
, BGP_PATH_REMOVED
))
1650 * The attributes have changed, type-2 routes needs to
1651 * be advertised with right labels.
1653 vni2label(vpn
->vni
, &label
[0]);
1654 if (evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
1655 && CHECK_FLAG(vpn
->flags
,
1656 VNI_FLAG_USE_TWO_LABELS
)) {
1659 l3vni
= bgpevpn_get_l3vni(vpn
);
1661 vni2label(l3vni
, &label
[1]);
1665 memcpy(&tmp_pi
->extra
->label
, label
, sizeof(label
));
1666 tmp_pi
->extra
->num_labels
= num_labels
;
1668 /* The attribute has changed. */
1669 /* Add (or update) attribute to hash. */
1670 attr_new
= bgp_attr_intern(attr
);
1671 bgp_path_info_set_flag(rn
, tmp_pi
,
1672 BGP_PATH_ATTR_CHANGED
);
1674 /* Extract MAC mobility sequence number, if any. */
1675 attr_new
->mm_seqnum
=
1676 bgp_attr_mac_mobility_seqnum(attr_new
, &sticky
);
1677 attr_new
->sticky
= sticky
;
1679 /* Restore route, if needed. */
1680 if (CHECK_FLAG(tmp_pi
->flags
, BGP_PATH_REMOVED
))
1681 bgp_path_info_restore(rn
, tmp_pi
);
1683 /* Unintern existing, set to new. */
1684 bgp_attr_unintern(&tmp_pi
->attr
);
1685 tmp_pi
->attr
= attr_new
;
1686 tmp_pi
->uptime
= bgp_clock();
1690 /* Return back the route entry. */
1692 return route_change
;
1696 * Create or update EVPN route (of type based on prefix) for specified VNI
1697 * and schedule for processing.
1699 static int update_evpn_route(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1700 struct prefix_evpn
*p
, uint8_t flags
,
1703 struct bgp_node
*rn
;
1705 struct attr
*attr_new
;
1706 int add_l3_ecomm
= 0;
1707 struct bgp_path_info
*pi
;
1708 afi_t afi
= AFI_L2VPN
;
1709 safi_t safi
= SAFI_EVPN
;
1712 memset(&attr
, 0, sizeof(struct attr
));
1714 /* Build path-attribute for this route. */
1715 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
1716 attr
.nexthop
= vpn
->originator_ip
;
1717 attr
.mp_nexthop_global_in
= vpn
->originator_ip
;
1718 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1719 attr
.sticky
= CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
) ? 1 : 0;
1720 attr
.default_gw
= CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
) ? 1 : 0;
1721 attr
.router_flag
= CHECK_FLAG(flags
,
1722 ZEBRA_MACIP_TYPE_ROUTER_FLAG
) ? 1 : 0;
1724 /* PMSI is only needed for type-3 routes */
1725 if (p
->prefix
.route_type
== BGP_EVPN_IMET_ROUTE
)
1726 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL
);
1728 /* router mac is only needed for type-2 routes here. */
1729 if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
)
1730 bgpevpn_get_rmac(vpn
, &attr
.rmac
);
1731 vni2label(vpn
->vni
, &(attr
.label
));
1733 /* Include L3 VNI related RTs and RMAC for type-2 routes, if they're
1734 * IPv4 or IPv6 global addresses and we're advertising L3VNI with
1737 if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
&&
1738 (is_evpn_prefix_ipaddr_v4(p
) ||
1739 !IN6_IS_ADDR_LINKLOCAL(&p
->prefix
.macip_addr
.ip
.ipaddr_v6
)) &&
1740 CHECK_FLAG(vpn
->flags
, VNI_FLAG_USE_TWO_LABELS
) &&
1741 bgpevpn_get_l3vni(vpn
))
1744 /* Set up extended community. */
1745 build_evpn_route_extcomm(vpn
, &attr
, add_l3_ecomm
);
1747 /* First, create (or fetch) route node within the VNI. */
1748 /* NOTE: There is no RD here. */
1749 rn
= bgp_node_get(vpn
->route_table
, (struct prefix
*)p
);
1751 /* Create or update route entry. */
1752 route_change
= update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &attr
,
1753 1, &pi
, flags
, seq
);
1755 attr_new
= pi
->attr
;
1757 /* Perform route selection; this is just to set the flags correctly
1758 * as local route in the VNI always wins.
1760 evpn_route_select_install(bgp
, vpn
, rn
);
1761 bgp_unlock_node(rn
);
1763 /* If this is a new route or some attribute has changed, export the
1764 * route to the global table. The route will be advertised to peers
1765 * from there. Note that this table is a 2-level tree (RD-level +
1766 * Prefix-level) similar to L3VPN routes.
1769 struct bgp_path_info
*global_pi
;
1771 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
1772 (struct prefix
*)p
, &vpn
->prd
);
1773 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, attr_new
, 1,
1774 &global_pi
, flags
, seq
);
1776 /* Schedule for processing and unlock node. */
1777 bgp_process(bgp
, rn
, afi
, safi
);
1778 bgp_unlock_node(rn
);
1781 /* Unintern temporary. */
1782 aspath_unintern(&attr
.aspath
);
1788 * Delete EVPN route entry.
1789 * The entry can be in ESI/VNI table or the global table.
1791 static void delete_evpn_route_entry(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1792 struct bgp_node
*rn
,
1793 struct bgp_path_info
**pi
)
1795 struct bgp_path_info
*tmp_pi
;
1799 /* Now, find matching route. */
1800 for (tmp_pi
= rn
->info
; tmp_pi
; tmp_pi
= tmp_pi
->next
)
1801 if (tmp_pi
->peer
== bgp
->peer_self
1802 && tmp_pi
->type
== ZEBRA_ROUTE_BGP
1803 && tmp_pi
->sub_type
== BGP_ROUTE_STATIC
)
1808 /* Mark route for delete. */
1810 bgp_path_info_delete(rn
, tmp_pi
);
1815 /* Delete EVPN ES (type-4) route */
1816 static int delete_evpn_type4_route(struct bgp
*bgp
,
1818 struct prefix_evpn
*p
)
1820 afi_t afi
= AFI_L2VPN
;
1821 safi_t safi
= SAFI_EVPN
;
1822 struct bgp_path_info
*pi
;
1823 struct bgp_node
*rn
= NULL
; /* rn in esi table */
1824 struct bgp_node
*global_rn
= NULL
; /* rn in global table */
1826 /* First, locate the route node within the ESI.
1827 * If it doesn't exist, ther is nothing to do.
1828 * Note: there is no RD here.
1830 rn
= bgp_node_lookup(es
->route_table
, (struct prefix
*)p
);
1834 /* Next, locate route node in the global EVPN routing table.
1835 * Note that this table is a 2-level tree (RD-level + Prefix-level)
1837 global_rn
= bgp_afi_node_lookup(bgp
->rib
[afi
][safi
], afi
, safi
,
1838 (struct prefix
*)p
, &es
->prd
);
1841 /* Delete route entry in the global EVPN table. */
1842 delete_evpn_route_entry(bgp
, afi
, safi
, global_rn
, &pi
);
1844 /* Schedule for processing - withdraws to peers happen from
1848 bgp_process(bgp
, global_rn
, afi
, safi
);
1849 bgp_unlock_node(global_rn
);
1853 * Delete route entry in the ESI route table.
1854 * This can just be removed.
1856 delete_evpn_route_entry(bgp
, afi
, safi
, rn
, &pi
);
1858 bgp_path_info_reap(rn
, pi
);
1859 bgp_unlock_node(rn
);
1863 /* Delete EVPN type5 route */
1864 static int delete_evpn_type5_route(struct bgp
*bgp_vrf
, struct prefix_evpn
*evp
)
1866 afi_t afi
= AFI_L2VPN
;
1867 safi_t safi
= SAFI_EVPN
;
1868 struct bgp_node
*rn
= NULL
;
1869 struct bgp_path_info
*pi
= NULL
;
1870 struct bgp
*bgp_def
= NULL
; /* default bgp instance */
1872 bgp_def
= bgp_get_default();
1876 /* locate the global route entry for this type-5 prefix */
1877 rn
= bgp_afi_node_lookup(bgp_def
->rib
[afi
][safi
], afi
, safi
,
1878 (struct prefix
*)evp
, &bgp_vrf
->vrf_prd
);
1882 delete_evpn_route_entry(bgp_def
, afi
, safi
, rn
, &pi
);
1884 bgp_process(bgp_def
, rn
, afi
, safi
);
1885 bgp_unlock_node(rn
);
1890 * Delete EVPN route (of type based on prefix) for specified VNI and
1891 * schedule for processing.
1893 static int delete_evpn_route(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1894 struct prefix_evpn
*p
)
1896 struct bgp_node
*rn
, *global_rn
;
1897 struct bgp_path_info
*pi
;
1898 afi_t afi
= AFI_L2VPN
;
1899 safi_t safi
= SAFI_EVPN
;
1901 /* First, locate the route node within the VNI. If it doesn't exist,
1903 * is nothing further to do.
1905 /* NOTE: There is no RD here. */
1906 rn
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)p
);
1910 /* Next, locate route node in the global EVPN routing table. Note that
1911 * this table is a 2-level tree (RD-level + Prefix-level) similar to
1914 global_rn
= bgp_afi_node_lookup(bgp
->rib
[afi
][safi
], afi
, safi
,
1915 (struct prefix
*)p
, &vpn
->prd
);
1917 /* Delete route entry in the global EVPN table. */
1918 delete_evpn_route_entry(bgp
, afi
, safi
, global_rn
, &pi
);
1920 /* Schedule for processing - withdraws to peers happen from
1924 bgp_process(bgp
, global_rn
, afi
, safi
);
1925 bgp_unlock_node(global_rn
);
1928 /* Delete route entry in the VNI route table. This can just be removed.
1930 delete_evpn_route_entry(bgp
, afi
, safi
, rn
, &pi
);
1932 bgp_path_info_reap(rn
, pi
);
1933 bgp_unlock_node(rn
);
1939 * Update all type-2 (MACIP) local routes for this VNI - these should also
1940 * be scheduled for advertise to peers.
1942 static int update_all_type2_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1946 struct bgp_node
*rn
;
1947 struct bgp_path_info
*pi
, *tmp_pi
;
1949 struct attr
*attr_new
;
1951 int add_l3_ecomm
= 0;
1956 /* Walk this VNI's route table and update local type-2 routes. For any
1957 * routes updated, update corresponding entry in the global table too.
1959 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
1960 rn
= bgp_route_next(rn
)) {
1961 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
1962 struct bgp_node
*rd_rn
;
1963 struct bgp_path_info
*global_pi
;
1965 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
1968 /* Identify local route. */
1969 for (tmp_pi
= rn
->info
; tmp_pi
; tmp_pi
= tmp_pi
->next
) {
1970 if (tmp_pi
->peer
== bgp
->peer_self
1971 && tmp_pi
->type
== ZEBRA_ROUTE_BGP
1972 && tmp_pi
->sub_type
== BGP_ROUTE_STATIC
)
1980 * Build attribute per local route as the MAC mobility and
1981 * some other values could differ for different routes. The
1982 * attributes will be shared in the hash table.
1984 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
1985 attr
.nexthop
= vpn
->originator_ip
;
1986 attr
.mp_nexthop_global_in
= vpn
->originator_ip
;
1987 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1988 bgpevpn_get_rmac(vpn
, &attr
.rmac
);
1990 if (evpn_route_is_sticky(bgp
, rn
))
1992 else if (evpn_route_is_def_gw(bgp
, rn
)) {
1993 attr
.default_gw
= 1;
1994 if (is_evpn_prefix_ipaddr_v6(evp
))
1995 attr
.router_flag
= 1;
1998 /* Add L3 VNI RTs and RMAC for non IPv6 link-local if
1999 * using L3 VNI for type-2 routes also.
2001 if ((is_evpn_prefix_ipaddr_v4(evp
) ||
2002 !IN6_IS_ADDR_LINKLOCAL(
2003 &evp
->prefix
.macip_addr
.ip
.ipaddr_v6
)) &&
2004 CHECK_FLAG(vpn
->flags
, VNI_FLAG_USE_TWO_LABELS
) &&
2005 bgpevpn_get_l3vni(vpn
))
2008 /* Set up extended community. */
2009 build_evpn_route_extcomm(vpn
, &attr
, add_l3_ecomm
);
2011 seq
= mac_mobility_seqnum(tmp_pi
->attr
);
2013 /* Update the route entry. */
2014 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &attr
, 0, &pi
,
2017 /* Perform route selection; this is just to set the flags
2018 * correctly as local route in the VNI always wins.
2020 evpn_route_select_install(bgp
, vpn
, rn
);
2022 attr_new
= pi
->attr
;
2024 /* Update route in global routing table. */
2025 rd_rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
2026 (struct prefix
*)evp
, &vpn
->prd
);
2028 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rd_rn
, attr_new
, 0,
2030 mac_mobility_seqnum(attr_new
));
2032 /* Schedule for processing and unlock node. */
2033 bgp_process(bgp
, rd_rn
, afi
, safi
);
2034 bgp_unlock_node(rd_rn
);
2036 /* Unintern temporary. */
2037 aspath_unintern(&attr
.aspath
);
2045 * Delete all type-2 (MACIP) local routes for this VNI - only from the
2046 * global routing table. These are also scheduled for withdraw from peers.
2048 static int delete_global_type2_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2052 struct bgp_node
*rdrn
, *rn
;
2053 struct bgp_table
*table
;
2054 struct bgp_path_info
*pi
;
2059 rdrn
= bgp_node_lookup(bgp
->rib
[afi
][safi
], (struct prefix
*)&vpn
->prd
);
2060 if (rdrn
&& rdrn
->info
) {
2061 table
= (struct bgp_table
*)rdrn
->info
;
2062 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
2063 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
2065 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
2068 delete_evpn_route_entry(bgp
, afi
, safi
, rn
, &pi
);
2070 bgp_process(bgp
, rn
, afi
, safi
);
2074 /* Unlock RD node. */
2076 bgp_unlock_node(rdrn
);
2082 * Delete all type-2 (MACIP) local routes for this VNI - from the global
2083 * table as well as the per-VNI route table.
2085 static int delete_all_type2_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2089 struct bgp_node
*rn
;
2090 struct bgp_path_info
*pi
;
2095 /* First, walk the global route table for this VNI's type-2 local
2097 * EVPN routes are a 2-level table, first get the RD table.
2099 delete_global_type2_routes(bgp
, vpn
);
2101 /* Next, walk this VNI's route table and delete local type-2 routes. */
2102 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
2103 rn
= bgp_route_next(rn
)) {
2104 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
2106 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
2109 delete_evpn_route_entry(bgp
, afi
, safi
, rn
, &pi
);
2111 /* Route entry in local table gets deleted immediately. */
2113 bgp_path_info_reap(rn
, pi
);
2120 * Delete all routes in per ES route-table
2122 static int delete_all_es_routes(struct bgp
*bgp
, struct evpnes
*es
)
2124 struct bgp_node
*rn
;
2125 struct bgp_path_info
*pi
, *nextpi
;
2127 /* Walk this ES's route table and delete all routes. */
2128 for (rn
= bgp_table_top(es
->route_table
); rn
;
2129 rn
= bgp_route_next(rn
)) {
2130 for (pi
= rn
->info
; (pi
!= NULL
) && (nextpi
= pi
->next
, 1);
2132 bgp_path_info_delete(rn
, pi
);
2133 bgp_path_info_reap(rn
, pi
);
2141 * Delete all routes in the per-VNI route table.
2143 static int delete_all_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2145 struct bgp_node
*rn
;
2146 struct bgp_path_info
*pi
, *nextpi
;
2148 /* Walk this VNI's route table and delete all routes. */
2149 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
2150 rn
= bgp_route_next(rn
)) {
2151 for (pi
= rn
->info
; (pi
!= NULL
) && (nextpi
= pi
->next
, 1);
2153 bgp_path_info_delete(rn
, pi
);
2154 bgp_path_info_reap(rn
, pi
);
2162 * Update (and advertise) local routes for a VNI. Invoked upon the VNI
2163 * export RT getting modified or change to tunnel IP. Note that these
2164 * situations need the route in the per-VNI table as well as the global
2165 * table to be updated (as attributes change).
2167 static int update_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2170 struct prefix_evpn p
;
2172 /* Update and advertise the type-3 route (only one) followed by the
2173 * locally learnt type-2 routes (MACIP) - for this VNI.
2175 * RT-3 only if doing head-end replication
2177 if (bgp
->vxlan_flood_ctrl
== VXLAN_FLOOD_HEAD_END_REPL
) {
2178 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
2179 ret
= update_evpn_route(bgp
, vpn
, &p
, 0, 0);
2184 return update_all_type2_routes(bgp
, vpn
);
2187 /* Delete (and withdraw) local routes for specified ES from global and ES table.
2188 * Also remove all other routes from the per ES table.
2189 * Invoked when ES is deleted.
2191 static int delete_routes_for_es(struct bgp
*bgp
, struct evpnes
*es
)
2194 char buf
[ESI_STR_LEN
];
2195 struct prefix_evpn p
;
2197 /* Delete and withdraw locally learnt ES route */
2198 build_evpn_type4_prefix(&p
, &es
->esi
, es
->originator_ip
.ipaddr_v4
);
2199 ret
= delete_evpn_type4_route(bgp
, es
, &p
);
2201 flog_err(EC_BGP_EVPN_ROUTE_DELETE
,
2202 "%u failed to delete type-4 route for ESI %s",
2203 bgp
->vrf_id
, esi_to_str(&es
->esi
, buf
, sizeof(buf
)));
2206 /* Delete all routes from per ES table */
2207 return delete_all_es_routes(bgp
, es
);
2211 * Delete (and withdraw) local routes for specified VNI from the global
2212 * table and per-VNI table. After this, remove all other routes from
2213 * the per-VNI table. Invoked upon the VNI being deleted or EVPN
2214 * (advertise-all-vni) being disabled.
2216 static int delete_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2219 struct prefix_evpn p
;
2221 /* Delete and withdraw locally learnt type-2 routes (MACIP)
2222 * followed by type-3 routes (only one) - for this VNI.
2224 ret
= delete_all_type2_routes(bgp
, vpn
);
2228 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
2229 ret
= delete_evpn_route(bgp
, vpn
, &p
);
2233 /* Delete all routes from the per-VNI table. */
2234 return delete_all_vni_routes(bgp
, vpn
);
2238 * There is a tunnel endpoint IP address change for this VNI, delete
2239 * prior type-3 route (if needed) and update.
2240 * Note: Route re-advertisement happens elsewhere after other processing
2243 static int handle_tunnel_ip_change(struct bgp
*bgp
, struct bgpevpn
*vpn
,
2244 struct in_addr originator_ip
)
2246 struct prefix_evpn p
;
2248 /* If VNI is not live, we only need to update the originator ip */
2249 if (!is_vni_live(vpn
)) {
2250 vpn
->originator_ip
= originator_ip
;
2254 /* Update the tunnel-ip hash */
2255 bgp_tip_del(bgp
, &vpn
->originator_ip
);
2256 bgp_tip_add(bgp
, &originator_ip
);
2258 /* filter routes as martian nexthop db has changed */
2259 bgp_filter_evpn_routes_upon_martian_nh_change(bgp
);
2261 /* Need to withdraw type-3 route as the originator IP is part
2264 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
2265 delete_evpn_route(bgp
, vpn
, &p
);
2267 /* Update the tunnel IP and re-advertise all routes for this VNI. */
2268 vpn
->originator_ip
= originator_ip
;
2272 /* Install EVPN route entry in ES */
2273 static int install_evpn_route_entry_in_es(struct bgp
*bgp
, struct evpnes
*es
,
2274 struct prefix_evpn
*p
,
2275 struct bgp_path_info
*parent_pi
)
2278 struct bgp_node
*rn
= NULL
;
2279 struct bgp_path_info
*pi
= NULL
;
2280 struct attr
*attr_new
= NULL
;
2282 /* Create (or fetch) route within the VNI.
2283 * NOTE: There is no RD here.
2285 rn
= bgp_node_get(es
->route_table
, (struct prefix
*)p
);
2287 /* Check if route entry is already present. */
2288 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
2290 && (struct bgp_path_info
*)pi
->extra
->parent
== parent_pi
)
2294 /* Add (or update) attribute to hash. */
2295 attr_new
= bgp_attr_intern(parent_pi
->attr
);
2297 /* Create new route with its attribute. */
2298 pi
= info_make(parent_pi
->type
, BGP_ROUTE_IMPORTED
, 0,
2299 parent_pi
->peer
, attr_new
, rn
);
2300 SET_FLAG(pi
->flags
, BGP_PATH_VALID
);
2301 bgp_path_info_extra_get(pi
);
2302 pi
->extra
->parent
= parent_pi
;
2303 bgp_path_info_add(rn
, pi
);
2305 if (attrhash_cmp(pi
->attr
, parent_pi
->attr
)
2306 && !CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)) {
2307 bgp_unlock_node(rn
);
2310 /* The attribute has changed. */
2311 /* Add (or update) attribute to hash. */
2312 attr_new
= bgp_attr_intern(parent_pi
->attr
);
2314 /* Restore route, if needed. */
2315 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
))
2316 bgp_path_info_restore(rn
, pi
);
2318 /* Mark if nexthop has changed. */
2319 if (!IPV4_ADDR_SAME(&pi
->attr
->nexthop
, &attr_new
->nexthop
))
2320 SET_FLAG(pi
->flags
, BGP_PATH_IGP_CHANGED
);
2322 /* Unintern existing, set to new. */
2323 bgp_attr_unintern(&pi
->attr
);
2324 pi
->attr
= attr_new
;
2325 pi
->uptime
= bgp_clock();
2328 /* Perform route selection and update zebra, if required. */
2329 ret
= evpn_es_route_select_install(bgp
, es
, rn
);
2334 * Install route entry into the VRF routing table and invoke route selection.
2336 static int install_evpn_route_entry_in_vrf(struct bgp
*bgp_vrf
,
2337 struct prefix_evpn
*evp
,
2338 struct bgp_path_info
*parent_pi
)
2340 struct bgp_node
*rn
;
2341 struct bgp_path_info
*pi
;
2343 struct attr
*attr_new
;
2346 struct prefix
*pp
= &p
;
2349 char buf
[PREFIX_STRLEN
];
2350 char buf1
[PREFIX_STRLEN
];
2352 memset(pp
, 0, sizeof(struct prefix
));
2353 ip_prefix_from_evpn_prefix(evp
, pp
);
2355 if (bgp_debug_zebra(NULL
)) {
2357 "installing evpn prefix %s as ip prefix %s in vrf %s",
2358 prefix2str(evp
, buf
, sizeof(buf
)),
2359 prefix2str(pp
, buf1
, sizeof(buf
)),
2360 vrf_id_to_name(bgp_vrf
->vrf_id
));
2363 /* Create (or fetch) route within the VRF. */
2364 /* NOTE: There is no RD here. */
2365 if (is_evpn_prefix_ipaddr_v4(evp
)) {
2367 safi
= SAFI_UNICAST
;
2368 rn
= bgp_node_get(bgp_vrf
->rib
[afi
][safi
], pp
);
2369 } else if (is_evpn_prefix_ipaddr_v6(evp
)) {
2371 safi
= SAFI_UNICAST
;
2372 rn
= bgp_node_get(bgp_vrf
->rib
[afi
][safi
], pp
);
2376 /* EVPN routes currently only support a IPv4 next hop which corresponds
2377 * to the remote VTEP. When importing into a VRF, if it is IPv6 host
2378 * or prefix route, we have to convert the next hop to an IPv4-mapped
2379 * address for the rest of the code to flow through. In the case of IPv4,
2380 * make sure to set the flag for next hop attribute.
2382 bgp_attr_dup(&attr
, parent_pi
->attr
);
2384 evpn_convert_nexthop_to_ipv6(&attr
);
2386 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
);
2388 /* Check if route entry is already present. */
2389 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
2391 && (struct bgp_path_info
*)pi
->extra
->parent
== parent_pi
)
2395 /* Add (or update) attribute to hash. */
2396 attr_new
= bgp_attr_intern(&attr
);
2398 /* Create new route with its attribute. */
2399 pi
= info_make(parent_pi
->type
, BGP_ROUTE_IMPORTED
, 0,
2400 parent_pi
->peer
, attr_new
, rn
);
2401 SET_FLAG(pi
->flags
, BGP_PATH_VALID
);
2402 bgp_path_info_extra_get(pi
);
2403 pi
->extra
->parent
= bgp_path_info_lock(parent_pi
);
2404 bgp_lock_node((struct bgp_node
*)parent_pi
->net
);
2405 if (parent_pi
->extra
) {
2406 memcpy(&pi
->extra
->label
, &parent_pi
->extra
->label
,
2407 sizeof(pi
->extra
->label
));
2408 pi
->extra
->num_labels
= parent_pi
->extra
->num_labels
;
2410 bgp_path_info_add(rn
, pi
);
2412 if (attrhash_cmp(pi
->attr
, &attr
)
2413 && !CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)) {
2414 bgp_unlock_node(rn
);
2417 /* The attribute has changed. */
2418 /* Add (or update) attribute to hash. */
2419 attr_new
= bgp_attr_intern(&attr
);
2421 /* Restore route, if needed. */
2422 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
))
2423 bgp_path_info_restore(rn
, pi
);
2425 /* Mark if nexthop has changed. */
2427 && !IPV4_ADDR_SAME(&pi
->attr
->nexthop
, &attr_new
->nexthop
))
2429 && !IPV6_ADDR_SAME(&pi
->attr
->mp_nexthop_global
,
2430 &attr_new
->mp_nexthop_global
)))
2431 SET_FLAG(pi
->flags
, BGP_PATH_IGP_CHANGED
);
2433 /* Unintern existing, set to new. */
2434 bgp_attr_unintern(&pi
->attr
);
2435 pi
->attr
= attr_new
;
2436 pi
->uptime
= bgp_clock();
2439 bgp_aggregate_increment(bgp_vrf
, &rn
->p
, pi
, afi
, safi
);
2441 /* Perform route selection and update zebra, if required. */
2442 bgp_process(bgp_vrf
, rn
, afi
, safi
);
2448 * Install route entry into the VNI routing table and invoke route selection.
2450 static int install_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
2451 struct prefix_evpn
*p
,
2452 struct bgp_path_info
*parent_pi
)
2454 struct bgp_node
*rn
;
2455 struct bgp_path_info
*pi
;
2456 struct attr
*attr_new
;
2459 /* Create (or fetch) route within the VNI. */
2460 /* NOTE: There is no RD here. */
2461 rn
= bgp_node_get(vpn
->route_table
, (struct prefix
*)p
);
2463 /* Check if route entry is already present. */
2464 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
2466 && (struct bgp_path_info
*)pi
->extra
->parent
== parent_pi
)
2470 /* Add (or update) attribute to hash. */
2471 attr_new
= bgp_attr_intern(parent_pi
->attr
);
2473 /* Create new route with its attribute. */
2474 pi
= info_make(parent_pi
->type
, BGP_ROUTE_IMPORTED
, 0,
2475 parent_pi
->peer
, attr_new
, rn
);
2476 SET_FLAG(pi
->flags
, BGP_PATH_VALID
);
2477 bgp_path_info_extra_get(pi
);
2478 pi
->extra
->parent
= bgp_path_info_lock(parent_pi
);
2479 bgp_lock_node((struct bgp_node
*)parent_pi
->net
);
2480 if (parent_pi
->extra
) {
2481 memcpy(&pi
->extra
->label
, &parent_pi
->extra
->label
,
2482 sizeof(pi
->extra
->label
));
2483 pi
->extra
->num_labels
= parent_pi
->extra
->num_labels
;
2485 bgp_path_info_add(rn
, pi
);
2487 if (attrhash_cmp(pi
->attr
, parent_pi
->attr
)
2488 && !CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)) {
2489 bgp_unlock_node(rn
);
2492 /* The attribute has changed. */
2493 /* Add (or update) attribute to hash. */
2494 attr_new
= bgp_attr_intern(parent_pi
->attr
);
2496 /* Restore route, if needed. */
2497 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
))
2498 bgp_path_info_restore(rn
, pi
);
2500 /* Mark if nexthop has changed. */
2501 if (!IPV4_ADDR_SAME(&pi
->attr
->nexthop
, &attr_new
->nexthop
))
2502 SET_FLAG(pi
->flags
, BGP_PATH_IGP_CHANGED
);
2504 /* Unintern existing, set to new. */
2505 bgp_attr_unintern(&pi
->attr
);
2506 pi
->attr
= attr_new
;
2507 pi
->uptime
= bgp_clock();
2510 /* Perform route selection and update zebra, if required. */
2511 ret
= evpn_route_select_install(bgp
, vpn
, rn
);
2516 /* Uninstall EVPN route entry from ES route table */
2517 static int uninstall_evpn_route_entry_in_es(struct bgp
*bgp
, struct evpnes
*es
,
2518 struct prefix_evpn
*p
,
2519 struct bgp_path_info
*parent_pi
)
2522 struct bgp_node
*rn
;
2523 struct bgp_path_info
*pi
;
2525 if (!es
->route_table
)
2528 /* Locate route within the ESI.
2529 * NOTE: There is no RD here.
2531 rn
= bgp_node_lookup(es
->route_table
, (struct prefix
*)p
);
2535 /* Find matching route entry. */
2536 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
2538 && (struct bgp_path_info
*)pi
->extra
->parent
== parent_pi
)
2544 /* Mark entry for deletion */
2545 bgp_path_info_delete(rn
, pi
);
2547 /* Perform route selection and update zebra, if required. */
2548 ret
= evpn_es_route_select_install(bgp
, es
, rn
);
2550 /* Unlock route node. */
2551 bgp_unlock_node(rn
);
2557 * Uninstall route entry from the VRF routing table and send message
2558 * to zebra, if appropriate.
2560 static int uninstall_evpn_route_entry_in_vrf(struct bgp
*bgp_vrf
,
2561 struct prefix_evpn
*evp
,
2562 struct bgp_path_info
*parent_pi
)
2564 struct bgp_node
*rn
;
2565 struct bgp_path_info
*pi
;
2568 struct prefix
*pp
= &p
;
2571 char buf
[PREFIX_STRLEN
];
2572 char buf1
[PREFIX_STRLEN
];
2574 memset(pp
, 0, sizeof(struct prefix
));
2575 ip_prefix_from_evpn_prefix(evp
, pp
);
2577 if (bgp_debug_zebra(NULL
)) {
2579 "uninstalling evpn prefix %s as ip prefix %s in vrf %s",
2580 prefix2str(evp
, buf
, sizeof(buf
)),
2581 prefix2str(pp
, buf1
, sizeof(buf
)),
2582 vrf_id_to_name(bgp_vrf
->vrf_id
));
2585 /* Locate route within the VRF. */
2586 /* NOTE: There is no RD here. */
2587 if (is_evpn_prefix_ipaddr_v4(evp
)) {
2589 safi
= SAFI_UNICAST
;
2590 rn
= bgp_node_lookup(bgp_vrf
->rib
[afi
][safi
], pp
);
2593 safi
= SAFI_UNICAST
;
2594 rn
= bgp_node_lookup(bgp_vrf
->rib
[afi
][safi
], pp
);
2600 /* Find matching route entry. */
2601 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
2603 && (struct bgp_path_info
*)pi
->extra
->parent
== parent_pi
)
2609 bgp_aggregate_decrement(bgp_vrf
, &rn
->p
, pi
, afi
, safi
);
2611 /* Mark entry for deletion */
2612 bgp_path_info_delete(rn
, pi
);
2614 /* Perform route selection and update zebra, if required. */
2615 bgp_process(bgp_vrf
, rn
, afi
, safi
);
2617 /* Unlock route node. */
2618 bgp_unlock_node(rn
);
2624 * Uninstall route entry from the VNI routing table and send message
2625 * to zebra, if appropriate.
2627 static int uninstall_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
2628 struct prefix_evpn
*p
,
2629 struct bgp_path_info
*parent_pi
)
2631 struct bgp_node
*rn
;
2632 struct bgp_path_info
*pi
;
2635 /* Locate route within the VNI. */
2636 /* NOTE: There is no RD here. */
2637 rn
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)p
);
2641 /* Find matching route entry. */
2642 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
2644 && (struct bgp_path_info
*)pi
->extra
->parent
== parent_pi
)
2650 /* Mark entry for deletion */
2651 bgp_path_info_delete(rn
, pi
);
2653 /* Perform route selection and update zebra, if required. */
2654 ret
= evpn_route_select_install(bgp
, vpn
, rn
);
2656 /* Unlock route node. */
2657 bgp_unlock_node(rn
);
2663 * Given a prefix, see if it belongs to ES.
2665 static int is_prefix_matching_for_es(struct prefix_evpn
*p
,
2668 /* if not an ES route return false */
2669 if (p
->prefix
.route_type
!= BGP_EVPN_ES_ROUTE
)
2672 if (memcmp(&p
->prefix
.es_addr
.esi
, &es
->esi
, sizeof(esi_t
)) == 0)
2679 * Given a route entry and a VRF, see if this route entry should be
2680 * imported into the VRF i.e., RTs match.
2682 static int is_route_matching_for_vrf(struct bgp
*bgp_vrf
,
2683 struct bgp_path_info
*pi
)
2685 struct attr
*attr
= pi
->attr
;
2686 struct ecommunity
*ecom
;
2690 /* Route should have valid RT to be even considered. */
2691 if (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)))
2694 ecom
= attr
->ecommunity
;
2695 if (!ecom
|| !ecom
->size
)
2698 /* For each extended community RT, see if it matches this VNI. If any RT
2699 * matches, we're done.
2701 for (i
= 0; i
< ecom
->size
; i
++) {
2703 uint8_t type
, sub_type
;
2704 struct ecommunity_val
*eval
;
2705 struct ecommunity_val eval_tmp
;
2706 struct vrf_irt_node
*irt
;
2708 /* Only deal with RTs */
2709 pnt
= (ecom
->val
+ (i
* ECOMMUNITY_SIZE
));
2710 eval
= (struct ecommunity_val
*)(ecom
->val
2711 + (i
* ECOMMUNITY_SIZE
));
2714 if (sub_type
!= ECOMMUNITY_ROUTE_TARGET
)
2717 /* See if this RT matches specified VNIs import RTs */
2718 irt
= lookup_vrf_import_rt(eval
);
2720 if (is_vrf_present_in_irt_vrfs(irt
->vrfs
, bgp_vrf
))
2723 /* Also check for non-exact match. In this, we mask out the AS
2725 * only check on the local-admin sub-field. This is to
2727 * VNI as the RT for EBGP peering too.
2730 if (type
== ECOMMUNITY_ENCODE_AS
2731 || type
== ECOMMUNITY_ENCODE_AS4
2732 || type
== ECOMMUNITY_ENCODE_IP
) {
2733 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
2734 mask_ecom_global_admin(&eval_tmp
, eval
);
2735 irt
= lookup_vrf_import_rt(&eval_tmp
);
2738 if (is_vrf_present_in_irt_vrfs(irt
->vrfs
, bgp_vrf
))
2746 * Given a route entry and a VNI, see if this route entry should be
2747 * imported into the VNI i.e., RTs match.
2749 static int is_route_matching_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
,
2750 struct bgp_path_info
*pi
)
2752 struct attr
*attr
= pi
->attr
;
2753 struct ecommunity
*ecom
;
2757 /* Route should have valid RT to be even considered. */
2758 if (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)))
2761 ecom
= attr
->ecommunity
;
2762 if (!ecom
|| !ecom
->size
)
2765 /* For each extended community RT, see if it matches this VNI. If any RT
2766 * matches, we're done.
2768 for (i
= 0; i
< ecom
->size
; i
++) {
2770 uint8_t type
, sub_type
;
2771 struct ecommunity_val
*eval
;
2772 struct ecommunity_val eval_tmp
;
2773 struct irt_node
*irt
;
2775 /* Only deal with RTs */
2776 pnt
= (ecom
->val
+ (i
* ECOMMUNITY_SIZE
));
2777 eval
= (struct ecommunity_val
*)(ecom
->val
2778 + (i
* ECOMMUNITY_SIZE
));
2781 if (sub_type
!= ECOMMUNITY_ROUTE_TARGET
)
2784 /* See if this RT matches specified VNIs import RTs */
2785 irt
= lookup_import_rt(bgp
, eval
);
2787 if (is_vni_present_in_irt_vnis(irt
->vnis
, vpn
))
2790 /* Also check for non-exact match. In this, we mask out the AS
2792 * only check on the local-admin sub-field. This is to
2794 * VNI as the RT for EBGP peering too.
2797 if (type
== ECOMMUNITY_ENCODE_AS
2798 || type
== ECOMMUNITY_ENCODE_AS4
2799 || type
== ECOMMUNITY_ENCODE_IP
) {
2800 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
2801 mask_ecom_global_admin(&eval_tmp
, eval
);
2802 irt
= lookup_import_rt(bgp
, &eval_tmp
);
2805 if (is_vni_present_in_irt_vnis(irt
->vnis
, vpn
))
2812 static int install_uninstall_routes_for_es(struct bgp
*bgp
,
2819 char buf
[PREFIX_STRLEN
];
2820 char buf1
[ESI_STR_LEN
];
2821 struct bgp_node
*rd_rn
, *rn
;
2822 struct bgp_table
*table
;
2823 struct bgp_path_info
*pi
;
2829 * Walk entire global routing table and evaluate routes which could be
2830 * imported into this VRF. Note that we need to loop through all global
2831 * routes to determine which route matches the import rt on vrf
2833 for (rd_rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rd_rn
;
2834 rd_rn
= bgp_route_next(rd_rn
)) {
2835 table
= (struct bgp_table
*)(rd_rn
->info
);
2839 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
2840 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
2842 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
2844 * Consider "valid" remote routes applicable for
2847 if (!(CHECK_FLAG(pi
->flags
, BGP_PATH_VALID
)
2848 && pi
->type
== ZEBRA_ROUTE_BGP
2849 && pi
->sub_type
== BGP_ROUTE_NORMAL
))
2852 if (!is_prefix_matching_for_es(evp
, es
))
2856 ret
= install_evpn_route_entry_in_es(
2859 ret
= uninstall_evpn_route_entry_in_es(
2865 "Failed to %s EVPN %s route in ESI %s",
2868 prefix2str(evp
, buf
,
2870 esi_to_str(&es
->esi
, buf1
,
2881 * Install or uninstall mac-ip routes are appropriate for this
2884 static int install_uninstall_routes_for_vrf(struct bgp
*bgp_vrf
, int install
)
2888 struct bgp_node
*rd_rn
, *rn
;
2889 struct bgp_table
*table
;
2890 struct bgp_path_info
*pi
;
2892 char buf
[PREFIX_STRLEN
];
2893 struct bgp
*bgp_def
= NULL
;
2897 bgp_def
= bgp_get_default();
2901 /* Walk entire global routing table and evaluate routes which could be
2902 * imported into this VRF. Note that we need to loop through all global
2903 * routes to determine which route matches the import rt on vrf
2905 for (rd_rn
= bgp_table_top(bgp_def
->rib
[afi
][safi
]); rd_rn
;
2906 rd_rn
= bgp_route_next(rd_rn
)) {
2907 table
= (struct bgp_table
*)(rd_rn
->info
);
2911 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
2912 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
2914 /* if not mac-ip route skip this route */
2915 if (!(evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
2916 || evp
->prefix
.route_type
2917 == BGP_EVPN_IP_PREFIX_ROUTE
))
2920 /* if not a mac+ip route skip this route */
2921 if (!(is_evpn_prefix_ipaddr_v4(evp
)
2922 || is_evpn_prefix_ipaddr_v6(evp
)))
2925 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
2926 /* Consider "valid" remote routes applicable for
2929 if (!(CHECK_FLAG(pi
->flags
, BGP_PATH_VALID
)
2930 && pi
->type
== ZEBRA_ROUTE_BGP
2931 && pi
->sub_type
== BGP_ROUTE_NORMAL
))
2934 if (is_route_matching_for_vrf(bgp_vrf
, pi
)) {
2936 ret
= install_evpn_route_entry_in_vrf(
2939 ret
= uninstall_evpn_route_entry_in_vrf(
2945 "Failed to %s EVPN %s route in VRF %s",
2948 prefix2str(evp
, buf
,
2963 * Install or uninstall routes of specified type that are appropriate for this
2966 static int install_uninstall_routes_for_vni(struct bgp
*bgp
,
2967 struct bgpevpn
*vpn
,
2968 bgp_evpn_route_type rtype
,
2973 struct bgp_node
*rd_rn
, *rn
;
2974 struct bgp_table
*table
;
2975 struct bgp_path_info
*pi
;
2981 /* Walk entire global routing table and evaluate routes which could be
2982 * imported into this VPN. Note that we cannot just look at the routes
2984 * the VNI's RD - remote routes applicable for this VNI could have any
2987 /* EVPN routes are a 2-level table. */
2988 for (rd_rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rd_rn
;
2989 rd_rn
= bgp_route_next(rd_rn
)) {
2990 table
= (struct bgp_table
*)(rd_rn
->info
);
2994 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
2995 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
2997 if (evp
->prefix
.route_type
!= rtype
)
3000 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
3001 /* Consider "valid" remote routes applicable for
3003 if (!(CHECK_FLAG(pi
->flags
, BGP_PATH_VALID
)
3004 && pi
->type
== ZEBRA_ROUTE_BGP
3005 && pi
->sub_type
== BGP_ROUTE_NORMAL
))
3008 if (is_route_matching_for_vni(bgp
, vpn
, pi
)) {
3010 ret
= install_evpn_route_entry(
3013 ret
= uninstall_evpn_route_entry(
3019 "%u: Failed to %s EVPN %s route in VNI %u",
3023 rtype
== BGP_EVPN_MAC_IP_ROUTE
3037 /* Install any existing remote ES routes applicable for this ES into its routing
3038 * table. This is invoked when ES comes up.
3040 static int install_routes_for_es(struct bgp
*bgp
, struct evpnes
*es
)
3042 return install_uninstall_routes_for_es(bgp
, es
, 1);
3046 /* Install any existing remote routes applicable for this VRF into VRF RIB. This
3047 * is invoked upon l3vni-add or l3vni import rt change
3049 static int install_routes_for_vrf(struct bgp
*bgp_vrf
)
3051 install_uninstall_routes_for_vrf(bgp_vrf
, 1);
3056 * Install any existing remote routes applicable for this VNI into its
3057 * routing table. This is invoked when a VNI becomes "live" or its Import
3060 static int install_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
3064 /* Install type-3 routes followed by type-2 routes - the ones applicable
3067 ret
= install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_IMET_ROUTE
,
3072 return install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_MAC_IP_ROUTE
,
3076 /* uninstall routes from l3vni vrf. */
3077 static int uninstall_routes_for_vrf(struct bgp
*bgp_vrf
)
3079 install_uninstall_routes_for_vrf(bgp_vrf
, 0);
3084 * Uninstall any existing remote routes for this VNI. One scenario in which
3085 * this is invoked is upon an import RT change.
3087 static int uninstall_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
3091 /* Uninstall type-2 routes followed by type-3 routes - the ones
3095 ret
= install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_MAC_IP_ROUTE
,
3100 return install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_IMET_ROUTE
,
3104 /* Install or unistall route in ES */
3105 static int install_uninstall_route_in_es(struct bgp
*bgp
, struct evpnes
*es
,
3106 afi_t afi
, safi_t safi
,
3107 struct prefix_evpn
*evp
,
3108 struct bgp_path_info
*pi
, int install
)
3111 char buf
[ESI_STR_LEN
];
3114 ret
= install_evpn_route_entry_in_es(bgp
, es
, evp
, pi
);
3116 ret
= uninstall_evpn_route_entry_in_es(bgp
, es
, evp
, pi
);
3121 "%u: Failed to %s EVPN %s route in ESI %s", bgp
->vrf_id
,
3122 install
? "install" : "uninstall", "ES",
3123 esi_to_str(&evp
->prefix
.es_addr
.esi
, buf
, sizeof(buf
)));
3130 * Install or uninstall route in matching VRFs (list).
3132 static int install_uninstall_route_in_vrfs(struct bgp
*bgp_def
, afi_t afi
,
3133 safi_t safi
, struct prefix_evpn
*evp
,
3134 struct bgp_path_info
*pi
,
3135 struct list
*vrfs
, int install
)
3137 char buf
[PREFIX2STR_BUFFER
];
3138 struct bgp
*bgp_vrf
;
3139 struct listnode
*node
, *nnode
;
3141 /* Only type-2/type-5 routes go into a VRF */
3142 if (!(evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
3143 || evp
->prefix
.route_type
== BGP_EVPN_IP_PREFIX_ROUTE
))
3146 /* if it is type-2 route and not a mac+ip route skip this route */
3147 if ((evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
)
3148 && !(is_evpn_prefix_ipaddr_v4(evp
)
3149 || is_evpn_prefix_ipaddr_v6(evp
)))
3152 for (ALL_LIST_ELEMENTS(vrfs
, node
, nnode
, bgp_vrf
)) {
3156 ret
= install_evpn_route_entry_in_vrf(bgp_vrf
, evp
, pi
);
3158 ret
= uninstall_evpn_route_entry_in_vrf(bgp_vrf
, evp
,
3162 flog_err(EC_BGP_EVPN_FAIL
,
3163 "%u: Failed to %s prefix %s in VRF %s",
3165 install
? "install" : "uninstall",
3166 prefix2str(evp
, buf
, sizeof(buf
)),
3167 vrf_id_to_name(bgp_vrf
->vrf_id
));
3176 * Install or uninstall route in matching VNIs (list).
3178 static int install_uninstall_route_in_vnis(struct bgp
*bgp
, afi_t afi
,
3179 safi_t safi
, struct prefix_evpn
*evp
,
3180 struct bgp_path_info
*pi
,
3181 struct list
*vnis
, int install
)
3183 struct bgpevpn
*vpn
;
3184 struct listnode
*node
, *nnode
;
3186 for (ALL_LIST_ELEMENTS(vnis
, node
, nnode
, vpn
)) {
3189 if (!is_vni_live(vpn
))
3193 ret
= install_evpn_route_entry(bgp
, vpn
, evp
, pi
);
3195 ret
= uninstall_evpn_route_entry(bgp
, vpn
, evp
, pi
);
3198 flog_err(EC_BGP_EVPN_FAIL
,
3199 "%u: Failed to %s EVPN %s route in VNI %u",
3200 bgp
->vrf_id
, install
? "install" : "uninstall",
3201 evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
3213 * Install or uninstall route for appropriate VNIs/ESIs.
3215 static int install_uninstall_evpn_route(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
3217 struct bgp_path_info
*pi
, int import
)
3219 struct prefix_evpn
*evp
= (struct prefix_evpn
*)p
;
3220 struct attr
*attr
= pi
->attr
;
3221 struct ecommunity
*ecom
;
3226 /* Only type-2, type-3, type-4 and type-5 are supported currently */
3227 if (!(evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
3228 || evp
->prefix
.route_type
== BGP_EVPN_IMET_ROUTE
3229 || evp
->prefix
.route_type
== BGP_EVPN_ES_ROUTE
3230 || evp
->prefix
.route_type
== BGP_EVPN_IP_PREFIX_ROUTE
))
3233 /* If we don't have Route Target, nothing much to do. */
3234 if (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)))
3237 ecom
= attr
->ecommunity
;
3238 if (!ecom
|| !ecom
->size
)
3241 /* An EVPN route belongs to a VNI or a VRF or an ESI based on the RTs
3242 * attached to the route */
3243 for (i
= 0; i
< ecom
->size
; i
++) {
3245 uint8_t type
, sub_type
;
3246 struct ecommunity_val
*eval
;
3247 struct ecommunity_val eval_tmp
;
3248 struct irt_node
*irt
; /* import rt for l2vni */
3249 struct vrf_irt_node
*vrf_irt
; /* import rt for l3vni */
3252 /* Only deal with RTs */
3253 pnt
= (ecom
->val
+ (i
* ECOMMUNITY_SIZE
));
3254 eval
= (struct ecommunity_val
*)(ecom
->val
3255 + (i
* ECOMMUNITY_SIZE
));
3258 if (sub_type
!= ECOMMUNITY_ROUTE_TARGET
)
3262 * macip routes (type-2) are imported into VNI and VRF tables.
3263 * IMET route is imported into VNI table.
3264 * prefix routes are imported into VRF table.
3266 if (evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
||
3267 evp
->prefix
.route_type
== BGP_EVPN_IMET_ROUTE
||
3268 evp
->prefix
.route_type
== BGP_EVPN_IP_PREFIX_ROUTE
) {
3270 irt
= lookup_import_rt(bgp
, eval
);
3272 install_uninstall_route_in_vnis(
3273 bgp
, afi
, safi
, evp
, pi
, irt
->vnis
,
3276 vrf_irt
= lookup_vrf_import_rt(eval
);
3278 install_uninstall_route_in_vrfs(
3279 bgp
, afi
, safi
, evp
, pi
, vrf_irt
->vrfs
,
3282 /* Also check for non-exact match.
3283 * In this, we mask out the AS and
3284 * only check on the local-admin sub-field.
3285 * This is to facilitate using
3286 * VNI as the RT for EBGP peering too.
3290 if (type
== ECOMMUNITY_ENCODE_AS
3291 || type
== ECOMMUNITY_ENCODE_AS4
3292 || type
== ECOMMUNITY_ENCODE_IP
) {
3293 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
3294 mask_ecom_global_admin(&eval_tmp
, eval
);
3295 irt
= lookup_import_rt(bgp
, &eval_tmp
);
3296 vrf_irt
= lookup_vrf_import_rt(&eval_tmp
);
3300 install_uninstall_route_in_vnis(
3301 bgp
, afi
, safi
, evp
, pi
, irt
->vnis
,
3304 install_uninstall_route_in_vrfs(
3305 bgp
, afi
, safi
, evp
, pi
, vrf_irt
->vrfs
,
3309 /* es route is imported into the es table */
3310 if (evp
->prefix
.route_type
== BGP_EVPN_ES_ROUTE
) {
3312 /* we will match based on the entire esi to avoid
3313 * imoort of an es route for esi2 into esi1
3315 es
= bgp_evpn_lookup_es(bgp
, &evp
->prefix
.es_addr
.esi
);
3316 if (es
&& is_es_local(es
))
3317 install_uninstall_route_in_es(
3318 bgp
, es
, afi
, safi
, evp
, pi
, import
);
3326 * delete and withdraw all ipv4 and ipv6 routes in the vrf table as type-5
3329 static void delete_withdraw_vrf_routes(struct bgp
*bgp_vrf
)
3331 /* delete all ipv4 routes and withdraw from peers */
3332 if (advertise_type5_routes(bgp_vrf
, AFI_IP
))
3333 bgp_evpn_withdraw_type5_routes(bgp_vrf
, AFI_IP
, SAFI_UNICAST
);
3335 /* delete all ipv6 routes and withdraw from peers */
3336 if (advertise_type5_routes(bgp_vrf
, AFI_IP6
))
3337 bgp_evpn_withdraw_type5_routes(bgp_vrf
, AFI_IP6
, SAFI_UNICAST
);
3341 * update and advertise all ipv4 and ipv6 routes in thr vrf table as type-5
3344 static void update_advertise_vrf_routes(struct bgp
*bgp_vrf
)
3346 /* update all ipv4 routes */
3347 if (advertise_type5_routes(bgp_vrf
, AFI_IP
))
3348 bgp_evpn_advertise_type5_routes(bgp_vrf
, AFI_IP
, SAFI_UNICAST
);
3350 /* update all ipv6 routes */
3351 if (advertise_type5_routes(bgp_vrf
, AFI_IP6
))
3352 bgp_evpn_advertise_type5_routes(bgp_vrf
, AFI_IP6
, SAFI_UNICAST
);
3356 * update and advertise local routes for a VRF as type-5 routes.
3357 * This is invoked upon RD change for a VRF. Note taht the processing is only
3358 * done in the global route table using the routes which already exist in the
3361 static void update_router_id_vrf(struct bgp
*bgp_vrf
)
3363 /* skip if the RD is configured */
3364 if (is_vrf_rd_configured(bgp_vrf
))
3367 /* derive the RD for the VRF based on new router-id */
3368 bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf
);
3370 /* update advertise ipv4|ipv6 routes as type-5 routes */
3371 update_advertise_vrf_routes(bgp_vrf
);
3375 * Delete and withdraw all type-5 routes for the RD corresponding to VRF.
3376 * This is invoked upon VRF RD change. The processing is done only from global
3379 static void withdraw_router_id_vrf(struct bgp
*bgp_vrf
)
3381 /* skip if the RD is configured */
3382 if (is_vrf_rd_configured(bgp_vrf
))
3385 /* delete/withdraw ipv4|ipv6 routes as type-5 routes */
3386 delete_withdraw_vrf_routes(bgp_vrf
);
3390 * Update and advertise local routes for a VNI. Invoked upon router-id
3391 * change. Note that the processing is done only on the global route table
3392 * using routes that already exist in the per-VNI table.
3394 static int update_advertise_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
3396 struct prefix_evpn p
;
3397 struct bgp_node
*rn
, *global_rn
;
3398 struct bgp_path_info
*pi
, *global_pi
;
3400 afi_t afi
= AFI_L2VPN
;
3401 safi_t safi
= SAFI_EVPN
;
3403 /* Locate type-3 route for VNI in the per-VNI table and use its
3404 * attributes to create and advertise the type-3 route for this VNI
3405 * in the global table.
3407 * RT-3 only if doing head-end replication
3409 if (bgp
->vxlan_flood_ctrl
== VXLAN_FLOOD_HEAD_END_REPL
) {
3410 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
3411 rn
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)&p
);
3412 if (!rn
) /* unexpected */
3414 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
3415 if (pi
->peer
== bgp
->peer_self
&&
3416 pi
->type
== ZEBRA_ROUTE_BGP
3417 && pi
->sub_type
== BGP_ROUTE_STATIC
)
3419 if (!pi
) /* unexpected */
3423 global_rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
3424 (struct prefix
*)&p
, &vpn
->prd
);
3425 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, attr
,
3426 1, &pi
, 0, mac_mobility_seqnum(attr
));
3428 /* Schedule for processing and unlock node. */
3429 bgp_process(bgp
, global_rn
, afi
, safi
);
3430 bgp_unlock_node(global_rn
);
3433 /* Now, walk this VNI's route table and use the route and its attribute
3434 * to create and schedule route in global table.
3436 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
3437 rn
= bgp_route_next(rn
)) {
3438 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
3440 /* Identify MAC-IP local routes. */
3441 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
3444 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
3445 if (pi
->peer
== bgp
->peer_self
3446 && pi
->type
== ZEBRA_ROUTE_BGP
3447 && pi
->sub_type
== BGP_ROUTE_STATIC
)
3452 /* Create route in global routing table using this route entry's
3456 global_rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
3457 (struct prefix
*)evp
, &vpn
->prd
);
3459 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, attr
, 1,
3461 mac_mobility_seqnum(attr
));
3463 /* Schedule for processing and unlock node. */
3464 bgp_process(bgp
, global_rn
, afi
, safi
);
3465 bgp_unlock_node(global_rn
);
3472 * Delete (and withdraw) local routes for a VNI - only from the global
3473 * table. Invoked upon router-id change.
3475 static int delete_withdraw_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
3478 struct prefix_evpn p
;
3479 struct bgp_node
*global_rn
;
3480 struct bgp_path_info
*pi
;
3481 afi_t afi
= AFI_L2VPN
;
3482 safi_t safi
= SAFI_EVPN
;
3484 /* Delete and withdraw locally learnt type-2 routes (MACIP)
3485 * for this VNI - from the global table.
3487 ret
= delete_global_type2_routes(bgp
, vpn
);
3491 /* Remove type-3 route for this VNI from global table. */
3492 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
3493 global_rn
= bgp_afi_node_lookup(bgp
->rib
[afi
][safi
], afi
, safi
,
3494 (struct prefix
*)&p
, &vpn
->prd
);
3496 /* Delete route entry in the global EVPN table. */
3497 delete_evpn_route_entry(bgp
, afi
, safi
, global_rn
, &pi
);
3499 /* Schedule for processing - withdraws to peers happen from
3503 bgp_process(bgp
, global_rn
, afi
, safi
);
3504 bgp_unlock_node(global_rn
);
3511 * Handle router-id change. Update and advertise local routes corresponding
3512 * to this VNI from peers. Note that this is invoked after updating the
3513 * router-id. The routes in the per-VNI table are used to create routes in
3514 * the global table and schedule them.
3516 static void update_router_id_vni(struct hash_backet
*backet
, struct bgp
*bgp
)
3518 struct bgpevpn
*vpn
= (struct bgpevpn
*)backet
->data
;
3520 /* Skip VNIs with configured RD. */
3521 if (is_rd_configured(vpn
))
3524 bgp_evpn_derive_auto_rd(bgp
, vpn
);
3525 update_advertise_vni_routes(bgp
, vpn
);
3529 * Handle router-id change. Delete and withdraw local routes corresponding
3530 * to this VNI from peers. Note that this is invoked prior to updating
3531 * the router-id and is done only on the global route table, the routes
3532 * are needed in the per-VNI table to re-advertise with new router id.
3534 static void withdraw_router_id_vni(struct hash_backet
*backet
, struct bgp
*bgp
)
3536 struct bgpevpn
*vpn
= (struct bgpevpn
*)backet
->data
;
3538 /* Skip VNIs with configured RD. */
3539 if (is_rd_configured(vpn
))
3542 delete_withdraw_vni_routes(bgp
, vpn
);
3546 * Create RT-3 for a VNI and schedule for processing and advertisement.
3547 * This is invoked upon flooding mode changing to head-end replication.
3549 static void create_advertise_type3(struct hash_backet
*backet
, void *data
)
3551 struct bgpevpn
*vpn
= backet
->data
;
3552 struct bgp
*bgp
= data
;
3553 struct prefix_evpn p
;
3555 if (!vpn
|| !is_vni_live(vpn
))
3558 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
3559 if (update_evpn_route(bgp
, vpn
, &p
, 0, 0))
3560 flog_err(EC_BGP_EVPN_ROUTE_CREATE
,
3561 "Type3 route creation failure for VNI %u", vpn
->vni
);
3565 * Delete RT-3 for a VNI and schedule for processing and withdrawal.
3566 * This is invoked upon flooding mode changing to drop BUM packets.
3568 static void delete_withdraw_type3(struct hash_backet
*backet
, void *data
)
3570 struct bgpevpn
*vpn
= backet
->data
;
3571 struct bgp
*bgp
= data
;
3572 struct prefix_evpn p
;
3574 if (!vpn
|| !is_vni_live(vpn
))
3577 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
3578 delete_evpn_route(bgp
, vpn
, &p
);
3582 * Process received EVPN type-2 route (advertise or withdraw).
3584 static int process_type2_route(struct peer
*peer
, afi_t afi
, safi_t safi
,
3585 struct attr
*attr
, uint8_t *pfx
, int psize
,
3586 uint32_t addpath_id
)
3588 struct prefix_rd prd
;
3589 struct prefix_evpn p
;
3590 struct bgp_route_evpn evpn
;
3592 uint8_t macaddr_len
;
3593 mpls_label_t label
[BGP_MAX_LABELS
]; /* holds the VNI(s) as in packet */
3594 uint32_t num_labels
= 0;
3598 /* Type-2 route should be either 33, 37 or 49 bytes or an
3599 * additional 3 bytes if there is a second label (VNI):
3600 * RD (8), ESI (10), Eth Tag (4), MAC Addr Len (1),
3601 * MAC Addr (6), IP len (1), IP (0, 4 or 16),
3602 * MPLS Lbl1 (3), MPLS Lbl2 (0 or 3)
3604 if (psize
!= 33 && psize
!= 37 && psize
!= 49 && psize
!= 36
3605 && psize
!= 40 && psize
!= 52) {
3606 flog_err(EC_BGP_EVPN_ROUTE_INVALID
,
3607 "%u:%s - Rx EVPN Type-2 NLRI with invalid length %d",
3608 peer
->bgp
->vrf_id
, peer
->host
, psize
);
3612 memset(&evpn
, 0, sizeof(evpn
));
3614 /* Make prefix_rd */
3615 prd
.family
= AF_UNSPEC
;
3617 memcpy(&prd
.val
, pfx
, 8);
3620 /* Make EVPN prefix. */
3621 memset(&p
, 0, sizeof(struct prefix_evpn
));
3623 p
.prefixlen
= EVPN_ROUTE_PREFIXLEN
;
3624 p
.prefix
.route_type
= BGP_EVPN_MAC_IP_ROUTE
;
3626 /* Copy Ethernet Seg Identifier */
3627 memcpy(&evpn
.eth_s_id
.val
, pfx
, ESI_LEN
);
3630 /* Copy Ethernet Tag */
3631 memcpy(ð_tag
, pfx
, 4);
3632 p
.prefix
.macip_addr
.eth_tag
= ntohl(eth_tag
);
3635 /* Get the MAC Addr len */
3636 macaddr_len
= *pfx
++;
3638 /* Get the MAC Addr */
3639 if (macaddr_len
== (ETH_ALEN
* 8)) {
3640 memcpy(&p
.prefix
.macip_addr
.mac
.octet
, pfx
, ETH_ALEN
);
3644 EC_BGP_EVPN_ROUTE_INVALID
,
3645 "%u:%s - Rx EVPN Type-2 NLRI with unsupported MAC address length %d",
3646 peer
->bgp
->vrf_id
, peer
->host
, macaddr_len
);
3652 ipaddr_len
= *pfx
++;
3653 if (ipaddr_len
!= 0 && ipaddr_len
!= IPV4_MAX_BITLEN
3654 && ipaddr_len
!= IPV6_MAX_BITLEN
) {
3656 EC_BGP_EVPN_ROUTE_INVALID
,
3657 "%u:%s - Rx EVPN Type-2 NLRI with unsupported IP address length %d",
3658 peer
->bgp
->vrf_id
, peer
->host
, ipaddr_len
);
3663 ipaddr_len
/= 8; /* Convert to bytes. */
3664 p
.prefix
.macip_addr
.ip
.ipa_type
= (ipaddr_len
== IPV4_MAX_BYTELEN
)
3667 memcpy(&p
.prefix
.macip_addr
.ip
.ip
.addr
, pfx
, ipaddr_len
);
3671 /* Get the VNI(s). Stored as bytes here. */
3673 memset(label
, 0, sizeof(label
));
3674 memcpy(&label
[0], pfx
, BGP_LABEL_BYTES
);
3675 pfx
+= BGP_LABEL_BYTES
;
3676 psize
-= (33 + ipaddr_len
);
3677 /* Do we have a second VNI? */
3680 memcpy(&label
[1], pfx
, BGP_LABEL_BYTES
);
3682 * If in future, we are required to access additional fields,
3683 * we MUST increment pfx by BGP_LABEL_BYTES in before reading
3688 /* Process the route. */
3690 ret
= bgp_update(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
3691 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3692 &prd
, &label
[0], num_labels
, 0, &evpn
);
3694 ret
= bgp_withdraw(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
3695 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3696 &prd
, &label
[0], num_labels
, &evpn
);
3701 * Process received EVPN type-3 route (advertise or withdraw).
3703 static int process_type3_route(struct peer
*peer
, afi_t afi
, safi_t safi
,
3704 struct attr
*attr
, uint8_t *pfx
, int psize
,
3705 uint32_t addpath_id
)
3707 struct prefix_rd prd
;
3708 struct prefix_evpn p
;
3713 /* Type-3 route should be either 17 or 29 bytes: RD (8), Eth Tag (4),
3714 * IP len (1) and IP (4 or 16).
3716 if (psize
!= 17 && psize
!= 29) {
3717 flog_err(EC_BGP_EVPN_ROUTE_INVALID
,
3718 "%u:%s - Rx EVPN Type-3 NLRI with invalid length %d",
3719 peer
->bgp
->vrf_id
, peer
->host
, psize
);
3723 /* If PMSI is present, log if it is anything other than IR.
3724 * Note: We just simply ignore the values as it is not clear if
3725 * doing anything else is better.
3728 (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL
))) {
3729 if (attr
->pmsi_tnl_type
!= PMSI_TNLTYPE_INGR_REPL
) {
3731 EC_BGP_EVPN_PMSI_PRESENT
,
3732 "%u:%s - Rx EVPN Type-3 NLRI with unsupported PTA %d",
3733 peer
->bgp
->vrf_id
, peer
->host
,
3734 attr
->pmsi_tnl_type
);
3738 /* Make prefix_rd */
3739 prd
.family
= AF_UNSPEC
;
3741 memcpy(&prd
.val
, pfx
, 8);
3744 /* Make EVPN prefix. */
3745 memset(&p
, 0, sizeof(struct prefix_evpn
));
3747 p
.prefixlen
= EVPN_ROUTE_PREFIXLEN
;
3748 p
.prefix
.route_type
= BGP_EVPN_IMET_ROUTE
;
3750 /* Copy Ethernet Tag */
3751 memcpy(ð_tag
, pfx
, 4);
3752 p
.prefix
.imet_addr
.eth_tag
= ntohl(eth_tag
);
3756 ipaddr_len
= *pfx
++;
3757 if (ipaddr_len
== IPV4_MAX_BITLEN
) {
3758 p
.prefix
.imet_addr
.ip
.ipa_type
= IPADDR_V4
;
3759 memcpy(&p
.prefix
.imet_addr
.ip
.ip
.addr
, pfx
, IPV4_MAX_BYTELEN
);
3762 EC_BGP_EVPN_ROUTE_INVALID
,
3763 "%u:%s - Rx EVPN Type-3 NLRI with unsupported IP address length %d",
3764 peer
->bgp
->vrf_id
, peer
->host
, ipaddr_len
);
3768 /* Process the route. */
3770 ret
= bgp_update(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
3771 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3772 &prd
, NULL
, 0, 0, NULL
);
3774 ret
= bgp_withdraw(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
3775 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3776 &prd
, NULL
, 0, NULL
);
3781 * Process received EVPN type-4 route (advertise or withdraw).
3783 static int process_type4_route(struct peer
*peer
, afi_t afi
, safi_t safi
,
3784 struct attr
*attr
, uint8_t *pfx
, int psize
,
3785 uint32_t addpath_id
)
3790 struct in_addr vtep_ip
;
3791 struct prefix_rd prd
;
3792 struct prefix_evpn p
;
3794 /* Type-4 route should be either 23 or 35 bytes
3795 * RD (8), ESI (10), ip-len (1), ip (4 or 16)
3797 if (psize
!= 23 && psize
!= 35) {
3798 flog_err(EC_BGP_EVPN_ROUTE_INVALID
,
3799 "%u:%s - Rx EVPN Type-4 NLRI with invalid length %d",
3800 peer
->bgp
->vrf_id
, peer
->host
, psize
);
3804 /* Make prefix_rd */
3805 prd
.family
= AF_UNSPEC
;
3807 memcpy(&prd
.val
, pfx
, 8);
3811 memcpy(&esi
, pfx
, ESI_BYTES
);
3816 ipaddr_len
= *pfx
++;
3817 if (ipaddr_len
== IPV4_MAX_BITLEN
) {
3818 memcpy(&vtep_ip
, pfx
, IPV4_MAX_BYTELEN
);
3821 EC_BGP_EVPN_ROUTE_INVALID
,
3822 "%u:%s - Rx EVPN Type-4 NLRI with unsupported IP address length %d",
3823 peer
->bgp
->vrf_id
, peer
->host
, ipaddr_len
);
3827 build_evpn_type4_prefix(&p
, &esi
, vtep_ip
);
3828 /* Process the route. */
3830 ret
= bgp_update(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
3831 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3832 &prd
, NULL
, 0, 0, NULL
);
3834 ret
= bgp_withdraw(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
3835 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3836 &prd
, NULL
, 0, NULL
);
3843 * Process received EVPN type-5 route (advertise or withdraw).
3845 static int process_type5_route(struct peer
*peer
, afi_t afi
, safi_t safi
,
3846 struct attr
*attr
, uint8_t *pfx
, int psize
,
3847 uint32_t addpath_id
, int withdraw
)
3849 struct prefix_rd prd
;
3850 struct prefix_evpn p
;
3851 struct bgp_route_evpn evpn
;
3854 mpls_label_t label
; /* holds the VNI as in the packet */
3857 /* Type-5 route should be 34 or 58 bytes:
3858 * RD (8), ESI (10), Eth Tag (4), IP len (1), IP (4 or 16),
3859 * GW (4 or 16) and VNI (3).
3860 * Note that the IP and GW should both be IPv4 or both IPv6.
3862 if (psize
!= 34 && psize
!= 58) {
3863 flog_err(EC_BGP_EVPN_ROUTE_INVALID
,
3864 "%u:%s - Rx EVPN Type-5 NLRI with invalid length %d",
3865 peer
->bgp
->vrf_id
, peer
->host
, psize
);
3869 /* Make prefix_rd */
3870 prd
.family
= AF_UNSPEC
;
3872 memcpy(&prd
.val
, pfx
, 8);
3875 /* Make EVPN prefix. */
3876 memset(&p
, 0, sizeof(struct prefix_evpn
));
3878 p
.prefixlen
= EVPN_ROUTE_PREFIXLEN
;
3879 p
.prefix
.route_type
= BGP_EVPN_IP_PREFIX_ROUTE
;
3881 /* Additional information outside of prefix - ESI and GW IP */
3882 memset(&evpn
, 0, sizeof(evpn
));
3885 memcpy(&evpn
.eth_s_id
.val
, pfx
, 10);
3888 /* Fetch Ethernet Tag. */
3889 memcpy(ð_tag
, pfx
, 4);
3890 p
.prefix
.prefix_addr
.eth_tag
= ntohl(eth_tag
);
3893 /* Fetch IP prefix length. */
3895 if (ippfx_len
> IPV6_MAX_BITLEN
) {
3897 EC_BGP_EVPN_ROUTE_INVALID
,
3898 "%u:%s - Rx EVPN Type-5 NLRI with invalid IP Prefix length %d",
3899 peer
->bgp
->vrf_id
, peer
->host
, ippfx_len
);
3902 p
.prefix
.prefix_addr
.ip_prefix_length
= ippfx_len
;
3904 /* Determine IPv4 or IPv6 prefix */
3905 /* Since the address and GW are from the same family, this just becomes
3906 * a simple check on the total size.
3909 SET_IPADDR_V4(&p
.prefix
.prefix_addr
.ip
);
3910 memcpy(&p
.prefix
.prefix_addr
.ip
.ipaddr_v4
, pfx
, 4);
3912 memcpy(&evpn
.gw_ip
.ipv4
, pfx
, 4);
3915 SET_IPADDR_V6(&p
.prefix
.prefix_addr
.ip
);
3916 memcpy(&p
.prefix
.prefix_addr
.ip
.ipaddr_v6
, pfx
, 16);
3918 memcpy(&evpn
.gw_ip
.ipv6
, pfx
, 16);
3922 /* Get the VNI (in MPLS label field). Stored as bytes here. */
3923 memset(&label
, 0, sizeof(label
));
3924 memcpy(&label
, pfx
, BGP_LABEL_BYTES
);
3927 * If in future, we are required to access additional fields,
3928 * we MUST increment pfx by BGP_LABEL_BYTES in before reading the next
3932 /* Process the route. */
3934 ret
= bgp_update(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
3935 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3936 &prd
, &label
, 1, 0, &evpn
);
3938 ret
= bgp_withdraw(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
3939 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3940 &prd
, &label
, 1, &evpn
);
3945 static void evpn_mpattr_encode_type5(struct stream
*s
, struct prefix
*p
,
3946 struct prefix_rd
*prd
, mpls_label_t
*label
,
3947 uint32_t num_labels
, struct attr
*attr
)
3951 struct evpn_addr
*p_evpn_p
;
3953 memset(&temp
, 0, 16);
3954 if (p
->family
!= AF_EVPN
)
3956 p_evpn_p
= &(p
->u
.prefix_evpn
);
3958 /* len denites the total len of IP and GW-IP in the route
3959 IP and GW-IP have to be both ipv4 or ipv6
3961 if (IS_IPADDR_V4(&p_evpn_p
->prefix_addr
.ip
))
3962 len
= 8; /* IP and GWIP are both ipv4 */
3964 len
= 32; /* IP and GWIP are both ipv6 */
3965 /* Prefix contains RD, ESI, EthTag, IP length, IP, GWIP and VNI */
3966 stream_putc(s
, 8 + 10 + 4 + 1 + len
+ 3);
3967 stream_put(s
, prd
->val
, 8);
3969 stream_put(s
, &(attr
->evpn_overlay
.eth_s_id
), 10);
3971 stream_put(s
, &temp
, 10);
3972 stream_putl(s
, p_evpn_p
->prefix_addr
.eth_tag
);
3973 stream_putc(s
, p_evpn_p
->prefix_addr
.ip_prefix_length
);
3974 if (IS_IPADDR_V4(&p_evpn_p
->prefix_addr
.ip
))
3975 stream_put_ipv4(s
, p_evpn_p
->prefix_addr
.ip
.ipaddr_v4
.s_addr
);
3977 stream_put(s
, &p_evpn_p
->prefix_addr
.ip
.ipaddr_v6
, 16);
3979 if (IS_IPADDR_V4(&p_evpn_p
->prefix_addr
.ip
))
3981 attr
->evpn_overlay
.gw_ip
.ipv4
.s_addr
);
3983 stream_put(s
, &(attr
->evpn_overlay
.gw_ip
.ipv6
), 16);
3985 if (IS_IPADDR_V4(&p_evpn_p
->prefix_addr
.ip
))
3986 stream_put_ipv4(s
, 0);
3988 stream_put(s
, &temp
, 16);
3992 stream_put(s
, label
, 3);
3998 * Cleanup specific VNI upon EVPN (advertise-all-vni) being disabled.
4000 static void cleanup_vni_on_disable(struct hash_backet
*backet
, struct bgp
*bgp
)
4002 struct bgpevpn
*vpn
= (struct bgpevpn
*)backet
->data
;
4004 /* Remove EVPN routes and schedule for processing. */
4005 delete_routes_for_vni(bgp
, vpn
);
4007 /* Clear "live" flag and see if hash needs to be freed. */
4008 UNSET_FLAG(vpn
->flags
, VNI_FLAG_LIVE
);
4009 if (!is_vni_configured(vpn
))
4010 bgp_evpn_free(bgp
, vpn
);
4014 * Free a VNI entry; iterator function called during cleanup.
4016 static void free_vni_entry(struct hash_backet
*backet
, struct bgp
*bgp
)
4018 struct bgpevpn
*vpn
= (struct bgpevpn
*)backet
->data
;
4020 delete_all_vni_routes(bgp
, vpn
);
4021 bgp_evpn_free(bgp
, vpn
);
4025 * Derive AUTO import RT for BGP VRF - L3VNI
4027 static void evpn_auto_rt_import_add_for_vrf(struct bgp
*bgp_vrf
)
4029 struct bgp
*bgp_def
= NULL
;
4031 form_auto_rt(bgp_vrf
, bgp_vrf
->l3vni
, bgp_vrf
->vrf_import_rtl
);
4032 UNSET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_IMPORT_RT_CFGD
);
4035 bgp_def
= bgp_get_default();
4038 bgp_evpn_map_vrf_to_its_rts(bgp_vrf
);
4042 * Delete AUTO import RT from BGP VRF - L3VNI
4044 static void evpn_auto_rt_import_delete_for_vrf(struct bgp
*bgp_vrf
)
4046 evpn_rt_delete_auto(bgp_vrf
, bgp_vrf
->l3vni
, bgp_vrf
->vrf_import_rtl
);
4050 * Derive AUTO export RT for BGP VRF - L3VNI
4052 static void evpn_auto_rt_export_add_for_vrf(struct bgp
*bgp_vrf
)
4054 UNSET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_EXPORT_RT_CFGD
);
4055 form_auto_rt(bgp_vrf
, bgp_vrf
->l3vni
, bgp_vrf
->vrf_export_rtl
);
4059 * Delete AUTO export RT from BGP VRF - L3VNI
4061 static void evpn_auto_rt_export_delete_for_vrf(struct bgp
*bgp_vrf
)
4063 evpn_rt_delete_auto(bgp_vrf
, bgp_vrf
->l3vni
, bgp_vrf
->vrf_export_rtl
);
4066 static void bgp_evpn_handle_export_rt_change_for_vrf(struct bgp
*bgp_vrf
)
4068 struct bgp
*bgp_def
= NULL
;
4069 struct listnode
*node
= NULL
;
4070 struct bgpevpn
*vpn
= NULL
;
4072 bgp_def
= bgp_get_default();
4076 /* update all type-5 routes */
4077 update_advertise_vrf_routes(bgp_vrf
);
4079 /* update all type-2 routes */
4080 for (ALL_LIST_ELEMENTS_RO(bgp_vrf
->l2vnis
, node
, vpn
))
4081 update_routes_for_vni(bgp_def
, vpn
);
4085 * Handle autort change for a given VNI.
4087 static void update_autort_vni(struct hash_backet
*backet
, struct bgp
*bgp
)
4089 struct bgpevpn
*vpn
= backet
->data
;
4091 if (!is_import_rt_configured(vpn
)) {
4092 if (is_vni_live(vpn
))
4093 bgp_evpn_uninstall_routes(bgp
, vpn
);
4094 bgp_evpn_unmap_vni_from_its_rts(bgp
, vpn
);
4095 list_delete_all_node(vpn
->import_rtl
);
4096 bgp_evpn_derive_auto_rt_import(bgp
, vpn
);
4097 if (is_vni_live(vpn
))
4098 bgp_evpn_install_routes(bgp
, vpn
);
4100 if (!is_export_rt_configured(vpn
)) {
4101 list_delete_all_node(vpn
->export_rtl
);
4102 bgp_evpn_derive_auto_rt_export(bgp
, vpn
);
4103 if (is_vni_live(vpn
))
4104 bgp_evpn_handle_export_rt_change(bgp
, vpn
);
4112 /* withdraw type-5 route corresponding to ip prefix */
4113 void bgp_evpn_withdraw_type5_route(struct bgp
*bgp_vrf
, struct prefix
*p
,
4114 afi_t afi
, safi_t safi
)
4117 struct prefix_evpn evp
;
4118 char buf
[PREFIX_STRLEN
];
4120 build_type5_prefix_from_ip_prefix(&evp
, p
);
4121 ret
= delete_evpn_type5_route(bgp_vrf
, &evp
);
4124 EC_BGP_EVPN_ROUTE_DELETE
,
4125 "%u failed to delete type-5 route for prefix %s in vrf %s",
4126 bgp_vrf
->vrf_id
, prefix2str(p
, buf
, sizeof(buf
)),
4127 vrf_id_to_name(bgp_vrf
->vrf_id
));
4131 /* withdraw all type-5 routes for an address family */
4132 void bgp_evpn_withdraw_type5_routes(struct bgp
*bgp_vrf
, afi_t afi
, safi_t safi
)
4134 struct bgp_table
*table
= NULL
;
4135 struct bgp_node
*rn
= NULL
;
4136 struct bgp_path_info
*pi
;
4138 table
= bgp_vrf
->rib
[afi
][safi
];
4139 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
4140 /* Only care about "selected" routes - non-imported. */
4141 /* TODO: Support for AddPath for EVPN. */
4142 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
4143 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)
4144 && (!pi
->extra
|| !pi
->extra
->parent
)) {
4145 bgp_evpn_withdraw_type5_route(bgp_vrf
, &rn
->p
,
4154 * Advertise IP prefix as type-5 route. The afi/safi and src_attr passed
4155 * to this function correspond to those of the source IP prefix (best
4156 * path in the case of the attr. In the case of a local prefix (when we
4157 * are advertising local subnets), the src_attr will be NULL.
4159 void bgp_evpn_advertise_type5_route(struct bgp
*bgp_vrf
, struct prefix
*p
,
4160 struct attr
*src_attr
, afi_t afi
,
4164 struct prefix_evpn evp
;
4165 char buf
[PREFIX_STRLEN
];
4167 build_type5_prefix_from_ip_prefix(&evp
, p
);
4168 ret
= update_evpn_type5_route(bgp_vrf
, &evp
, src_attr
);
4170 flog_err(EC_BGP_EVPN_ROUTE_CREATE
,
4171 "%u: Failed to create type-5 route for prefix %s",
4172 bgp_vrf
->vrf_id
, prefix2str(p
, buf
, sizeof(buf
)));
4175 /* Inject all prefixes of a particular address-family (currently, IPv4 or
4176 * IPv6 unicast) into EVPN as type-5 routes. This is invoked when the
4177 * advertisement is enabled.
4179 void bgp_evpn_advertise_type5_routes(struct bgp
*bgp_vrf
, afi_t afi
,
4182 struct bgp_table
*table
= NULL
;
4183 struct bgp_node
*rn
= NULL
;
4184 struct bgp_path_info
*pi
;
4186 table
= bgp_vrf
->rib
[afi
][safi
];
4187 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
4188 /* Need to identify the "selected" route entry to use its
4189 * attribute. Also, we only consider "non-imported" routes.
4190 * TODO: Support for AddPath for EVPN.
4192 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
4193 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)
4194 && (!pi
->extra
|| !pi
->extra
->parent
)) {
4196 /* apply the route-map */
4197 if (bgp_vrf
->adv_cmd_rmap
[afi
][safi
].map
) {
4200 ret
= route_map_apply(
4201 bgp_vrf
->adv_cmd_rmap
[afi
][safi
]
4203 &rn
->p
, RMAP_BGP
, pi
);
4204 if (ret
== RMAP_DENYMATCH
)
4207 bgp_evpn_advertise_type5_route(
4208 bgp_vrf
, &rn
->p
, pi
->attr
, afi
, safi
);
4215 void evpn_rt_delete_auto(struct bgp
*bgp
, vni_t vni
, struct list
*rtl
)
4217 struct listnode
*node
, *nnode
, *node_to_del
;
4218 struct ecommunity
*ecom
, *ecom_auto
;
4219 struct ecommunity_val eval
;
4221 if (bgp
->advertise_autort_rfc8365
)
4222 vni
|= EVPN_AUTORT_VXLAN
;
4223 encode_route_target_as((bgp
->as
& 0xFFFF), vni
, &eval
);
4225 ecom_auto
= ecommunity_new();
4226 ecommunity_add_val(ecom_auto
, &eval
);
4229 for (ALL_LIST_ELEMENTS(rtl
, node
, nnode
, ecom
)) {
4230 if (ecommunity_match(ecom
, ecom_auto
)) {
4231 ecommunity_free(&ecom
);
4237 list_delete_node(rtl
, node_to_del
);
4239 ecommunity_free(&ecom_auto
);
4242 void bgp_evpn_configure_import_rt_for_vrf(struct bgp
*bgp_vrf
,
4243 struct ecommunity
*ecomadd
)
4245 /* uninstall routes from vrf */
4246 uninstall_routes_for_vrf(bgp_vrf
);
4248 /* Cleanup the RT to VRF mapping */
4249 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf
);
4251 /* Remove auto generated RT */
4252 evpn_auto_rt_import_delete_for_vrf(bgp_vrf
);
4254 /* Add the newly configured RT to RT list */
4255 listnode_add_sort(bgp_vrf
->vrf_import_rtl
, ecomadd
);
4256 SET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_IMPORT_RT_CFGD
);
4258 /* map VRF to its RTs */
4259 bgp_evpn_map_vrf_to_its_rts(bgp_vrf
);
4261 /* install routes matching the new VRF */
4262 install_routes_for_vrf(bgp_vrf
);
4265 void bgp_evpn_unconfigure_import_rt_for_vrf(struct bgp
*bgp_vrf
,
4266 struct ecommunity
*ecomdel
)
4268 struct listnode
*node
= NULL
, *nnode
= NULL
, *node_to_del
= NULL
;
4269 struct ecommunity
*ecom
= NULL
;
4271 /* uninstall routes from vrf */
4272 uninstall_routes_for_vrf(bgp_vrf
);
4274 /* Cleanup the RT to VRF mapping */
4275 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf
);
4277 /* remove the RT from the RT list */
4278 for (ALL_LIST_ELEMENTS(bgp_vrf
->vrf_import_rtl
, node
, nnode
, ecom
)) {
4279 if (ecommunity_match(ecom
, ecomdel
)) {
4280 ecommunity_free(&ecom
);
4287 list_delete_node(bgp_vrf
->vrf_import_rtl
, node_to_del
);
4289 assert(bgp_vrf
->vrf_import_rtl
);
4290 /* fallback to auto import rt, if this was the last RT */
4291 if (bgp_vrf
->vrf_import_rtl
&& list_isempty(bgp_vrf
->vrf_import_rtl
)) {
4292 UNSET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_IMPORT_RT_CFGD
);
4293 evpn_auto_rt_import_add_for_vrf(bgp_vrf
);
4296 /* map VRFs to its RTs */
4297 bgp_evpn_map_vrf_to_its_rts(bgp_vrf
);
4299 /* install routes matching this new RT */
4300 install_routes_for_vrf(bgp_vrf
);
4303 void bgp_evpn_configure_export_rt_for_vrf(struct bgp
*bgp_vrf
,
4304 struct ecommunity
*ecomadd
)
4306 /* remove auto-generated RT */
4307 evpn_auto_rt_export_delete_for_vrf(bgp_vrf
);
4309 /* Add the new RT to the RT list */
4310 listnode_add_sort(bgp_vrf
->vrf_export_rtl
, ecomadd
);
4311 SET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_EXPORT_RT_CFGD
);
4313 bgp_evpn_handle_export_rt_change_for_vrf(bgp_vrf
);
4316 void bgp_evpn_unconfigure_export_rt_for_vrf(struct bgp
*bgp_vrf
,
4317 struct ecommunity
*ecomdel
)
4319 struct listnode
*node
= NULL
, *nnode
= NULL
, *node_to_del
= NULL
;
4320 struct ecommunity
*ecom
= NULL
;
4322 /* Remove the RT from the RT list */
4323 for (ALL_LIST_ELEMENTS(bgp_vrf
->vrf_export_rtl
, node
, nnode
, ecom
)) {
4324 if (ecommunity_match(ecom
, ecomdel
)) {
4325 ecommunity_free(&ecom
);
4332 list_delete_node(bgp_vrf
->vrf_export_rtl
, node_to_del
);
4335 * Temporary assert to make SA happy.
4336 * The ALL_LIST_ELEMENTS macro above has a NULL check
4337 * which means that SA is going to complain about
4338 * the list_isempty call, which doesn't NULL check.
4339 * So until we get this situation cleaned up, here
4342 assert(bgp_vrf
->vrf_export_rtl
);
4344 /* fall back to auto-generated RT if this was the last RT */
4345 if (list_isempty(bgp_vrf
->vrf_export_rtl
)) {
4346 UNSET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_EXPORT_RT_CFGD
);
4347 evpn_auto_rt_export_add_for_vrf(bgp_vrf
);
4350 bgp_evpn_handle_export_rt_change_for_vrf(bgp_vrf
);
4354 * Handle change to BGP router id. This is invoked twice by the change
4355 * handler, first before the router id has been changed and then after
4356 * the router id has been changed. The first invocation will result in
4357 * local routes for all VNIs/VRF being deleted and withdrawn and the next
4358 * will result in the routes being re-advertised.
4360 void bgp_evpn_handle_router_id_update(struct bgp
*bgp
, int withdraw
)
4364 /* delete and withdraw all the type-5 routes
4365 stored in the global table for this vrf
4367 withdraw_router_id_vrf(bgp
);
4369 /* delete all the VNI routes (type-2/type-3) routes for all the
4372 hash_iterate(bgp
->vnihash
,
4373 (void (*)(struct hash_backet
*,
4374 void *))withdraw_router_id_vni
,
4378 /* advertise all routes in the vrf as type-5 routes with the new
4381 update_router_id_vrf(bgp
);
4383 /* advertise all the VNI routes (type-2/type-3) routes with the
4386 hash_iterate(bgp
->vnihash
,
4387 (void (*)(struct hash_backet
*,
4388 void *))update_router_id_vni
,
4394 * Handle change to auto-RT algorithm - update and advertise local routes.
4396 void bgp_evpn_handle_autort_change(struct bgp
*bgp
)
4398 hash_iterate(bgp
->vnihash
,
4399 (void (*)(struct hash_backet
*,
4400 void*))update_autort_vni
,
4405 * Handle change to export RT - update and advertise local routes.
4407 int bgp_evpn_handle_export_rt_change(struct bgp
*bgp
, struct bgpevpn
*vpn
)
4409 return update_routes_for_vni(bgp
, vpn
);
4412 void bgp_evpn_handle_vrf_rd_change(struct bgp
*bgp_vrf
, int withdraw
)
4415 delete_withdraw_vrf_routes(bgp_vrf
);
4417 update_advertise_vrf_routes(bgp_vrf
);
4421 * Handle change to RD. This is invoked twice by the change handler,
4422 * first before the RD has been changed and then after the RD has
4423 * been changed. The first invocation will result in local routes
4424 * of this VNI being deleted and withdrawn and the next will result
4425 * in the routes being re-advertised.
4427 void bgp_evpn_handle_rd_change(struct bgp
*bgp
, struct bgpevpn
*vpn
,
4431 delete_withdraw_vni_routes(bgp
, vpn
);
4433 update_advertise_vni_routes(bgp
, vpn
);
4437 * Install routes for this VNI. Invoked upon change to Import RT.
4439 int bgp_evpn_install_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
4441 return install_routes_for_vni(bgp
, vpn
);
4445 * Uninstall all routes installed for this VNI. Invoked upon change
4448 int bgp_evpn_uninstall_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
4450 return uninstall_routes_for_vni(bgp
, vpn
);
4454 * TODO: Hardcoded for a maximum of 2 VNIs right now
4456 char *bgp_evpn_label2str(mpls_label_t
*label
, uint32_t num_labels
, char *buf
,
4461 vni1
= label2vni(label
);
4462 if (num_labels
== 2) {
4463 vni2
= label2vni(label
+ 1);
4464 snprintf(buf
, len
, "%u/%u", vni1
, vni2
);
4466 snprintf(buf
, len
, "%u", vni1
);
4471 * Function to convert evpn route to json format.
4472 * NOTE: We don't use prefix2str as the output here is a bit different.
4474 void bgp_evpn_route2json(struct prefix_evpn
*p
, json_object
*json
)
4476 char buf1
[ETHER_ADDR_STRLEN
];
4477 char buf2
[PREFIX2STR_BUFFER
];
4482 if (p
->prefix
.route_type
== BGP_EVPN_IMET_ROUTE
) {
4483 json_object_int_add(json
, "routeType", p
->prefix
.route_type
);
4484 json_object_int_add(json
, "ethTag",
4485 p
->prefix
.imet_addr
.eth_tag
);
4486 json_object_int_add(json
, "ipLen",
4487 is_evpn_prefix_ipaddr_v4(p
)
4490 json_object_string_add(json
, "ip",
4491 inet_ntoa(p
->prefix
.imet_addr
.ip
.ipaddr_v4
));
4492 } else if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
) {
4493 if (is_evpn_prefix_ipaddr_none(p
)) {
4494 json_object_int_add(json
, "routeType",
4495 p
->prefix
.route_type
);
4496 json_object_int_add(json
, "ethTag",
4497 p
->prefix
.macip_addr
.eth_tag
);
4498 json_object_int_add(json
, "macLen", 8 * ETH_ALEN
);
4499 json_object_string_add(json
, "mac",
4500 prefix_mac2str(&p
->prefix
.macip_addr
.mac
,
4506 family
= is_evpn_prefix_ipaddr_v4(p
) ? AF_INET
4509 json_object_int_add(json
, "routeType",
4510 p
->prefix
.route_type
);
4511 json_object_int_add(json
, "ethTag",
4512 p
->prefix
.macip_addr
.eth_tag
);
4513 json_object_int_add(json
, "macLen", 8 * ETH_ALEN
);
4514 json_object_string_add(json
, "mac",
4515 prefix_mac2str(&p
->prefix
.macip_addr
.mac
,
4518 json_object_int_add(json
, "ipLen",
4519 is_evpn_prefix_ipaddr_v4(p
)
4522 json_object_string_add(
4525 &p
->prefix
.macip_addr
.ip
.ip
.addr
,
4527 PREFIX2STR_BUFFER
));
4530 /* Currently, this is to cater to other AF_ETHERNET code. */
4535 * Function to convert evpn route to string.
4536 * NOTE: We don't use prefix2str as the output here is a bit different.
4538 char *bgp_evpn_route2str(struct prefix_evpn
*p
, char *buf
, int len
)
4540 char buf1
[ETHER_ADDR_STRLEN
];
4541 char buf2
[PREFIX2STR_BUFFER
];
4542 char buf3
[ESI_STR_LEN
];
4544 if (p
->prefix
.route_type
== BGP_EVPN_IMET_ROUTE
) {
4545 snprintf(buf
, len
, "[%d]:[%d]:[%d]:[%s]", p
->prefix
.route_type
,
4546 p
->prefix
.imet_addr
.eth_tag
,
4547 is_evpn_prefix_ipaddr_v4(p
) ? IPV4_MAX_BITLEN
4549 inet_ntoa(p
->prefix
.imet_addr
.ip
.ipaddr_v4
));
4550 } else if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
) {
4551 if (is_evpn_prefix_ipaddr_none(p
))
4552 snprintf(buf
, len
, "[%d]:[%d]:[%d]:[%s]",
4553 p
->prefix
.route_type
,
4554 p
->prefix
.macip_addr
.eth_tag
,
4556 prefix_mac2str(&p
->prefix
.macip_addr
.mac
, buf1
,
4561 family
= is_evpn_prefix_ipaddr_v4(p
) ? AF_INET
4563 snprintf(buf
, len
, "[%d]:[%d]:[%d]:[%s]:[%d]:[%s]",
4564 p
->prefix
.route_type
,
4565 p
->prefix
.macip_addr
.eth_tag
,
4567 prefix_mac2str(&p
->prefix
.macip_addr
.mac
, buf1
,
4569 family
== AF_INET
? IPV4_MAX_BITLEN
4572 &p
->prefix
.macip_addr
.ip
.ip
.addr
,
4574 PREFIX2STR_BUFFER
));
4576 } else if (p
->prefix
.route_type
== BGP_EVPN_IP_PREFIX_ROUTE
) {
4577 snprintf(buf
, len
, "[%d]:[%d]:[%d]:[%s]",
4578 p
->prefix
.route_type
,
4579 p
->prefix
.prefix_addr
.eth_tag
,
4580 p
->prefix
.prefix_addr
.ip_prefix_length
,
4581 is_evpn_prefix_ipaddr_v4(p
)
4582 ? inet_ntoa(p
->prefix
.prefix_addr
.ip
.ipaddr_v4
)
4583 : inet6_ntoa(p
->prefix
.prefix_addr
.ip
.ipaddr_v6
));
4584 } else if (p
->prefix
.route_type
== BGP_EVPN_ES_ROUTE
) {
4585 snprintf(buf
, len
, "[%d]:[%s]:[%d]:[%s]",
4586 p
->prefix
.route_type
,
4587 esi_to_str(&p
->prefix
.es_addr
.esi
, buf3
, sizeof(buf3
)),
4588 is_evpn_prefix_ipaddr_v4(p
) ? IPV4_MAX_BITLEN
4590 inet_ntoa(p
->prefix
.es_addr
.ip
.ipaddr_v4
));
4592 /* For EVPN route types not supported yet. */
4593 snprintf(buf
, len
, "(unsupported route type %d)",
4594 p
->prefix
.route_type
);
4601 * Encode EVPN prefix in Update (MP_REACH)
4603 void bgp_evpn_encode_prefix(struct stream
*s
, struct prefix
*p
,
4604 struct prefix_rd
*prd
, mpls_label_t
*label
,
4605 uint32_t num_labels
, struct attr
*attr
,
4606 int addpath_encode
, uint32_t addpath_tx_id
)
4608 struct prefix_evpn
*evp
= (struct prefix_evpn
*)p
;
4609 int len
, ipa_len
= 0;
4612 stream_putl(s
, addpath_tx_id
);
4615 stream_putc(s
, evp
->prefix
.route_type
);
4617 switch (evp
->prefix
.route_type
) {
4618 case BGP_EVPN_MAC_IP_ROUTE
:
4619 if (is_evpn_prefix_ipaddr_v4(evp
))
4620 ipa_len
= IPV4_MAX_BYTELEN
;
4621 else if (is_evpn_prefix_ipaddr_v6(evp
))
4622 ipa_len
= IPV6_MAX_BYTELEN
;
4623 /* RD, ESI, EthTag, MAC+len, IP len, [IP], 1 VNI */
4624 len
= 8 + 10 + 4 + 1 + 6 + 1 + ipa_len
+ 3;
4625 if (ipa_len
&& num_labels
> 1) /* There are 2 VNIs */
4627 stream_putc(s
, len
);
4628 stream_put(s
, prd
->val
, 8); /* RD */
4630 stream_put(s
, &attr
->evpn_overlay
.eth_s_id
, ESI_LEN
);
4632 stream_put(s
, 0, 10);
4633 stream_putl(s
, evp
->prefix
.macip_addr
.eth_tag
); /* Ethernet Tag ID */
4634 stream_putc(s
, 8 * ETH_ALEN
); /* Mac Addr Len - bits */
4635 stream_put(s
, evp
->prefix
.macip_addr
.mac
.octet
, 6); /* Mac Addr */
4636 stream_putc(s
, 8 * ipa_len
); /* IP address Length */
4637 if (ipa_len
) /* IP */
4638 stream_put(s
, &evp
->prefix
.macip_addr
.ip
.ip
.addr
,
4640 /* 1st label is the L2 VNI */
4641 stream_put(s
, label
, BGP_LABEL_BYTES
);
4642 /* Include 2nd label (L3 VNI) if advertising MAC+IP */
4643 if (ipa_len
&& num_labels
> 1)
4644 stream_put(s
, label
+ 1, BGP_LABEL_BYTES
);
4647 case BGP_EVPN_IMET_ROUTE
:
4648 stream_putc(s
, 17); // TODO: length - assumes IPv4 address
4649 stream_put(s
, prd
->val
, 8); /* RD */
4650 stream_putl(s
, evp
->prefix
.imet_addr
.eth_tag
); /* Ethernet Tag ID */
4651 stream_putc(s
, IPV4_MAX_BITLEN
); /* IP address Length - bits */
4652 /* Originating Router's IP Addr */
4653 stream_put_in_addr(s
, &evp
->prefix
.imet_addr
.ip
.ipaddr_v4
);
4656 case BGP_EVPN_ES_ROUTE
:
4657 stream_putc(s
, 23); /* TODO: length: assumes ipv4 VTEP */
4658 stream_put(s
, prd
->val
, 8); /* RD */
4659 stream_put(s
, evp
->prefix
.es_addr
.esi
.val
, 10); /* ESI */
4660 stream_putc(s
, IPV4_MAX_BITLEN
); /* IP address Length - bits */
4662 stream_put_in_addr(s
, &evp
->prefix
.es_addr
.ip
.ipaddr_v4
);
4665 case BGP_EVPN_IP_PREFIX_ROUTE
:
4666 /* TODO: AddPath support. */
4667 evpn_mpattr_encode_type5(s
, p
, prd
, label
, num_labels
, attr
);
4675 int bgp_nlri_parse_evpn(struct peer
*peer
, struct attr
*attr
,
4676 struct bgp_nlri
*packet
, int withdraw
)
4682 uint32_t addpath_id
;
4683 int addpath_encoded
;
4688 /* Start processing the NLRI - there may be multiple in the MP_REACH */
4690 lim
= pnt
+ packet
->length
;
4692 safi
= packet
->safi
;
4696 (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
4697 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
4698 PEER_CAP_ADDPATH_AF_TX_RCV
));
4700 for (; pnt
< lim
; pnt
+= psize
) {
4701 /* Clear prefix structure. */
4702 memset(&p
, 0, sizeof(struct prefix
));
4704 /* Deal with path-id if AddPath is supported. */
4705 if (addpath_encoded
) {
4706 /* When packet overflow occurs return immediately. */
4707 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
4710 addpath_id
= ntohl(*((uint32_t *)pnt
));
4711 pnt
+= BGP_ADDPATH_ID_LEN
;
4714 /* All EVPN NLRI types start with type and length. */
4721 /* When packet overflow occur return immediately. */
4722 if (pnt
+ psize
> lim
)
4726 case BGP_EVPN_MAC_IP_ROUTE
:
4727 if (process_type2_route(peer
, afi
, safi
,
4728 withdraw
? NULL
: attr
, pnt
,
4729 psize
, addpath_id
)) {
4732 "%u:%s - Error in processing EVPN type-2 NLRI size %d",
4733 peer
->bgp
->vrf_id
, peer
->host
, psize
);
4738 case BGP_EVPN_IMET_ROUTE
:
4739 if (process_type3_route(peer
, afi
, safi
,
4740 withdraw
? NULL
: attr
, pnt
,
4741 psize
, addpath_id
)) {
4744 "%u:%s - Error in processing EVPN type-3 NLRI size %d",
4745 peer
->bgp
->vrf_id
, peer
->host
, psize
);
4750 case BGP_EVPN_ES_ROUTE
:
4751 if (process_type4_route(peer
, afi
, safi
,
4752 withdraw
? NULL
: attr
, pnt
,
4753 psize
, addpath_id
)) {
4756 "%u:%s - Error in processing EVPN type-4 NLRI size %d",
4757 peer
->bgp
->vrf_id
, peer
->host
, psize
);
4762 case BGP_EVPN_IP_PREFIX_ROUTE
:
4763 if (process_type5_route(peer
, afi
, safi
, attr
, pnt
,
4764 psize
, addpath_id
, withdraw
)) {
4767 "%u:%s - Error in processing EVPN type-5 NLRI size %d",
4768 peer
->bgp
->vrf_id
, peer
->host
, psize
);
4778 /* Packet length consistency check. */
4786 * Map the RTs (configured or automatically derived) of a VRF to the VRF.
4787 * The mapping will be used during route processing.
4788 * bgp_def: default bgp instance
4789 * bgp_vrf: specific bgp vrf instance on which RT is configured
4791 void bgp_evpn_map_vrf_to_its_rts(struct bgp
*bgp_vrf
)
4794 struct ecommunity_val
*eval
= NULL
;
4795 struct listnode
*node
= NULL
, *nnode
= NULL
;
4796 struct ecommunity
*ecom
= NULL
;
4798 for (ALL_LIST_ELEMENTS(bgp_vrf
->vrf_import_rtl
, node
, nnode
, ecom
)) {
4799 for (i
= 0; i
< ecom
->size
; i
++) {
4800 eval
= (struct ecommunity_val
*)(ecom
->val
4802 * ECOMMUNITY_SIZE
));
4803 map_vrf_to_rt(bgp_vrf
, eval
);
4809 * Unmap the RTs (configured or automatically derived) of a VRF from the VRF.
4811 void bgp_evpn_unmap_vrf_from_its_rts(struct bgp
*bgp_vrf
)
4814 struct ecommunity_val
*eval
;
4815 struct listnode
*node
, *nnode
;
4816 struct ecommunity
*ecom
;
4818 for (ALL_LIST_ELEMENTS(bgp_vrf
->vrf_import_rtl
, node
, nnode
, ecom
)) {
4819 for (i
= 0; i
< ecom
->size
; i
++) {
4820 struct vrf_irt_node
*irt
;
4821 struct ecommunity_val eval_tmp
;
4823 eval
= (struct ecommunity_val
*)(ecom
->val
4825 * ECOMMUNITY_SIZE
));
4826 /* If using "automatic" RT, we only care about the
4827 * local-admin sub-field.
4828 * This is to facilitate using VNI as the RT for EBGP
4831 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
4832 if (!CHECK_FLAG(bgp_vrf
->vrf_flags
,
4833 BGP_VRF_IMPORT_RT_CFGD
))
4834 mask_ecom_global_admin(&eval_tmp
, eval
);
4836 irt
= lookup_vrf_import_rt(&eval_tmp
);
4838 unmap_vrf_from_rt(bgp_vrf
, irt
);
4845 * Map the RTs (configured or automatically derived) of a VNI to the VNI.
4846 * The mapping will be used during route processing.
4848 void bgp_evpn_map_vni_to_its_rts(struct bgp
*bgp
, struct bgpevpn
*vpn
)
4851 struct ecommunity_val
*eval
;
4852 struct listnode
*node
, *nnode
;
4853 struct ecommunity
*ecom
;
4855 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
)) {
4856 for (i
= 0; i
< ecom
->size
; i
++) {
4857 eval
= (struct ecommunity_val
*)(ecom
->val
4859 * ECOMMUNITY_SIZE
));
4860 map_vni_to_rt(bgp
, vpn
, eval
);
4866 * Unmap the RTs (configured or automatically derived) of a VNI from the VNI.
4868 void bgp_evpn_unmap_vni_from_its_rts(struct bgp
*bgp
, struct bgpevpn
*vpn
)
4871 struct ecommunity_val
*eval
;
4872 struct listnode
*node
, *nnode
;
4873 struct ecommunity
*ecom
;
4875 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
)) {
4876 for (i
= 0; i
< ecom
->size
; i
++) {
4877 struct irt_node
*irt
;
4878 struct ecommunity_val eval_tmp
;
4880 eval
= (struct ecommunity_val
*)(ecom
->val
4882 * ECOMMUNITY_SIZE
));
4883 /* If using "automatic" RT, we only care about the
4884 * local-admin sub-field.
4885 * This is to facilitate using VNI as the RT for EBGP
4888 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
4889 if (!is_import_rt_configured(vpn
))
4890 mask_ecom_global_admin(&eval_tmp
, eval
);
4892 irt
= lookup_import_rt(bgp
, &eval_tmp
);
4894 unmap_vni_from_rt(bgp
, vpn
, irt
);
4900 * Derive Import RT automatically for VNI and map VNI to RT.
4901 * The mapping will be used during route processing.
4903 void bgp_evpn_derive_auto_rt_import(struct bgp
*bgp
, struct bgpevpn
*vpn
)
4905 form_auto_rt(bgp
, vpn
->vni
, vpn
->import_rtl
);
4906 UNSET_FLAG(vpn
->flags
, VNI_FLAG_IMPRT_CFGD
);
4909 bgp_evpn_map_vni_to_its_rts(bgp
, vpn
);
4913 * Derive Export RT automatically for VNI.
4915 void bgp_evpn_derive_auto_rt_export(struct bgp
*bgp
, struct bgpevpn
*vpn
)
4917 form_auto_rt(bgp
, vpn
->vni
, vpn
->export_rtl
);
4918 UNSET_FLAG(vpn
->flags
, VNI_FLAG_EXPRT_CFGD
);
4922 * Derive RD automatically for VNI using passed information - it
4923 * is of the form RouterId:unique-id-for-vni.
4925 void bgp_evpn_derive_auto_rd_for_vrf(struct bgp
*bgp
)
4927 form_auto_rd(bgp
->router_id
, bgp
->vrf_rd_id
, &bgp
->vrf_prd
);
4931 * Derive RD automatically for VNI using passed information - it
4932 * is of the form RouterId:unique-id-for-vni.
4934 void bgp_evpn_derive_auto_rd(struct bgp
*bgp
, struct bgpevpn
*vpn
)
4938 vpn
->prd
.family
= AF_UNSPEC
;
4939 vpn
->prd
.prefixlen
= 64;
4940 sprintf(buf
, "%s:%hu", inet_ntoa(bgp
->router_id
), vpn
->rd_id
);
4941 (void)str2prefix_rd(buf
, &vpn
->prd
);
4942 UNSET_FLAG(vpn
->flags
, VNI_FLAG_RD_CFGD
);
4948 bool bgp_evpn_lookup_l3vni_l2vni_table(vni_t vni
)
4950 struct list
*inst
= bm
->bgp
;
4951 struct listnode
*node
;
4952 struct bgp
*bgp_vrf
;
4954 for (ALL_LIST_ELEMENTS_RO(inst
, node
, bgp_vrf
)) {
4955 if (bgp_vrf
->l3vni
== vni
)
4965 struct bgpevpn
*bgp_evpn_lookup_vni(struct bgp
*bgp
, vni_t vni
)
4967 struct bgpevpn
*vpn
;
4970 memset(&tmp
, 0, sizeof(struct bgpevpn
));
4972 vpn
= hash_lookup(bgp
->vnihash
, &tmp
);
4977 * Create a new vpn - invoked upon configuration or zebra notification.
4979 struct bgpevpn
*bgp_evpn_new(struct bgp
*bgp
, vni_t vni
,
4980 struct in_addr originator_ip
,
4981 vrf_id_t tenant_vrf_id
)
4983 struct bgpevpn
*vpn
;
4988 vpn
= XCALLOC(MTYPE_BGP_EVPN
, sizeof(struct bgpevpn
));
4992 /* Set values - RD and RT set to defaults. */
4994 vpn
->originator_ip
= originator_ip
;
4995 vpn
->tenant_vrf_id
= tenant_vrf_id
;
4997 /* Initialize route-target import and export lists */
4998 vpn
->import_rtl
= list_new();
4999 vpn
->import_rtl
->cmp
= (int (*)(void *, void *))evpn_route_target_cmp
;
5000 vpn
->import_rtl
->del
= evpn_xxport_delete_ecomm
;
5001 vpn
->export_rtl
= list_new();
5002 vpn
->export_rtl
->cmp
= (int (*)(void *, void *))evpn_route_target_cmp
;
5003 vpn
->export_rtl
->del
= evpn_xxport_delete_ecomm
;
5004 bf_assign_index(bm
->rd_idspace
, vpn
->rd_id
);
5005 derive_rd_rt_for_vni(bgp
, vpn
);
5007 /* Initialize EVPN route table. */
5008 vpn
->route_table
= bgp_table_init(bgp
, AFI_L2VPN
, SAFI_EVPN
);
5011 if (!hash_get(bgp
->vnihash
, vpn
, hash_alloc_intern
)) {
5012 XFREE(MTYPE_BGP_EVPN
, vpn
);
5016 /* add to l2vni list on corresponding vrf */
5017 bgpevpn_link_to_l3vni(vpn
);
5019 QOBJ_REG(vpn
, bgpevpn
);
5024 * Free a given VPN - called in multiple scenarios such as zebra
5025 * notification, configuration being deleted, advertise-all-vni disabled etc.
5026 * This just frees appropriate memory, caller should have taken other
5029 void bgp_evpn_free(struct bgp
*bgp
, struct bgpevpn
*vpn
)
5031 bgpevpn_unlink_from_l3vni(vpn
);
5032 bgp_table_unlock(vpn
->route_table
);
5033 bgp_evpn_unmap_vni_from_its_rts(bgp
, vpn
);
5034 list_delete(&vpn
->import_rtl
);
5035 list_delete(&vpn
->export_rtl
);
5036 bf_release_index(bm
->rd_idspace
, vpn
->rd_id
);
5037 hash_release(bgp
->vnihash
, vpn
);
5039 XFREE(MTYPE_BGP_EVPN
, vpn
);
5045 struct evpnes
*bgp_evpn_lookup_es(struct bgp
*bgp
, esi_t
*esi
)
5050 memset(&tmp
, 0, sizeof(struct evpnes
));
5051 memcpy(&tmp
.esi
, esi
, sizeof(esi_t
));
5052 es
= hash_lookup(bgp
->esihash
, &tmp
);
5057 * Create a new local es - invoked upon zebra notification.
5059 struct evpnes
*bgp_evpn_es_new(struct bgp
*bgp
,
5061 struct ipaddr
*originator_ip
)
5069 es
= XCALLOC(MTYPE_BGP_EVPN_ES
, sizeof(struct evpnes
));
5073 /* set the ESI and originator_ip */
5074 memcpy(&es
->esi
, esi
, sizeof(esi_t
));
5075 memcpy(&es
->originator_ip
, originator_ip
, sizeof(struct ipaddr
));
5077 /* Initialise the VTEP list */
5078 es
->vtep_list
= list_new();
5079 es
->vtep_list
->cmp
= evpn_vtep_ip_cmp
;
5081 /* auto derive RD for this es */
5082 bf_assign_index(bm
->rd_idspace
, es
->rd_id
);
5083 es
->prd
.family
= AF_UNSPEC
;
5084 es
->prd
.prefixlen
= 64;
5085 sprintf(buf
, "%s:%hu", inet_ntoa(bgp
->router_id
), es
->rd_id
);
5086 (void)str2prefix_rd(buf
, &es
->prd
);
5088 /* Initialize the ES route table */
5089 es
->route_table
= bgp_table_init(bgp
, AFI_L2VPN
, SAFI_EVPN
);
5092 if (!hash_get(bgp
->esihash
, es
, hash_alloc_intern
)) {
5093 XFREE(MTYPE_BGP_EVPN_ES
, es
);
5097 QOBJ_REG(es
, evpnes
);
5103 * This just frees appropriate memory, caller should have taken other
5106 void bgp_evpn_es_free(struct bgp
*bgp
, struct evpnes
*es
)
5108 list_delete(&es
->vtep_list
);
5109 bgp_table_unlock(es
->route_table
);
5110 bf_release_index(bm
->rd_idspace
, es
->rd_id
);
5111 hash_release(bgp
->esihash
, es
);
5113 XFREE(MTYPE_BGP_EVPN_ES
, es
);
5117 * Import evpn route from global table to VNI/VRF/ESI.
5119 int bgp_evpn_import_route(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
5120 struct prefix
*p
, struct bgp_path_info
*pi
)
5122 return install_uninstall_evpn_route(bgp
, afi
, safi
, p
, pi
, 1);
5126 * Unimport evpn route from VNI/VRF/ESI.
5128 int bgp_evpn_unimport_route(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
5129 struct prefix
*p
, struct bgp_path_info
*pi
)
5131 return install_uninstall_evpn_route(bgp
, afi
, safi
, p
, pi
, 0);
5134 /* filter routes which have martian next hops */
5135 int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp
*bgp
)
5139 struct bgp_node
*rd_rn
, *rn
;
5140 struct bgp_table
*table
;
5141 struct bgp_path_info
*pi
;
5146 /* Walk entire global routing table and evaluate routes which could be
5147 * imported into this VPN. Note that we cannot just look at the routes
5148 * for the VNI's RD -
5149 * remote routes applicable for this VNI could have any RD.
5151 /* EVPN routes are a 2-level table. */
5152 for (rd_rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rd_rn
;
5153 rd_rn
= bgp_route_next(rd_rn
)) {
5154 table
= (struct bgp_table
*)(rd_rn
->info
);
5158 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
5160 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
5162 /* Consider "valid" remote routes applicable for
5164 if (!(pi
->type
== ZEBRA_ROUTE_BGP
5165 && pi
->sub_type
== BGP_ROUTE_NORMAL
))
5168 if (bgp_nexthop_self(bgp
, pi
->attr
->nexthop
)) {
5170 char attr_str
[BUFSIZ
];
5171 char pbuf
[PREFIX_STRLEN
];
5173 bgp_dump_attr(pi
->attr
, attr_str
,
5176 if (bgp_debug_update(pi
->peer
, &rn
->p
,
5179 "%u: prefix %s with attr %s - DENIED due to martian or self nexthop",
5186 bgp_evpn_unimport_route(bgp
, afi
, safi
,
5189 bgp_rib_remove(rn
, pi
, pi
->peer
, afi
,
5200 * Handle del of a local MACIP.
5202 int bgp_evpn_local_macip_del(struct bgp
*bgp
, vni_t vni
, struct ethaddr
*mac
,
5205 struct bgpevpn
*vpn
;
5206 struct prefix_evpn p
;
5208 /* Lookup VNI hash - should exist. */
5209 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
5210 if (!vpn
|| !is_vni_live(vpn
)) {
5211 flog_warn(EC_BGP_EVPN_VPN_VNI
,
5212 "%u: VNI hash entry for VNI %u %s at MACIP DEL",
5213 bgp
->vrf_id
, vni
, vpn
? "not live" : "not found");
5217 /* Remove EVPN type-2 route and schedule for processing. */
5218 build_evpn_type2_prefix(&p
, mac
, ip
);
5219 delete_evpn_route(bgp
, vpn
, &p
);
5225 * Handle add of a local MACIP.
5227 int bgp_evpn_local_macip_add(struct bgp
*bgp
, vni_t vni
, struct ethaddr
*mac
,
5228 struct ipaddr
*ip
, uint8_t flags
, uint32_t seq
)
5230 struct bgpevpn
*vpn
;
5231 struct prefix_evpn p
;
5233 /* Lookup VNI hash - should exist. */
5234 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
5235 if (!vpn
|| !is_vni_live(vpn
)) {
5236 flog_warn(EC_BGP_EVPN_VPN_VNI
,
5237 "%u: VNI hash entry for VNI %u %s at MACIP ADD",
5238 bgp
->vrf_id
, vni
, vpn
? "not live" : "not found");
5242 /* Create EVPN type-2 route and schedule for processing. */
5243 build_evpn_type2_prefix(&p
, mac
, ip
);
5244 if (update_evpn_route(bgp
, vpn
, &p
, flags
, seq
)) {
5245 char buf
[ETHER_ADDR_STRLEN
];
5246 char buf2
[INET6_ADDRSTRLEN
];
5249 EC_BGP_EVPN_ROUTE_CREATE
,
5250 "%u:Failed to create Type-2 route, VNI %u %s MAC %s IP %s (flags: 0x%x)",
5251 bgp
->vrf_id
, vpn
->vni
,
5252 CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
)
5255 prefix_mac2str(mac
, buf
, sizeof(buf
)),
5256 ipaddr2str(ip
, buf2
, sizeof(buf2
)), flags
);
5263 static void link_l2vni_hash_to_l3vni(struct hash_backet
*backet
,
5264 struct bgp
*bgp_vrf
)
5266 struct bgpevpn
*vpn
= (struct bgpevpn
*)backet
->data
;
5267 struct bgp
*bgp_def
= NULL
;
5269 bgp_def
= bgp_get_default();
5272 if (vpn
->tenant_vrf_id
== bgp_vrf
->vrf_id
)
5273 bgpevpn_link_to_l3vni(vpn
);
5276 int bgp_evpn_local_l3vni_add(vni_t l3vni
, vrf_id_t vrf_id
, struct ethaddr
*rmac
,
5277 struct in_addr originator_ip
, int filter
)
5279 struct bgp
*bgp_vrf
= NULL
; /* bgp VRF instance */
5280 struct bgp
*bgp_def
= NULL
; /* default bgp instance */
5281 struct listnode
*node
= NULL
;
5282 struct bgpevpn
*vpn
= NULL
;
5285 /* get the default instance - required to get the AS number for VRF
5288 bgp_def
= bgp_get_default();
5292 "Cannot process L3VNI %u ADD - default BGP instance not yet created",
5298 /* if the BGP vrf instance doesn't exist - create one */
5299 bgp_vrf
= bgp_lookup_by_name(vrf_id_to_name(vrf_id
));
5304 ret
= bgp_get(&bgp_vrf
, &as
, vrf_id_to_name(vrf_id
),
5305 BGP_INSTANCE_TYPE_VRF
);
5307 case BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
:
5308 flog_err(EC_BGP_MULTI_INSTANCE
,
5309 "'bgp multiple-instance' not present\n");
5311 case BGP_ERR_AS_MISMATCH
:
5312 flog_err(EC_BGP_EVPN_AS_MISMATCH
,
5313 "BGP is already running; AS is %u\n", as
);
5315 case BGP_ERR_INSTANCE_MISMATCH
:
5316 flog_err(EC_BGP_EVPN_INSTANCE_MISMATCH
,
5317 "BGP instance name and AS number mismatch\n");
5321 /* mark as auto created */
5322 SET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_AUTO
);
5325 /* associate with l3vni */
5326 bgp_vrf
->l3vni
= l3vni
;
5328 /* set the router mac - to be used in mac-ip routes for this vrf */
5329 memcpy(&bgp_vrf
->rmac
, rmac
, sizeof(struct ethaddr
));
5331 /* set the originator ip */
5332 bgp_vrf
->originator_ip
= originator_ip
;
5334 /* set the right filter - are we using l3vni only for prefix routes? */
5336 SET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY
);
5338 /* auto derive RD/RT */
5339 if (!CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_IMPORT_RT_CFGD
))
5340 evpn_auto_rt_import_add_for_vrf(bgp_vrf
);
5341 if (!CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_EXPORT_RT_CFGD
))
5342 evpn_auto_rt_export_add_for_vrf(bgp_vrf
);
5343 bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf
);
5345 /* link all corresponding l2vnis */
5346 hash_iterate(bgp_def
->vnihash
,
5347 (void (*)(struct hash_backet
*,
5348 void *))link_l2vni_hash_to_l3vni
,
5351 /* Only update all corresponding type-2 routes if we are advertising two
5352 * labels along with type-2 routes
5355 for (ALL_LIST_ELEMENTS_RO(bgp_vrf
->l2vnis
, node
, vpn
))
5356 update_routes_for_vni(bgp_def
, vpn
);
5358 /* advertise type-5 routes if needed */
5359 update_advertise_vrf_routes(bgp_vrf
);
5361 /* install all remote routes belonging to this l3vni into correspondng
5363 install_routes_for_vrf(bgp_vrf
);
5368 int bgp_evpn_local_l3vni_del(vni_t l3vni
, vrf_id_t vrf_id
)
5370 struct bgp
*bgp_vrf
= NULL
; /* bgp vrf instance */
5371 struct bgp
*bgp_def
= NULL
; /* default bgp instance */
5372 struct listnode
*node
= NULL
;
5373 struct listnode
*next
= NULL
;
5374 struct bgpevpn
*vpn
= NULL
;
5376 bgp_vrf
= bgp_lookup_by_vrf_id(vrf_id
);
5380 "Cannot process L3VNI %u Del - Could not find BGP instance",
5385 bgp_def
= bgp_get_default();
5389 "Cannot process L3VNI %u Del - Could not find default BGP instance",
5394 /* Remove remote routes from BGT VRF even if BGP_VRF_AUTO is configured,
5395 * bgp_delete would not remove/decrement bgp_path_info of the ip_prefix
5396 * routes. This will uninstalling the routes from zebra and decremnt the
5399 uninstall_routes_for_vrf(bgp_vrf
);
5401 /* delete/withdraw all type-5 routes */
5402 delete_withdraw_vrf_routes(bgp_vrf
);
5404 /* remove the l3vni from vrf instance */
5407 /* remove the Rmac from the BGP vrf */
5408 memset(&bgp_vrf
->rmac
, 0, sizeof(struct ethaddr
));
5411 if (!list_isempty(bgp_vrf
->vrf_import_rtl
)) {
5412 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf
);
5413 list_delete_all_node(bgp_vrf
->vrf_import_rtl
);
5415 if (!list_isempty(bgp_vrf
->vrf_export_rtl
)) {
5416 list_delete_all_node(bgp_vrf
->vrf_export_rtl
);
5419 /* update all corresponding local mac-ip routes */
5420 if (!CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY
)) {
5421 for (ALL_LIST_ELEMENTS_RO(bgp_vrf
->l2vnis
, node
, vpn
)) {
5422 UNSET_FLAG(vpn
->flags
, VNI_FLAG_USE_TWO_LABELS
);
5423 update_routes_for_vni(bgp_def
, vpn
);
5427 /* If any L2VNIs point to this instance, unlink them. */
5428 for (ALL_LIST_ELEMENTS(bgp_vrf
->l2vnis
, node
, next
, vpn
))
5429 bgpevpn_unlink_from_l3vni(vpn
);
5431 /* Delete the instance if it was autocreated */
5432 if (CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_AUTO
))
5433 bgp_delete(bgp_vrf
);
5439 * Handle del of a local VNI.
5441 int bgp_evpn_local_vni_del(struct bgp
*bgp
, vni_t vni
)
5443 struct bgpevpn
*vpn
;
5445 /* Locate VNI hash */
5446 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
5448 if (bgp_debug_zebra(NULL
))
5450 EC_BGP_EVPN_VPN_VNI
,
5451 "%u: VNI hash entry for VNI %u not found at DEL",
5456 /* Remove all local EVPN routes and schedule for processing (to
5457 * withdraw from peers).
5459 delete_routes_for_vni(bgp
, vpn
);
5462 * tunnel is no longer active, del tunnel ip address from tip_hash
5464 bgp_tip_del(bgp
, &vpn
->originator_ip
);
5466 /* Clear "live" flag and see if hash needs to be freed. */
5467 UNSET_FLAG(vpn
->flags
, VNI_FLAG_LIVE
);
5468 if (!is_vni_configured(vpn
))
5469 bgp_evpn_free(bgp
, vpn
);
5475 * Handle add (or update) of a local VNI. The VNI changes we care
5476 * about are for the local-tunnel-ip and the (tenant) VRF.
5478 int bgp_evpn_local_vni_add(struct bgp
*bgp
, vni_t vni
,
5479 struct in_addr originator_ip
, vrf_id_t tenant_vrf_id
)
5481 struct bgpevpn
*vpn
;
5482 struct prefix_evpn p
;
5484 /* Lookup VNI. If present and no change, exit. */
5485 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
5488 if (is_vni_live(vpn
)
5489 && IPV4_ADDR_SAME(&vpn
->originator_ip
, &originator_ip
)
5490 && vpn
->tenant_vrf_id
== tenant_vrf_id
)
5491 /* Probably some other param has changed that we don't
5495 /* Update tenant_vrf_id if it has changed. */
5496 if (vpn
->tenant_vrf_id
!= tenant_vrf_id
) {
5497 bgpevpn_unlink_from_l3vni(vpn
);
5498 vpn
->tenant_vrf_id
= tenant_vrf_id
;
5499 bgpevpn_link_to_l3vni(vpn
);
5502 /* If tunnel endpoint IP has changed, update (and delete prior
5503 * type-3 route, if needed.)
5505 if (!IPV4_ADDR_SAME(&vpn
->originator_ip
, &originator_ip
))
5506 handle_tunnel_ip_change(bgp
, vpn
, originator_ip
);
5508 /* Update all routes with new endpoint IP and/or export RT
5511 if (is_vni_live(vpn
))
5512 update_routes_for_vni(bgp
, vpn
);
5515 /* Create or update as appropriate. */
5517 vpn
= bgp_evpn_new(bgp
, vni
, originator_ip
, tenant_vrf_id
);
5521 "%u: Failed to allocate VNI entry for VNI %u - at Add",
5527 /* if the VNI is live already, there is nothing more to do */
5528 if (is_vni_live(vpn
))
5531 /* Mark as "live" */
5532 SET_FLAG(vpn
->flags
, VNI_FLAG_LIVE
);
5534 /* tunnel is now active, add tunnel-ip to db */
5535 bgp_tip_add(bgp
, &originator_ip
);
5537 /* filter routes as nexthop database has changed */
5538 bgp_filter_evpn_routes_upon_martian_nh_change(bgp
);
5541 * Create EVPN type-3 route and schedule for processing.
5543 * RT-3 only if doing head-end replication
5545 if (bgp
->vxlan_flood_ctrl
== VXLAN_FLOOD_HEAD_END_REPL
) {
5546 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
5547 if (update_evpn_route(bgp
, vpn
, &p
, 0, 0)) {
5548 flog_err(EC_BGP_EVPN_ROUTE_CREATE
,
5549 "%u: Type3 route creation failure for VNI %u",
5555 /* If we have learnt and retained remote routes (VTEPs, MACs) for this
5559 install_routes_for_vni(bgp
, vpn
);
5561 /* If we are advertising gateway mac-ip
5562 It needs to be conveyed again to zebra */
5563 bgp_zebra_advertise_gw_macip(bgp
, vpn
->advertise_gw_macip
, vpn
->vni
);
5569 * bgp_evpn_local_es_del
5571 int bgp_evpn_local_es_del(struct bgp
*bgp
,
5573 struct ipaddr
*originator_ip
)
5575 char buf
[ESI_STR_LEN
];
5576 struct evpnes
*es
= NULL
;
5578 if (!bgp
->esihash
) {
5579 flog_err(EC_BGP_ES_CREATE
, "%u: ESI hash not yet created",
5584 /* Lookup ESI hash - should exist. */
5585 es
= bgp_evpn_lookup_es(bgp
, esi
);
5587 flog_warn(EC_BGP_EVPN_ESI
,
5588 "%u: ESI hash entry for ESI %s at Local ES DEL",
5589 bgp
->vrf_id
, esi_to_str(esi
, buf
, sizeof(buf
)));
5593 /* Delete all local EVPN ES routes from ESI table
5594 * and schedule for processing (to withdraw from peers))
5596 delete_routes_for_es(bgp
, es
);
5598 /* free the hash entry */
5599 bgp_evpn_es_free(bgp
, es
);
5605 * bgp_evpn_local_es_add
5607 int bgp_evpn_local_es_add(struct bgp
*bgp
,
5609 struct ipaddr
*originator_ip
)
5611 char buf
[ESI_STR_LEN
];
5612 struct evpnes
*es
= NULL
;
5613 struct prefix_evpn p
;
5615 if (!bgp
->esihash
) {
5616 flog_err(EC_BGP_ES_CREATE
, "%u: ESI hash not yet created",
5621 /* create the new es */
5622 es
= bgp_evpn_lookup_es(bgp
, esi
);
5624 es
= bgp_evpn_es_new(bgp
, esi
, originator_ip
);
5628 "%u: Failed to allocate ES entry for ESI %s - at Local ES Add",
5629 bgp
->vrf_id
, esi_to_str(esi
, buf
, sizeof(buf
)));
5633 UNSET_FLAG(es
->flags
, EVPNES_REMOTE
);
5634 SET_FLAG(es
->flags
, EVPNES_LOCAL
);
5636 build_evpn_type4_prefix(&p
, esi
, originator_ip
->ipaddr_v4
);
5637 if (update_evpn_type4_route(bgp
, es
, &p
)) {
5638 flog_err(EC_BGP_EVPN_ROUTE_CREATE
,
5639 "%u: Type4 route creation failure for ESI %s",
5640 bgp
->vrf_id
, esi_to_str(esi
, buf
, sizeof(buf
)));
5644 /* import all remote ES routes in th ES table */
5645 install_routes_for_es(bgp
, es
);
5651 * Handle change in setting for BUM handling. The supported values
5652 * are head-end replication and dropping all BUM packets. Any change
5653 * should be registered with zebra. Also, if doing head-end replication,
5654 * need to advertise local VNIs as EVPN RT-3 wheras, if BUM packets are
5655 * to be dropped, the RT-3s must be withdrawn.
5657 void bgp_evpn_flood_control_change(struct bgp
*bgp
)
5659 zlog_info("L2VPN EVPN BUM handling is %s",
5660 bgp
->vxlan_flood_ctrl
== VXLAN_FLOOD_HEAD_END_REPL
?
5661 "Flooding" : "Flooding Disabled");
5663 bgp_zebra_vxlan_flood_control(bgp
, bgp
->vxlan_flood_ctrl
);
5664 if (bgp
->vxlan_flood_ctrl
== VXLAN_FLOOD_HEAD_END_REPL
)
5665 hash_iterate(bgp
->vnihash
, create_advertise_type3
, bgp
);
5666 else if (bgp
->vxlan_flood_ctrl
== VXLAN_FLOOD_DISABLED
)
5667 hash_iterate(bgp
->vnihash
, delete_withdraw_type3
, bgp
);
5671 * Cleanup EVPN information on disable - Need to delete and withdraw
5672 * EVPN routes from peers.
5674 void bgp_evpn_cleanup_on_disable(struct bgp
*bgp
)
5676 hash_iterate(bgp
->vnihash
, (void (*)(struct hash_backet
*,
5677 void *))cleanup_vni_on_disable
,
5682 * Cleanup EVPN information - invoked at the time of bgpd exit or when the
5683 * BGP instance (default) is being freed.
5685 void bgp_evpn_cleanup(struct bgp
*bgp
)
5687 hash_iterate(bgp
->vnihash
,
5688 (void (*)(struct hash_backet
*, void *))free_vni_entry
,
5691 hash_free(bgp
->import_rt_hash
);
5692 bgp
->import_rt_hash
= NULL
;
5694 hash_free(bgp
->vrf_import_rt_hash
);
5695 bgp
->vrf_import_rt_hash
= NULL
;
5697 hash_free(bgp
->vnihash
);
5698 bgp
->vnihash
= NULL
;
5700 hash_free(bgp
->esihash
);
5701 bgp
->esihash
= NULL
;
5703 list_delete(&bgp
->vrf_import_rtl
);
5704 list_delete(&bgp
->vrf_export_rtl
);
5705 list_delete(&bgp
->l2vnis
);
5709 * Initialization for EVPN
5712 * hash for RT to VNI
5714 void bgp_evpn_init(struct bgp
*bgp
)
5717 hash_create(vni_hash_key_make
, vni_hash_cmp
, "BGP VNI Hash");
5719 hash_create(esi_hash_keymake
, esi_cmp
,
5720 "BGP EVPN Local ESI Hash");
5721 bgp
->import_rt_hash
=
5722 hash_create(import_rt_hash_key_make
, import_rt_hash_cmp
,
5723 "BGP Import RT Hash");
5724 bgp
->vrf_import_rt_hash
=
5725 hash_create(vrf_import_rt_hash_key_make
, vrf_import_rt_hash_cmp
,
5726 "BGP VRF Import RT Hash");
5727 bgp
->vrf_import_rtl
= list_new();
5728 bgp
->vrf_import_rtl
->cmp
=
5729 (int (*)(void *, void *))evpn_route_target_cmp
;
5730 bgp
->vrf_import_rtl
->del
= evpn_xxport_delete_ecomm
;
5731 bgp
->vrf_export_rtl
= list_new();
5732 bgp
->vrf_export_rtl
->cmp
=
5733 (int (*)(void *, void *))evpn_route_target_cmp
;
5734 bgp
->vrf_export_rtl
->del
= evpn_xxport_delete_ecomm
;
5735 bgp
->l2vnis
= list_new();
5736 bgp
->l2vnis
->cmp
= vni_list_cmp
;
5738 /* Default BUM handling is to do head-end replication. */
5739 bgp
->vxlan_flood_ctrl
= VXLAN_FLOOD_HEAD_END_REPL
;
5742 void bgp_evpn_vrf_delete(struct bgp
*bgp_vrf
)
5744 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf
);