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_aspath.h"
47 #include "bgpd/bgp_zebra.h"
48 #include "bgpd/bgp_nexthop.h"
51 * Definitions and external declarations.
53 extern struct zclient
*zclient
;
55 DEFINE_QOBJ_TYPE(bgpevpn
)
59 * Static function declarations
61 static void delete_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
62 afi_t afi
, safi_t safi
, struct bgp_node
*rn
,
63 struct bgp_info
**ri
);
64 static int delete_all_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
);
73 static unsigned int vni_hash_key_make(void *p
)
75 struct bgpevpn
*vpn
= p
;
76 return (jhash_1word(vpn
->vni
, 0));
80 * Comparison function for vni hash
82 static int vni_hash_cmp(const void *p1
, const void *p2
)
84 const struct bgpevpn
*vpn1
= p1
;
85 const struct bgpevpn
*vpn2
= p2
;
91 return (vpn1
->vni
== vpn2
->vni
);
95 * Make vrf import route target hash key.
97 static unsigned int vrf_import_rt_hash_key_make(void *p
)
99 struct vrf_irt_node
*irt
= p
;
100 char *pnt
= irt
->rt
.val
;
102 return jhash(pnt
, 8, 0x5abc1234);
106 * Comparison function for vrf import rt hash
108 static int vrf_import_rt_hash_cmp(const void *p1
, const void *p2
)
110 const struct vrf_irt_node
*irt1
= p1
;
111 const struct vrf_irt_node
*irt2
= p2
;
113 if (irt1
== NULL
&& irt2
== NULL
)
116 if (irt1
== NULL
|| irt2
== NULL
)
119 return (memcmp(irt1
->rt
.val
, irt2
->rt
.val
, ECOMMUNITY_SIZE
) == 0);
123 * Create a new vrf import_rt in default instance
125 static struct vrf_irt_node
*vrf_import_rt_new(struct ecommunity_val
*rt
)
127 struct bgp
*bgp_def
= NULL
;
128 struct vrf_irt_node
*irt
;
130 bgp_def
= bgp_get_default();
132 zlog_err("vrf import rt new - def instance not created yet");
136 irt
= XCALLOC(MTYPE_BGP_EVPN_VRF_IMPORT_RT
,
137 sizeof(struct vrf_irt_node
));
142 irt
->vrfs
= list_new();
145 if (!hash_get(bgp_def
->vrf_import_rt_hash
, irt
, hash_alloc_intern
)) {
146 XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT
, irt
);
154 * Free the vrf import rt node
156 static void vrf_import_rt_free(struct vrf_irt_node
*irt
)
158 struct bgp
*bgp_def
= NULL
;
160 bgp_def
= bgp_get_default();
162 zlog_err("vrf import rt free - def instance not created yet");
166 hash_release(bgp_def
->vrf_import_rt_hash
, irt
);
167 XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT
, irt
);
171 * Function to lookup Import RT node - used to map a RT to set of
172 * VNIs importing routes with that RT.
174 static struct vrf_irt_node
*lookup_vrf_import_rt(struct ecommunity_val
*rt
)
176 struct bgp
*bgp_def
= NULL
;
177 struct vrf_irt_node
*irt
;
178 struct vrf_irt_node tmp
;
180 bgp_def
= bgp_get_default();
182 zlog_err("vrf import rt lookup - def instance not created yet");
186 memset(&tmp
, 0, sizeof(struct vrf_irt_node
));
187 memcpy(&tmp
.rt
, rt
, ECOMMUNITY_SIZE
);
188 irt
= hash_lookup(bgp_def
->vrf_import_rt_hash
, &tmp
);
193 * Is specified VRF present on the RT's list of "importing" VRFs?
195 static int is_vrf_present_in_irt_vrfs(struct list
*vrfs
, struct bgp
*bgp_vrf
)
197 struct listnode
*node
= NULL
, *nnode
= NULL
;
198 struct bgp
*tmp_bgp_vrf
= NULL
;
200 for (ALL_LIST_ELEMENTS(vrfs
, node
, nnode
, tmp_bgp_vrf
)) {
201 if (tmp_bgp_vrf
== bgp_vrf
)
208 * Make import route target hash key.
210 static unsigned int import_rt_hash_key_make(void *p
)
212 struct irt_node
*irt
= p
;
213 char *pnt
= irt
->rt
.val
;
215 return jhash(pnt
, 8, 0xdeadbeef);
219 * Comparison function for import rt hash
221 static int import_rt_hash_cmp(const void *p1
, const void *p2
)
223 const struct irt_node
*irt1
= p1
;
224 const struct irt_node
*irt2
= p2
;
226 if (irt1
== NULL
&& irt2
== NULL
)
229 if (irt1
== NULL
|| irt2
== NULL
)
232 return (memcmp(irt1
->rt
.val
, irt2
->rt
.val
, ECOMMUNITY_SIZE
) == 0);
236 * Create a new import_rt
238 static struct irt_node
*import_rt_new(struct bgp
*bgp
,
239 struct ecommunity_val
*rt
)
241 struct irt_node
*irt
;
246 irt
= XCALLOC(MTYPE_BGP_EVPN_IMPORT_RT
, sizeof(struct irt_node
));
251 irt
->vnis
= list_new();
254 if (!hash_get(bgp
->import_rt_hash
, irt
, hash_alloc_intern
)) {
255 XFREE(MTYPE_BGP_EVPN_IMPORT_RT
, irt
);
263 * Free the import rt node
265 static void import_rt_free(struct bgp
*bgp
, struct irt_node
*irt
)
267 hash_release(bgp
->import_rt_hash
, irt
);
268 XFREE(MTYPE_BGP_EVPN_IMPORT_RT
, irt
);
272 * Function to lookup Import RT node - used to map a RT to set of
273 * VNIs importing routes with that RT.
275 static struct irt_node
*lookup_import_rt(struct bgp
*bgp
,
276 struct ecommunity_val
*rt
)
278 struct irt_node
*irt
;
281 memset(&tmp
, 0, sizeof(struct irt_node
));
282 memcpy(&tmp
.rt
, rt
, ECOMMUNITY_SIZE
);
283 irt
= hash_lookup(bgp
->import_rt_hash
, &tmp
);
288 * Is specified VNI present on the RT's list of "importing" VNIs?
290 static int is_vni_present_in_irt_vnis(struct list
*vnis
, struct bgpevpn
*vpn
)
292 struct listnode
*node
, *nnode
;
293 struct bgpevpn
*tmp_vpn
;
295 for (ALL_LIST_ELEMENTS(vnis
, node
, nnode
, tmp_vpn
)) {
304 * Compare Route Targets.
306 static int evpn_route_target_cmp(struct ecommunity
*ecom1
,
307 struct ecommunity
*ecom2
)
315 if (!ecom1
&& !ecom2
)
318 if (ecom1
->str
&& !ecom2
->str
)
321 if (!ecom1
->str
&& ecom2
->str
)
324 if (!ecom1
->str
&& !ecom2
->str
)
327 return strcmp(ecom1
->str
, ecom2
->str
);
331 * Mask off global-admin field of specified extended community (RT),
332 * just retain the local-admin field.
334 static inline void mask_ecom_global_admin(struct ecommunity_val
*dst
,
335 struct ecommunity_val
*src
)
341 if (type
== ECOMMUNITY_ENCODE_AS
) {
342 dst
->val
[2] = dst
->val
[3] = 0;
343 } else if (type
== ECOMMUNITY_ENCODE_AS4
344 || type
== ECOMMUNITY_ENCODE_IP
) {
345 dst
->val
[2] = dst
->val
[3] = 0;
346 dst
->val
[4] = dst
->val
[5] = 0;
351 * Map one RT to specified VRF.
352 * bgp_vrf = BGP vrf instance
354 static void map_vrf_to_rt(struct bgp
*bgp_vrf
, struct ecommunity_val
*eval
)
356 struct vrf_irt_node
*irt
= NULL
;
357 struct ecommunity_val eval_tmp
;
359 /* If using "automatic" RT,
360 * we only care about the local-admin sub-field.
361 * This is to facilitate using L3VNI(VRF-VNI)
362 * as the RT for EBGP peering too.
364 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
365 if (!CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_IMPORT_RT_CFGD
))
366 mask_ecom_global_admin(&eval_tmp
, eval
);
368 irt
= lookup_vrf_import_rt(&eval_tmp
);
369 if (irt
&& is_vrf_present_in_irt_vrfs(irt
->vrfs
, bgp_vrf
))
370 /* Already mapped. */
374 irt
= vrf_import_rt_new(&eval_tmp
);
376 /* Add VRF to the list for this RT. */
377 listnode_add(irt
->vrfs
, bgp_vrf
);
381 * Unmap specified VRF from specified RT. If there are no other
382 * VRFs for this RT, then the RT hash is deleted.
383 * bgp_vrf: BGP VRF specific instance
385 static void unmap_vrf_from_rt(struct bgp
*bgp_vrf
, struct vrf_irt_node
*irt
)
387 /* Delete VRF from list for this RT. */
388 listnode_delete(irt
->vrfs
, bgp_vrf
);
389 if (!listnode_head(irt
->vrfs
)) {
390 list_delete_and_null(&irt
->vrfs
);
391 vrf_import_rt_free(irt
);
396 * Map one RT to specified VNI.
398 static void map_vni_to_rt(struct bgp
*bgp
, struct bgpevpn
*vpn
,
399 struct ecommunity_val
*eval
)
401 struct irt_node
*irt
;
402 struct ecommunity_val eval_tmp
;
404 /* If using "automatic" RT, we only care about the local-admin
406 * This is to facilitate using VNI as the RT for EBGP peering too.
408 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
409 if (!is_import_rt_configured(vpn
))
410 mask_ecom_global_admin(&eval_tmp
, eval
);
412 irt
= lookup_import_rt(bgp
, &eval_tmp
);
413 if (irt
&& irt
->vnis
)
414 if (is_vni_present_in_irt_vnis(irt
->vnis
, vpn
))
415 /* Already mapped. */
419 irt
= import_rt_new(bgp
, &eval_tmp
);
423 /* Add VNI to the hash list for this RT. */
424 listnode_add(irt
->vnis
, vpn
);
428 * Unmap specified VNI from specified RT. If there are no other
429 * VNIs for this RT, then the RT hash is deleted.
431 static void unmap_vni_from_rt(struct bgp
*bgp
, struct bgpevpn
*vpn
,
432 struct irt_node
*irt
)
434 /* Delete VNI from hash list for this RT. */
435 listnode_delete(irt
->vnis
, vpn
);
436 if (!listnode_head(irt
->vnis
)) {
437 list_delete_and_null(&irt
->vnis
);
438 import_rt_free(bgp
, irt
);
443 * Create RT extended community automatically from passed information:
444 * of the form AS:VNI.
445 * NOTE: We use only the lower 16 bits of the AS. This is sufficient as
446 * the need is to get a RT value that will be unique across different
447 * VNIs but the same across routers (in the same AS) for a particular
450 static void form_auto_rt(struct bgp
*bgp
, vni_t vni
, struct list
*rtl
)
452 struct ecommunity_val eval
;
453 struct ecommunity
*ecomadd
;
455 encode_route_target_as((bgp
->as
& 0xFFFF), vni
, &eval
);
457 ecomadd
= ecommunity_new();
458 ecommunity_add_val(ecomadd
, &eval
);
459 listnode_add_sort(rtl
, ecomadd
);
463 * Derive RD and RT for a VNI automatically. Invoked at the time of
466 static void derive_rd_rt_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
468 bgp_evpn_derive_auto_rd(bgp
, vpn
);
469 bgp_evpn_derive_auto_rt_import(bgp
, vpn
);
470 bgp_evpn_derive_auto_rt_export(bgp
, vpn
);
474 * Convert nexthop (remote VTEP IP) into an IPv6 address.
476 static void evpn_convert_nexthop_to_ipv6(struct attr
*attr
)
478 if (BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
480 ipv4_to_ipv4_mapped_ipv6(&attr
->mp_nexthop_global
, attr
->nexthop
);
481 attr
->mp_nexthop_len
= IPV6_MAX_BYTELEN
;
485 * Add (update) or delete MACIP from zebra.
487 static int bgp_zebra_send_remote_macip(struct bgp
*bgp
, struct bgpevpn
*vpn
,
488 struct prefix_evpn
*p
,
489 struct in_addr remote_vtep_ip
, int add
,
494 char buf1
[ETHER_ADDR_STRLEN
];
495 char buf2
[INET6_ADDRSTRLEN
];
496 char buf3
[INET6_ADDRSTRLEN
];
499 if (!zclient
|| zclient
->sock
< 0)
502 /* Don't try to register if Zebra doesn't know of this instance. */
503 if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
509 zclient_create_header(
510 s
, add
? ZEBRA_REMOTE_MACIP_ADD
: ZEBRA_REMOTE_MACIP_DEL
,
512 stream_putl(s
, vpn
->vni
);
513 stream_put(s
, &p
->prefix
.mac
.octet
, ETH_ALEN
); /* Mac Addr */
514 /* IP address length and IP address, if any. */
515 if (IS_EVPN_PREFIX_IPADDR_NONE(p
))
518 ipa_len
= IS_EVPN_PREFIX_IPADDR_V4(p
) ? IPV4_MAX_BYTELEN
520 stream_putl(s
, ipa_len
);
521 stream_put(s
, &p
->prefix
.ip
.ip
.addr
, ipa_len
);
523 stream_put_in_addr(s
, &remote_vtep_ip
);
525 /* TX flags - MAC sticky status and/or gateway mac */
527 stream_putc(s
, flags
);
529 stream_putw_at(s
, 0, stream_get_endp(s
));
531 if (bgp_debug_zebra(NULL
))
533 "Tx %s MACIP, VNI %u MAC %s IP %s (flags: 0x%x) remote VTEP %s",
534 add
? "ADD" : "DEL", vpn
->vni
,
535 prefix_mac2str(&p
->prefix
.mac
, buf1
, sizeof(buf1
)),
536 ipaddr2str(&p
->prefix
.ip
, buf3
, sizeof(buf3
)), flags
,
537 inet_ntop(AF_INET
, &remote_vtep_ip
, buf2
,
540 return zclient_send_message(zclient
);
544 * Add (update) or delete remote VTEP from zebra.
546 static int bgp_zebra_send_remote_vtep(struct bgp
*bgp
, struct bgpevpn
*vpn
,
547 struct prefix_evpn
*p
, int add
)
552 if (!zclient
|| zclient
->sock
< 0)
555 /* Don't try to register if Zebra doesn't know of this instance. */
556 if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
562 zclient_create_header(
563 s
, add
? ZEBRA_REMOTE_VTEP_ADD
: ZEBRA_REMOTE_VTEP_DEL
,
565 stream_putl(s
, vpn
->vni
);
566 if (IS_EVPN_PREFIX_IPADDR_V4(p
))
567 stream_put_in_addr(s
, &p
->prefix
.ip
.ipaddr_v4
);
568 else if (IS_EVPN_PREFIX_IPADDR_V6(p
)) {
570 "Bad remote IP when trying to %s remote VTEP for VNI %u",
571 add
? "ADD" : "DEL", vpn
->vni
);
575 stream_putw_at(s
, 0, stream_get_endp(s
));
577 if (bgp_debug_zebra(NULL
))
578 zlog_debug("Tx %s Remote VTEP, VNI %u remote VTEP %s",
579 add
? "ADD" : "DEL", vpn
->vni
,
580 inet_ntoa(p
->prefix
.ip
.ipaddr_v4
));
582 return zclient_send_message(zclient
);
586 * Build extended communities for EVPN prefix route.
588 static void build_evpn_type5_route_extcomm(struct bgp
*bgp_vrf
,
591 struct ecommunity ecom_encap
;
592 struct ecommunity ecom_rmac
;
593 struct ecommunity_val eval
;
594 struct ecommunity_val eval_rmac
;
595 bgp_encap_types tnl_type
;
596 struct listnode
*node
, *nnode
;
597 struct ecommunity
*ecom
;
598 struct list
*vrf_export_rtl
= NULL
;
601 tnl_type
= BGP_ENCAP_TYPE_VXLAN
;
602 memset(&ecom_encap
, 0, sizeof(ecom_encap
));
603 encode_encap_extcomm(tnl_type
, &eval
);
605 ecom_encap
.val
= (uint8_t *)eval
.val
;
608 attr
->ecommunity
= ecommunity_dup(&ecom_encap
);
610 /* Add the export RTs for L3VNI/VRF */
611 vrf_export_rtl
= bgp_vrf
->vrf_export_rtl
;
612 if (vrf_export_rtl
&& !list_isempty(vrf_export_rtl
)) {
613 for (ALL_LIST_ELEMENTS(vrf_export_rtl
, node
, nnode
, ecom
))
615 ecommunity_merge(attr
->ecommunity
, ecom
);
618 /* add the router mac extended community */
619 if (!is_zero_mac(&attr
->rmac
)) {
620 memset(&ecom_rmac
, 0, sizeof(ecom_rmac
));
621 encode_rmac_extcomm(&eval_rmac
, &attr
->rmac
);
623 ecom_rmac
.val
= (uint8_t *)eval_rmac
.val
;
625 ecommunity_merge(attr
->ecommunity
, &ecom_rmac
);
628 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
);
632 * Build extended communities for EVPN route.
633 * This function is applicable for type-2 and type-3 routes. The layer-2 RT
634 * and ENCAP extended communities are applicable for all routes.
635 * The default gateway extended community and MAC mobility (sticky) extended
636 * community are added as needed based on passed settings - only for type-2
637 * routes. Likewise, the layer-3 RT and Router MAC extended communities are
638 * added, if present, based on passed settings - only for non-link-local
641 static void build_evpn_route_extcomm(struct bgpevpn
*vpn
, struct attr
*attr
,
644 struct ecommunity ecom_encap
;
645 struct ecommunity ecom_sticky
;
646 struct ecommunity ecom_default_gw
;
647 struct ecommunity ecom_rmac
;
648 struct ecommunity_val eval
;
649 struct ecommunity_val eval_sticky
;
650 struct ecommunity_val eval_default_gw
;
651 struct ecommunity_val eval_rmac
;
652 bgp_encap_types tnl_type
;
653 struct listnode
*node
, *nnode
;
654 struct ecommunity
*ecom
;
656 struct list
*vrf_export_rtl
= NULL
;
659 tnl_type
= BGP_ENCAP_TYPE_VXLAN
;
660 memset(&ecom_encap
, 0, sizeof(ecom_encap
));
661 encode_encap_extcomm(tnl_type
, &eval
);
663 ecom_encap
.val
= (uint8_t *)eval
.val
;
666 attr
->ecommunity
= ecommunity_dup(&ecom_encap
);
668 /* Add the export RTs for L2VNI */
669 for (ALL_LIST_ELEMENTS(vpn
->export_rtl
, node
, nnode
, ecom
))
670 attr
->ecommunity
= ecommunity_merge(attr
->ecommunity
, ecom
);
672 /* Add the export RTs for L3VNI if told to - caller determines
673 * when this should be done.
676 vrf_export_rtl
= bgpevpn_get_vrf_export_rtl(vpn
);
677 if (vrf_export_rtl
&& !list_isempty(vrf_export_rtl
)) {
678 for (ALL_LIST_ELEMENTS(vrf_export_rtl
, node
, nnode
,
680 attr
->ecommunity
= ecommunity_merge(
681 attr
->ecommunity
, ecom
);
685 /* Add MAC mobility (sticky) if needed. */
688 memset(&ecom_sticky
, 0, sizeof(ecom_sticky
));
689 encode_mac_mobility_extcomm(1, seqnum
, &eval_sticky
);
690 ecom_sticky
.size
= 1;
691 ecom_sticky
.val
= (uint8_t *)eval_sticky
.val
;
693 ecommunity_merge(attr
->ecommunity
, &ecom_sticky
);
696 /* Add RMAC, if told to. */
698 memset(&ecom_rmac
, 0, sizeof(ecom_rmac
));
699 encode_rmac_extcomm(&eval_rmac
, &attr
->rmac
);
701 ecom_rmac
.val
= (uint8_t *)eval_rmac
.val
;
703 ecommunity_merge(attr
->ecommunity
, &ecom_rmac
);
706 /* Add default gateway, if needed. */
707 if (attr
->default_gw
) {
708 memset(&ecom_default_gw
, 0, sizeof(ecom_default_gw
));
709 encode_default_gw_extcomm(&eval_default_gw
);
710 ecom_default_gw
.size
= 1;
711 ecom_default_gw
.val
= (uint8_t *)eval_default_gw
.val
;
713 ecommunity_merge(attr
->ecommunity
, &ecom_default_gw
);
716 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
);
720 * Add MAC mobility extended community to attribute.
722 static void add_mac_mobility_to_attr(uint32_t seq_num
, struct attr
*attr
)
724 struct ecommunity ecom_tmp
;
725 struct ecommunity_val eval
;
726 uint8_t *ecom_val_ptr
;
733 encode_mac_mobility_extcomm(0, seq_num
, &eval
);
735 /* Find current MM ecommunity */
738 if (attr
->ecommunity
) {
739 for (i
= 0; i
< attr
->ecommunity
->size
; i
++) {
740 pnt
= attr
->ecommunity
->val
+ (i
* 8);
744 if (type
== ECOMMUNITY_ENCODE_EVPN
746 == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY
) {
747 ecom_val_ptr
= (uint8_t *)(attr
->ecommunity
->val
754 /* Update the existing MM ecommunity */
756 memcpy(ecom_val_ptr
, eval
.val
, sizeof(char) * ECOMMUNITY_SIZE
);
758 /* Add MM to existing */
760 memset(&ecom_tmp
, 0, sizeof(ecom_tmp
));
762 ecom_tmp
.val
= (uint8_t *)eval
.val
;
765 ecommunity_merge(attr
->ecommunity
, &ecom_tmp
);
769 /* Install EVPN route into zebra. */
770 static int evpn_zebra_install(struct bgp
*bgp
, struct bgpevpn
*vpn
,
771 struct prefix_evpn
*p
,
772 struct in_addr remote_vtep_ip
, uint8_t flags
)
776 if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
)
777 ret
= bgp_zebra_send_remote_macip(bgp
, vpn
, p
, remote_vtep_ip
,
780 ret
= bgp_zebra_send_remote_vtep(bgp
, vpn
, p
, 1);
785 /* Uninstall EVPN route from zebra. */
786 static int evpn_zebra_uninstall(struct bgp
*bgp
, struct bgpevpn
*vpn
,
787 struct prefix_evpn
*p
,
788 struct in_addr remote_vtep_ip
)
792 if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
)
793 ret
= bgp_zebra_send_remote_macip(bgp
, vpn
, p
, remote_vtep_ip
,
796 ret
= bgp_zebra_send_remote_vtep(bgp
, vpn
, p
, 0);
802 * Due to MAC mobility, the prior "local" best route has been supplanted
803 * by a "remote" best route. The prior route has to be deleted and withdrawn
806 static void evpn_delete_old_local_route(struct bgp
*bgp
, struct bgpevpn
*vpn
,
808 struct bgp_info
*old_local
)
810 struct bgp_node
*global_rn
;
812 afi_t afi
= AFI_L2VPN
;
813 safi_t safi
= SAFI_EVPN
;
815 /* Locate route node in the global EVPN routing table. Note that
816 * this table is a 2-level tree (RD-level + Prefix-level) similar to
819 global_rn
= bgp_afi_node_lookup(bgp
->rib
[afi
][safi
], afi
, safi
,
820 (struct prefix
*)&rn
->p
, &vpn
->prd
);
822 /* Delete route entry in the global EVPN table. */
823 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, &ri
);
825 /* Schedule for processing - withdraws to peers happen from
829 bgp_process(bgp
, global_rn
, afi
, safi
);
830 bgp_unlock_node(global_rn
);
833 /* Delete route entry in the VNI route table, caller to remove. */
834 bgp_info_delete(rn
, old_local
);
838 * Calculate the best path for an EVPN route. Install/update best path in zebra,
841 static int evpn_route_select_install(struct bgp
*bgp
, struct bgpevpn
*vpn
,
844 struct bgp_info
*old_select
, *new_select
;
845 struct bgp_info_pair old_and_new
;
846 afi_t afi
= AFI_L2VPN
;
847 safi_t safi
= SAFI_EVPN
;
851 /* Compute the best path. */
852 bgp_best_selection(bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
,
854 old_select
= old_and_new
.old
;
855 new_select
= old_and_new
.new;
857 /* If the best path hasn't changed - see if there is still something to
861 if (old_select
&& old_select
== new_select
862 && old_select
->type
== ZEBRA_ROUTE_BGP
863 && old_select
->sub_type
== BGP_ROUTE_IMPORTED
864 && !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
)
865 && !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
)
866 && !bgp
->addpath_tx_used
[afi
][safi
]) {
867 if (bgp_zebra_has_route_changed(rn
, old_select
)) {
868 if (old_select
->attr
->sticky
)
869 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
870 if (old_select
->attr
->default_gw
)
871 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
872 ret
= evpn_zebra_install(
873 bgp
, vpn
, (struct prefix_evpn
*)&rn
->p
,
874 old_select
->attr
->nexthop
, flags
);
876 UNSET_FLAG(old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
877 bgp_zebra_clear_route_change_flags(rn
);
881 /* If the user did a "clear" this flag will be set */
882 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
884 /* bestpath has changed; update relevant fields and install or uninstall
885 * into the zebra RIB.
887 if (old_select
|| new_select
)
888 bgp_bump_version(rn
);
891 bgp_info_unset_flag(rn
, old_select
, BGP_INFO_SELECTED
);
893 bgp_info_set_flag(rn
, new_select
, BGP_INFO_SELECTED
);
894 bgp_info_unset_flag(rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
895 UNSET_FLAG(new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
898 if (new_select
&& new_select
->type
== ZEBRA_ROUTE_BGP
899 && new_select
->sub_type
== BGP_ROUTE_IMPORTED
) {
901 if (new_select
->attr
->sticky
)
902 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
);
903 if (new_select
->attr
->default_gw
)
904 SET_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
);
905 ret
= evpn_zebra_install(bgp
, vpn
, (struct prefix_evpn
*)&rn
->p
,
906 new_select
->attr
->nexthop
, flags
);
907 /* If an old best existed and it was a "local" route, the only
909 * it would be supplanted is due to MAC mobility procedures. So,
911 * need to do an implicit delete and withdraw that route from
914 if (old_select
&& old_select
->peer
== bgp
->peer_self
915 && old_select
->type
== ZEBRA_ROUTE_BGP
916 && old_select
->sub_type
== BGP_ROUTE_STATIC
)
917 evpn_delete_old_local_route(bgp
, vpn
, rn
, old_select
);
919 if (old_select
&& old_select
->type
== ZEBRA_ROUTE_BGP
920 && old_select
->sub_type
== BGP_ROUTE_IMPORTED
)
921 ret
= evpn_zebra_uninstall(bgp
, vpn
,
922 (struct prefix_evpn
*)&rn
->p
,
923 old_select
->attr
->nexthop
);
926 /* Clear any route change flags. */
927 bgp_zebra_clear_route_change_flags(rn
);
929 /* Reap old select bgp_info, if it has been removed */
930 if (old_select
&& CHECK_FLAG(old_select
->flags
, BGP_INFO_REMOVED
))
931 bgp_info_reap(rn
, old_select
);
937 * Return true if the local ri for this rn is of type gateway mac
939 static int evpn_route_is_def_gw(struct bgp
*bgp
, struct bgp_node
*rn
)
941 struct bgp_info
*tmp_ri
= NULL
;
942 struct bgp_info
*local_ri
= NULL
;
945 for (tmp_ri
= rn
->info
; tmp_ri
; tmp_ri
= tmp_ri
->next
) {
946 if (tmp_ri
->peer
== bgp
->peer_self
947 && tmp_ri
->type
== ZEBRA_ROUTE_BGP
948 && tmp_ri
->sub_type
== BGP_ROUTE_STATIC
)
955 return local_ri
->attr
->default_gw
;
960 * Return true if the local ri for this rn has sticky set
962 static int evpn_route_is_sticky(struct bgp
*bgp
, struct bgp_node
*rn
)
964 struct bgp_info
*tmp_ri
;
965 struct bgp_info
*local_ri
;
968 for (tmp_ri
= rn
->info
; tmp_ri
; tmp_ri
= tmp_ri
->next
) {
969 if (tmp_ri
->peer
== bgp
->peer_self
970 && tmp_ri
->type
== ZEBRA_ROUTE_BGP
971 && tmp_ri
->sub_type
== BGP_ROUTE_STATIC
)
978 return local_ri
->attr
->sticky
;
981 static int update_evpn_type5_route_entry(struct bgp
*bgp_def
,
982 struct bgp
*bgp_vrf
, afi_t afi
,
983 safi_t safi
, struct bgp_node
*rn
,
984 struct attr
*attr
, int *route_changed
)
986 struct attr
*attr_new
= NULL
;
987 struct bgp_info
*ri
= NULL
;
988 mpls_label_t label
= MPLS_INVALID_LABEL
;
989 struct bgp_info
*local_ri
= NULL
;
990 struct bgp_info
*tmp_ri
= NULL
;
993 /* locate the local route entry if any */
994 for (tmp_ri
= rn
->info
; tmp_ri
; tmp_ri
= tmp_ri
->next
) {
995 if (tmp_ri
->peer
== bgp_def
->peer_self
996 && tmp_ri
->type
== ZEBRA_ROUTE_BGP
997 && tmp_ri
->sub_type
== BGP_ROUTE_STATIC
)
1001 /* create a new route entry if one doesnt exist.
1002 Otherwise see if route attr has changed
1006 /* route has changed as this is the first entry */
1009 /* Add (or update) attribute to hash. */
1010 attr_new
= bgp_attr_intern(attr
);
1012 /* create the route info from attribute */
1013 ri
= info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0,
1014 bgp_def
->peer_self
, attr_new
, rn
);
1015 SET_FLAG(ri
->flags
, BGP_INFO_VALID
);
1017 /* Type-5 routes advertise the L3-VNI */
1018 bgp_info_extra_get(ri
);
1019 vni2label(bgp_vrf
->l3vni
, &label
);
1020 memcpy(&ri
->extra
->label
, &label
, sizeof(label
));
1021 ri
->extra
->num_labels
= 1;
1023 /* add the route entry to route node*/
1024 bgp_info_add(rn
, ri
);
1028 if (!attrhash_cmp(tmp_ri
->attr
, attr
)) {
1030 /* attribute changed */
1033 /* The attribute has changed. */
1034 /* Add (or update) attribute to hash. */
1035 attr_new
= bgp_attr_intern(attr
);
1036 bgp_info_set_flag(rn
, tmp_ri
, BGP_INFO_ATTR_CHANGED
);
1038 /* Restore route, if needed. */
1039 if (CHECK_FLAG(tmp_ri
->flags
, BGP_INFO_REMOVED
))
1040 bgp_info_restore(rn
, tmp_ri
);
1042 /* Unintern existing, set to new. */
1043 bgp_attr_unintern(&tmp_ri
->attr
);
1044 tmp_ri
->attr
= attr_new
;
1045 tmp_ri
->uptime
= bgp_clock();
1051 /* update evpn type-5 route entry */
1052 static int update_evpn_type5_route(struct bgp
*bgp_vrf
, struct prefix_evpn
*evp
,
1053 struct attr
*src_attr
)
1055 afi_t afi
= AFI_L2VPN
;
1056 safi_t safi
= SAFI_EVPN
;
1058 struct bgp_node
*rn
= NULL
;
1059 struct bgp
*bgp_def
= NULL
;
1060 int route_changed
= 0;
1062 bgp_def
= bgp_get_default();
1066 /* Build path attribute for this route - use the source attr, if
1067 * present, else treat as locally originated.
1070 bgp_attr_dup(&attr
, src_attr
);
1072 memset(&attr
, 0, sizeof(struct attr
));
1073 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
1075 /* Set nexthop to ourselves and fill in the Router MAC. */
1076 attr
.nexthop
= bgp_vrf
->originator_ip
;
1077 attr
.mp_nexthop_global_in
= bgp_vrf
->originator_ip
;
1078 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1079 memcpy(&attr
.rmac
, &bgp_vrf
->rmac
, sizeof(struct ethaddr
));
1081 /* Setup RT and encap extended community */
1082 build_evpn_type5_route_extcomm(bgp_vrf
, &attr
);
1084 /* get the route node in global table */
1085 rn
= bgp_afi_node_get(bgp_def
->rib
[afi
][safi
], afi
, safi
,
1086 (struct prefix
*)evp
, &bgp_vrf
->vrf_prd
);
1089 /* create or update the route entry within the route node */
1090 update_evpn_type5_route_entry(bgp_def
, bgp_vrf
, afi
, safi
, rn
, &attr
,
1093 /* schedule for processing and unlock node */
1094 if (route_changed
) {
1095 bgp_process(bgp_def
, rn
, afi
, safi
);
1096 bgp_unlock_node(rn
);
1099 /* uninten temporary */
1101 aspath_unintern(&attr
.aspath
);
1106 * Create or update EVPN route entry. This could be in the VNI route table
1107 * or the global route table.
1109 static int update_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1110 afi_t afi
, safi_t safi
, struct bgp_node
*rn
,
1111 struct attr
*attr
, int add
, int vni_table
,
1112 struct bgp_info
**ri
, uint8_t flags
)
1114 struct bgp_info
*tmp_ri
;
1115 struct bgp_info
*local_ri
, *remote_ri
;
1116 struct attr
*attr_new
;
1117 mpls_label_t label
[BGP_MAX_LABELS
];
1118 uint32_t num_labels
= 1;
1119 int route_change
= 1;
1121 struct prefix_evpn
*evp
;
1124 evp
= (struct prefix_evpn
*)&rn
->p
;
1125 memset(&label
, 0, sizeof(label
));
1127 /* See if this is an update of an existing route, or a new add. Also,
1128 * identify if already known from remote, and if so, the one with the
1129 * highest sequence number; this is only when adding to the VNI routing
1132 local_ri
= remote_ri
= NULL
;
1133 for (tmp_ri
= rn
->info
; tmp_ri
; tmp_ri
= tmp_ri
->next
) {
1134 if (tmp_ri
->peer
== bgp
->peer_self
1135 && tmp_ri
->type
== ZEBRA_ROUTE_BGP
1136 && tmp_ri
->sub_type
== BGP_ROUTE_STATIC
)
1139 if (tmp_ri
->type
== ZEBRA_ROUTE_BGP
1140 && tmp_ri
->sub_type
== BGP_ROUTE_IMPORTED
1141 && CHECK_FLAG(tmp_ri
->flags
, BGP_INFO_VALID
)) {
1144 else if (mac_mobility_seqnum(tmp_ri
->attr
)
1145 > mac_mobility_seqnum(remote_ri
->attr
))
1151 /* If route doesn't exist already, create a new one, if told to.
1152 * Otherwise act based on whether the attributes of the route have
1155 if (!local_ri
&& !add
)
1159 /* When learnt locally for the first time but already known from
1160 * remote, we have to initiate appropriate MAC mobility steps.
1162 * is applicable when updating the VNI routing table.
1163 * We need to skip mobility steps for g/w macs (local mac on g/w
1164 * SVI) advertised in EVPN.
1165 * This will ensure that local routes are preferred for g/w macs
1167 if (remote_ri
&& !CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
)) {
1168 uint32_t cur_seqnum
;
1170 /* Add MM extended community to route. */
1171 cur_seqnum
= mac_mobility_seqnum(remote_ri
->attr
);
1172 add_mac_mobility_to_attr(cur_seqnum
+ 1, attr
);
1175 /* Add (or update) attribute to hash. */
1176 attr_new
= bgp_attr_intern(attr
);
1178 /* Extract MAC mobility sequence number, if any. */
1179 attr_new
->mm_seqnum
=
1180 bgp_attr_mac_mobility_seqnum(attr_new
, &sticky
);
1181 attr_new
->sticky
= sticky
;
1183 /* Create new route with its attribute. */
1184 tmp_ri
= info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0,
1185 bgp
->peer_self
, attr_new
, rn
);
1186 SET_FLAG(tmp_ri
->flags
, BGP_INFO_VALID
);
1187 bgp_info_extra_get(tmp_ri
);
1189 /* The VNI goes into the 'label' field of the route */
1190 vni2label(vpn
->vni
, &label
[0]);
1192 /* Type-2 routes may carry a second VNI - the L3-VNI.
1193 * Only attach second label if we are advertising two labels for
1196 if (evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
1197 && CHECK_FLAG(vpn
->flags
, VNI_FLAG_USE_TWO_LABELS
)) {
1200 l3vni
= bgpevpn_get_l3vni(vpn
);
1202 vni2label(l3vni
, &label
[1]);
1207 memcpy(&tmp_ri
->extra
->label
, label
, sizeof(label
));
1208 tmp_ri
->extra
->num_labels
= num_labels
;
1209 bgp_info_add(rn
, tmp_ri
);
1212 if (attrhash_cmp(tmp_ri
->attr
, attr
)
1213 && !CHECK_FLAG(tmp_ri
->flags
, BGP_INFO_REMOVED
))
1217 * The attributes have changed, type-2 routes needs to
1218 * be advertised with right labels.
1220 vni2label(vpn
->vni
, &label
[0]);
1221 if (evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
1222 && CHECK_FLAG(vpn
->flags
,
1223 VNI_FLAG_USE_TWO_LABELS
)) {
1226 l3vni
= bgpevpn_get_l3vni(vpn
);
1228 vni2label(l3vni
, &label
[1]);
1232 memcpy(&tmp_ri
->extra
->label
, label
, sizeof(label
));
1233 tmp_ri
->extra
->num_labels
= num_labels
;
1235 /* The attribute has changed. */
1236 /* Add (or update) attribute to hash. */
1237 attr_new
= bgp_attr_intern(attr
);
1238 bgp_info_set_flag(rn
, tmp_ri
, BGP_INFO_ATTR_CHANGED
);
1240 /* Restore route, if needed. */
1241 if (CHECK_FLAG(tmp_ri
->flags
, BGP_INFO_REMOVED
))
1242 bgp_info_restore(rn
, tmp_ri
);
1244 /* Unintern existing, set to new. */
1245 bgp_attr_unintern(&tmp_ri
->attr
);
1246 tmp_ri
->attr
= attr_new
;
1247 tmp_ri
->uptime
= bgp_clock();
1251 /* Return back the route entry. */
1253 return route_change
;
1257 * Create or update EVPN route (of type based on prefix) for specified VNI
1258 * and schedule for processing.
1260 static int update_evpn_route(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1261 struct prefix_evpn
*p
, uint8_t flags
)
1263 struct bgp_node
*rn
;
1265 struct attr
*attr_new
;
1266 int add_l3_ecomm
= 0;
1267 struct bgp_info
*ri
;
1268 afi_t afi
= AFI_L2VPN
;
1269 safi_t safi
= SAFI_EVPN
;
1272 memset(&attr
, 0, sizeof(struct attr
));
1274 /* Build path-attribute for this route. */
1275 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
1276 attr
.nexthop
= vpn
->originator_ip
;
1277 attr
.mp_nexthop_global_in
= vpn
->originator_ip
;
1278 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1279 attr
.sticky
= CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
) ? 1 : 0;
1280 attr
.default_gw
= CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_GW
) ? 1 : 0;
1282 /* PMSI is only needed for type-3 routes */
1283 if (p
->prefix
.route_type
== BGP_EVPN_IMET_ROUTE
)
1284 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL
);
1286 /* router mac is only needed for type-2 routes here. */
1287 if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
)
1288 bgpevpn_get_rmac(vpn
, &attr
.rmac
);
1289 vni2label(vpn
->vni
, &(attr
.label
));
1291 /* Include L3 VNI related RTs and RMAC for type-2 routes, if they're
1292 * IPv4 or IPv6 global addresses and we're advertising L3VNI with
1295 if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
&&
1296 (IS_EVPN_PREFIX_IPADDR_V4(p
) ||
1297 !IN6_IS_ADDR_LINKLOCAL(&p
->prefix
.ip
.ipaddr_v6
)) &&
1298 CHECK_FLAG(vpn
->flags
, VNI_FLAG_USE_TWO_LABELS
))
1301 /* Set up extended community. */
1302 build_evpn_route_extcomm(vpn
, &attr
, add_l3_ecomm
);
1304 /* First, create (or fetch) route node within the VNI. */
1305 /* NOTE: There is no RD here. */
1306 rn
= bgp_node_get(vpn
->route_table
, (struct prefix
*)p
);
1308 /* Create or update route entry. */
1309 route_change
= update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &attr
,
1312 attr_new
= ri
->attr
;
1314 /* Perform route selection; this is just to set the flags correctly
1315 * as local route in the VNI always wins.
1317 evpn_route_select_install(bgp
, vpn
, rn
);
1318 bgp_unlock_node(rn
);
1320 /* If this is a new route or some attribute has changed, export the
1321 * route to the global table. The route will be advertised to peers
1322 * from there. Note that this table is a 2-level tree (RD-level +
1323 * Prefix-level) similar to L3VPN routes.
1326 struct bgp_info
*global_ri
;
1328 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
1329 (struct prefix
*)p
, &vpn
->prd
);
1330 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, attr_new
, 1, 0,
1333 /* Schedule for processing and unlock node. */
1334 bgp_process(bgp
, rn
, afi
, safi
);
1335 bgp_unlock_node(rn
);
1338 /* Unintern temporary. */
1339 aspath_unintern(&attr
.aspath
);
1344 /* Delete EVPN type5 route entry from global table */
1345 static void delete_evpn_type5_route_entry(struct bgp
*bgp_def
,
1346 struct bgp
*bgp_vrf
, afi_t afi
,
1347 safi_t safi
, struct bgp_node
*rn
,
1348 struct bgp_info
**ri
)
1350 struct bgp_info
*tmp_ri
= NULL
;
1354 /* find the matching route entry */
1355 for (tmp_ri
= rn
->info
; tmp_ri
; tmp_ri
= tmp_ri
->next
)
1356 if (tmp_ri
->peer
== bgp_def
->peer_self
1357 && tmp_ri
->type
== ZEBRA_ROUTE_BGP
1358 && tmp_ri
->sub_type
== BGP_ROUTE_STATIC
)
1363 /* Mark route for delete. */
1365 bgp_info_delete(rn
, tmp_ri
);
1368 /* Delete EVPN type5 route */
1369 static int delete_evpn_type5_route(struct bgp
*bgp_vrf
, struct prefix_evpn
*evp
)
1371 afi_t afi
= AFI_L2VPN
;
1372 safi_t safi
= SAFI_EVPN
;
1373 struct bgp_node
*rn
= NULL
;
1374 struct bgp_info
*ri
= NULL
;
1375 struct bgp
*bgp_def
= NULL
; /* default bgp instance */
1377 bgp_def
= bgp_get_default();
1381 /* locate the global route entry for this type-5 prefix */
1382 rn
= bgp_afi_node_lookup(bgp_def
->rib
[afi
][safi
], afi
, safi
,
1383 (struct prefix
*)evp
, &bgp_vrf
->vrf_prd
);
1387 delete_evpn_type5_route_entry(bgp_def
, bgp_vrf
, afi
, safi
, rn
, &ri
);
1389 bgp_process(bgp_def
, rn
, afi
, safi
);
1390 bgp_unlock_node(rn
);
1395 * Delete EVPN route entry. This could be in the VNI route table
1396 * or the global route table.
1398 static void delete_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1399 afi_t afi
, safi_t safi
, struct bgp_node
*rn
,
1400 struct bgp_info
**ri
)
1402 struct bgp_info
*tmp_ri
;
1406 /* Now, find matching route. */
1407 for (tmp_ri
= rn
->info
; tmp_ri
; tmp_ri
= tmp_ri
->next
)
1408 if (tmp_ri
->peer
== bgp
->peer_self
1409 && tmp_ri
->type
== ZEBRA_ROUTE_BGP
1410 && tmp_ri
->sub_type
== BGP_ROUTE_STATIC
)
1415 /* Mark route for delete. */
1417 bgp_info_delete(rn
, tmp_ri
);
1421 * Delete EVPN route (of type based on prefix) for specified VNI and
1422 * schedule for processing.
1424 static int delete_evpn_route(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1425 struct prefix_evpn
*p
)
1427 struct bgp_node
*rn
, *global_rn
;
1428 struct bgp_info
*ri
;
1429 afi_t afi
= AFI_L2VPN
;
1430 safi_t safi
= SAFI_EVPN
;
1432 /* First, locate the route node within the VNI. If it doesn't exist,
1434 * is nothing further to do.
1436 /* NOTE: There is no RD here. */
1437 rn
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)p
);
1441 /* Next, locate route node in the global EVPN routing table. Note that
1442 * this table is a 2-level tree (RD-level + Prefix-level) similar to
1445 global_rn
= bgp_afi_node_lookup(bgp
->rib
[afi
][safi
], afi
, safi
,
1446 (struct prefix
*)p
, &vpn
->prd
);
1448 /* Delete route entry in the global EVPN table. */
1449 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, &ri
);
1451 /* Schedule for processing - withdraws to peers happen from
1455 bgp_process(bgp
, global_rn
, afi
, safi
);
1456 bgp_unlock_node(global_rn
);
1459 /* Delete route entry in the VNI route table. This can just be removed.
1461 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &ri
);
1463 bgp_info_reap(rn
, ri
);
1464 bgp_unlock_node(rn
);
1470 * Update all type-2 (MACIP) local routes for this VNI - these should also
1471 * be scheduled for advertise to peers.
1473 static int update_all_type2_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1477 struct bgp_node
*rn
;
1478 struct bgp_info
*ri
;
1480 struct attr attr_sticky
;
1481 struct attr attr_def_gw
;
1482 struct attr attr_ip6_ll
;
1483 struct attr
*attr_new
;
1484 int add_l3_ecomm
= 0;
1488 memset(&attr
, 0, sizeof(struct attr
));
1489 memset(&attr_sticky
, 0, sizeof(struct attr
));
1490 memset(&attr_def_gw
, 0, sizeof(struct attr
));
1491 memset(&attr_ip6_ll
, 0, sizeof(struct attr
));
1493 /* Build path-attribute - multiple type-2 routes for this VNI will share
1494 * the same path attribute, but we need separate structures for sticky
1495 * MACs, default gateway and IPv6 link-local addresses (no L3 RT/RMAC).
1497 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
1498 bgp_attr_default_set(&attr_sticky
, BGP_ORIGIN_IGP
);
1499 bgp_attr_default_set(&attr_def_gw
, BGP_ORIGIN_IGP
);
1500 attr
.nexthop
= vpn
->originator_ip
;
1501 attr
.mp_nexthop_global_in
= vpn
->originator_ip
;
1502 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1503 bgpevpn_get_rmac(vpn
, &attr
.rmac
);
1504 attr_sticky
.nexthop
= vpn
->originator_ip
;
1505 attr_sticky
.mp_nexthop_global_in
= vpn
->originator_ip
;
1506 attr_sticky
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1507 attr_sticky
.sticky
= 1;
1508 bgpevpn_get_rmac(vpn
, &attr_sticky
.rmac
);
1509 attr_def_gw
.nexthop
= vpn
->originator_ip
;
1510 attr_def_gw
.mp_nexthop_global_in
= vpn
->originator_ip
;
1511 attr_def_gw
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1512 attr_def_gw
.default_gw
= 1;
1513 bgpevpn_get_rmac(vpn
, &attr_def_gw
.rmac
);
1514 bgp_attr_default_set(&attr_ip6_ll
, BGP_ORIGIN_IGP
);
1515 attr_ip6_ll
.nexthop
= vpn
->originator_ip
;
1516 attr_ip6_ll
.mp_nexthop_global_in
= vpn
->originator_ip
;
1517 attr_ip6_ll
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
1519 /* Add L3 VNI RTs and RMAC for non IPv6 link-local attributes if
1520 * using L3 VNI for type-2 routes also.
1522 if (CHECK_FLAG(vpn
->flags
, VNI_FLAG_USE_TWO_LABELS
))
1525 build_evpn_route_extcomm(vpn
, &attr
, add_l3_ecomm
);
1526 build_evpn_route_extcomm(vpn
, &attr_sticky
, add_l3_ecomm
);
1527 build_evpn_route_extcomm(vpn
, &attr_def_gw
, add_l3_ecomm
);
1528 build_evpn_route_extcomm(vpn
, &attr_ip6_ll
, 0);
1530 /* Walk this VNI's route table and update local type-2 routes. For any
1531 * routes updated, update corresponding entry in the global table too.
1533 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
1534 rn
= bgp_route_next(rn
)) {
1535 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
1536 struct bgp_node
*rd_rn
;
1537 struct bgp_info
*global_ri
;
1539 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
1542 if (IS_EVPN_PREFIX_IPADDR_V6(evp
) &&
1543 IN6_IS_ADDR_LINKLOCAL(&evp
->prefix
.ip
.ipaddr_v6
))
1544 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
,
1545 &attr_ip6_ll
, 0, 1, &ri
, 0);
1547 if (evpn_route_is_sticky(bgp
, rn
))
1548 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
,
1549 &attr_sticky
, 0, 1, &ri
,
1551 else if (evpn_route_is_def_gw(bgp
, rn
))
1552 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
,
1553 &attr_def_gw
, 0, 1, &ri
,
1556 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
,
1557 &attr
, 0, 1, &ri
, 0);
1560 /* If a local route exists for this prefix, we need to update
1561 * the global routing table too.
1566 /* Perform route selection; this is just to set the flags
1568 * as local route in the VNI always wins.
1570 evpn_route_select_install(bgp
, vpn
, rn
);
1572 attr_new
= ri
->attr
;
1574 /* Update route in global routing table. */
1575 rd_rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
1576 (struct prefix
*)evp
, &vpn
->prd
);
1578 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rd_rn
, attr_new
, 0,
1581 /* Schedule for processing and unlock node. */
1582 bgp_process(bgp
, rd_rn
, afi
, safi
);
1583 bgp_unlock_node(rd_rn
);
1586 /* Unintern temporary. */
1587 aspath_unintern(&attr
.aspath
);
1588 aspath_unintern(&attr_sticky
.aspath
);
1589 aspath_unintern(&attr_def_gw
.aspath
);
1590 aspath_unintern(&attr_ip6_ll
.aspath
);
1596 * Delete all type-2 (MACIP) local routes for this VNI - only from the
1597 * global routing table. These are also scheduled for withdraw from peers.
1599 static int delete_global_type2_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1603 struct bgp_node
*rdrn
, *rn
;
1604 struct bgp_table
*table
;
1605 struct bgp_info
*ri
;
1610 rdrn
= bgp_node_lookup(bgp
->rib
[afi
][safi
], (struct prefix
*)&vpn
->prd
);
1611 if (rdrn
&& rdrn
->info
) {
1612 table
= (struct bgp_table
*)rdrn
->info
;
1613 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
1614 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
1616 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
1619 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &ri
);
1621 bgp_process(bgp
, rn
, afi
, safi
);
1625 /* Unlock RD node. */
1627 bgp_unlock_node(rdrn
);
1633 * Delete all type-2 (MACIP) local routes for this VNI - from the global
1634 * table as well as the per-VNI route table.
1636 static int delete_all_type2_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1640 struct bgp_node
*rn
;
1641 struct bgp_info
*ri
;
1646 /* First, walk the global route table for this VNI's type-2 local
1648 * EVPN routes are a 2-level table, first get the RD table.
1650 delete_global_type2_routes(bgp
, vpn
);
1652 /* Next, walk this VNI's route table and delete local type-2 routes. */
1653 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
1654 rn
= bgp_route_next(rn
)) {
1655 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
1657 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
1660 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &ri
);
1662 /* Route entry in local table gets deleted immediately. */
1664 bgp_info_reap(rn
, ri
);
1671 * Delete all routes in the per-VNI route table.
1673 static int delete_all_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1675 struct bgp_node
*rn
;
1676 struct bgp_info
*ri
, *nextri
;
1678 /* Walk this VNI's route table and delete all routes. */
1679 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
1680 rn
= bgp_route_next(rn
)) {
1681 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1);
1683 bgp_info_delete(rn
, ri
);
1684 bgp_info_reap(rn
, ri
);
1692 * Update (and advertise) local routes for a VNI. Invoked upon the VNI
1693 * export RT getting modified or change to tunnel IP. Note that these
1694 * situations need the route in the per-VNI table as well as the global
1695 * table to be updated (as attributes change).
1697 static int update_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1700 struct prefix_evpn p
;
1702 /* Update and advertise the type-3 route (only one) followed by the
1703 * locally learnt type-2 routes (MACIP) - for this VNI.
1705 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
1706 ret
= update_evpn_route(bgp
, vpn
, &p
, 0);
1710 return update_all_type2_routes(bgp
, vpn
);
1714 * Delete (and withdraw) local routes for specified VNI from the global
1715 * table and per-VNI table. After this, remove all other routes from
1716 * the per-VNI table. Invoked upon the VNI being deleted or EVPN
1717 * (advertise-all-vni) being disabled.
1719 static int delete_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1722 struct prefix_evpn p
;
1724 /* Delete and withdraw locally learnt type-2 routes (MACIP)
1725 * followed by type-3 routes (only one) - for this VNI.
1727 ret
= delete_all_type2_routes(bgp
, vpn
);
1731 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
1732 ret
= delete_evpn_route(bgp
, vpn
, &p
);
1736 /* Delete all routes from the per-VNI table. */
1737 return delete_all_vni_routes(bgp
, vpn
);
1741 * There is a tunnel endpoint IP address change for this VNI, delete
1742 * prior type-3 route (if needed) and update.
1743 * Note: Route re-advertisement happens elsewhere after other processing
1746 static int handle_tunnel_ip_change(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1747 struct in_addr originator_ip
)
1749 struct prefix_evpn p
;
1751 /* If VNI is not live, we only need to update the originator ip */
1752 if (!is_vni_live(vpn
)) {
1753 vpn
->originator_ip
= originator_ip
;
1757 /* Update the tunnel-ip hash */
1758 bgp_tip_del(bgp
, &vpn
->originator_ip
);
1759 bgp_tip_add(bgp
, &originator_ip
);
1761 /* filter routes as martian nexthop db has changed */
1762 bgp_filter_evpn_routes_upon_martian_nh_change(bgp
);
1764 /* Need to withdraw type-3 route as the originator IP is part
1767 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
1768 delete_evpn_route(bgp
, vpn
, &p
);
1770 /* Update the tunnel IP and re-advertise all routes for this VNI. */
1771 vpn
->originator_ip
= originator_ip
;
1776 * Install route entry into the VRF routing table and invoke route selection.
1778 static int install_evpn_route_entry_in_vrf(struct bgp
*bgp_vrf
,
1779 struct prefix_evpn
*evp
,
1780 struct bgp_info
*parent_ri
)
1782 struct bgp_node
*rn
;
1783 struct bgp_info
*ri
;
1785 struct attr
*attr_new
;
1788 struct prefix
*pp
= &p
;
1791 char buf
[PREFIX_STRLEN
];
1792 char buf1
[PREFIX_STRLEN
];
1794 memset(pp
, 0, sizeof(struct prefix
));
1795 if (evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
)
1796 ip_prefix_from_type2_prefix(evp
, pp
);
1797 else if (evp
->prefix
.route_type
== BGP_EVPN_IP_PREFIX_ROUTE
)
1798 ip_prefix_from_type5_prefix(evp
, pp
);
1800 if (bgp_debug_zebra(NULL
)) {
1802 "installing evpn prefix %s as ip prefix %s in vrf %s",
1803 prefix2str(evp
, buf
, sizeof(buf
)),
1804 prefix2str(pp
, buf1
, sizeof(buf
)),
1805 vrf_id_to_name(bgp_vrf
->vrf_id
));
1808 /* Create (or fetch) route within the VRF. */
1809 /* NOTE: There is no RD here. */
1810 if (IS_EVPN_PREFIX_IPADDR_V4(evp
)) {
1812 safi
= SAFI_UNICAST
;
1813 rn
= bgp_node_get(bgp_vrf
->rib
[afi
][safi
], pp
);
1814 } else if (IS_EVPN_PREFIX_IPADDR_V6(evp
)) {
1816 safi
= SAFI_UNICAST
;
1817 rn
= bgp_node_get(bgp_vrf
->rib
[afi
][safi
], pp
);
1821 /* EVPN routes currently only support a IPv4 next hop which corresponds
1822 * to the remote VTEP. When importing into a VRF, if it is IPv6 host
1823 * route, we have to convert the next hop to an IPv4-mapped address
1824 * for the rest of the code to flow through.
1826 bgp_attr_dup(&attr
, parent_ri
->attr
);
1828 evpn_convert_nexthop_to_ipv6(&attr
);
1830 /* Check if route entry is already present. */
1831 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1833 && (struct bgp_info
*)ri
->extra
->parent
== parent_ri
)
1837 /* Add (or update) attribute to hash. */
1838 attr_new
= bgp_attr_intern(&attr
);
1840 /* Create new route with its attribute. */
1841 ri
= info_make(parent_ri
->type
, BGP_ROUTE_IMPORTED
, 0,
1842 parent_ri
->peer
, attr_new
, rn
);
1843 SET_FLAG(ri
->flags
, BGP_INFO_VALID
);
1844 bgp_info_extra_get(ri
);
1845 ri
->extra
->parent
= parent_ri
;
1846 if (parent_ri
->extra
) {
1847 memcpy(&ri
->extra
->label
, &parent_ri
->extra
->label
,
1848 sizeof(ri
->extra
->label
));
1849 ri
->extra
->num_labels
= parent_ri
->extra
->num_labels
;
1851 bgp_info_add(rn
, ri
);
1853 if (attrhash_cmp(ri
->attr
, &attr
)
1854 && !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
1855 bgp_unlock_node(rn
);
1858 /* The attribute has changed. */
1859 /* Add (or update) attribute to hash. */
1860 attr_new
= bgp_attr_intern(&attr
);
1862 /* Restore route, if needed. */
1863 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
1864 bgp_info_restore(rn
, ri
);
1866 /* Mark if nexthop has changed. */
1867 if ((afi
== AFI_IP
&&
1868 !IPV4_ADDR_SAME(&ri
->attr
->nexthop
, &attr_new
->nexthop
)) ||
1870 !IPV6_ADDR_SAME(&ri
->attr
->mp_nexthop_global
,
1871 &attr_new
->mp_nexthop_global
)))
1872 SET_FLAG(ri
->flags
, BGP_INFO_IGP_CHANGED
);
1874 /* Unintern existing, set to new. */
1875 bgp_attr_unintern(&ri
->attr
);
1876 ri
->attr
= attr_new
;
1877 ri
->uptime
= bgp_clock();
1880 /* Perform route selection and update zebra, if required. */
1881 bgp_process(bgp_vrf
, rn
, afi
, safi
);
1887 * Install route entry into the VNI routing table and invoke route selection.
1889 static int install_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1890 struct prefix_evpn
*p
,
1891 struct bgp_info
*parent_ri
)
1893 struct bgp_node
*rn
;
1894 struct bgp_info
*ri
;
1895 struct attr
*attr_new
;
1898 /* Create (or fetch) route within the VNI. */
1899 /* NOTE: There is no RD here. */
1900 rn
= bgp_node_get(vpn
->route_table
, (struct prefix
*)p
);
1902 /* Check if route entry is already present. */
1903 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1905 && (struct bgp_info
*)ri
->extra
->parent
== parent_ri
)
1909 /* Add (or update) attribute to hash. */
1910 attr_new
= bgp_attr_intern(parent_ri
->attr
);
1912 /* Create new route with its attribute. */
1913 ri
= info_make(parent_ri
->type
, BGP_ROUTE_IMPORTED
, 0,
1914 parent_ri
->peer
, attr_new
, rn
);
1915 SET_FLAG(ri
->flags
, BGP_INFO_VALID
);
1916 bgp_info_extra_get(ri
);
1917 ri
->extra
->parent
= parent_ri
;
1918 if (parent_ri
->extra
) {
1919 memcpy(&ri
->extra
->label
, &parent_ri
->extra
->label
,
1920 sizeof(ri
->extra
->label
));
1921 ri
->extra
->num_labels
= parent_ri
->extra
->num_labels
;
1923 bgp_info_add(rn
, ri
);
1925 if (attrhash_cmp(ri
->attr
, parent_ri
->attr
)
1926 && !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
1927 bgp_unlock_node(rn
);
1930 /* The attribute has changed. */
1931 /* Add (or update) attribute to hash. */
1932 attr_new
= bgp_attr_intern(parent_ri
->attr
);
1934 /* Restore route, if needed. */
1935 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
1936 bgp_info_restore(rn
, ri
);
1938 /* Mark if nexthop has changed. */
1939 if (!IPV4_ADDR_SAME(&ri
->attr
->nexthop
, &attr_new
->nexthop
))
1940 SET_FLAG(ri
->flags
, BGP_INFO_IGP_CHANGED
);
1942 /* Unintern existing, set to new. */
1943 bgp_attr_unintern(&ri
->attr
);
1944 ri
->attr
= attr_new
;
1945 ri
->uptime
= bgp_clock();
1948 /* Perform route selection and update zebra, if required. */
1949 ret
= evpn_route_select_install(bgp
, vpn
, rn
);
1955 * Uninstall route entry from the VRF routing table and send message
1956 * to zebra, if appropriate.
1958 static int uninstall_evpn_route_entry_in_vrf(struct bgp
*bgp_vrf
,
1959 struct prefix_evpn
*evp
,
1960 struct bgp_info
*parent_ri
)
1962 struct bgp_node
*rn
;
1963 struct bgp_info
*ri
;
1966 struct prefix
*pp
= &p
;
1969 char buf
[PREFIX_STRLEN
];
1970 char buf1
[PREFIX_STRLEN
];
1972 memset(pp
, 0, sizeof(struct prefix
));
1973 if (evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
)
1974 ip_prefix_from_type2_prefix(evp
, pp
);
1975 else if (evp
->prefix
.route_type
== BGP_EVPN_IP_PREFIX_ROUTE
)
1976 ip_prefix_from_type5_prefix(evp
, pp
);
1978 if (bgp_debug_zebra(NULL
)) {
1980 "uninstalling evpn prefix %s as ip prefix %s in vrf %s",
1981 prefix2str(evp
, buf
, sizeof(buf
)),
1982 prefix2str(pp
, buf1
, sizeof(buf
)),
1983 vrf_id_to_name(bgp_vrf
->vrf_id
));
1986 /* Locate route within the VRF. */
1987 /* NOTE: There is no RD here. */
1988 if (IS_EVPN_PREFIX_IPADDR_V4(evp
)) {
1990 safi
= SAFI_UNICAST
;
1991 rn
= bgp_node_lookup(bgp_vrf
->rib
[afi
][safi
], pp
);
1994 safi
= SAFI_UNICAST
;
1995 rn
= bgp_node_lookup(bgp_vrf
->rib
[afi
][safi
], pp
);
2001 /* Find matching route entry. */
2002 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2004 && (struct bgp_info
*)ri
->extra
->parent
== parent_ri
)
2010 /* Mark entry for deletion */
2011 bgp_info_delete(rn
, ri
);
2013 /* Perform route selection and update zebra, if required. */
2014 bgp_process(bgp_vrf
, rn
, afi
, safi
);
2016 /* Unlock route node. */
2017 bgp_unlock_node(rn
);
2023 * Uninstall route entry from the VNI routing table and send message
2024 * to zebra, if appropriate.
2026 static int uninstall_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
2027 struct prefix_evpn
*p
,
2028 struct bgp_info
*parent_ri
)
2030 struct bgp_node
*rn
;
2031 struct bgp_info
*ri
;
2034 /* Locate route within the VNI. */
2035 /* NOTE: There is no RD here. */
2036 rn
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)p
);
2040 /* Find matching route entry. */
2041 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2043 && (struct bgp_info
*)ri
->extra
->parent
== parent_ri
)
2049 /* Mark entry for deletion */
2050 bgp_info_delete(rn
, ri
);
2052 /* Perform route selection and update zebra, if required. */
2053 ret
= evpn_route_select_install(bgp
, vpn
, rn
);
2055 /* Unlock route node. */
2056 bgp_unlock_node(rn
);
2062 * Given a route entry and a VRF, see if this route entry should be
2063 * imported into the VRF i.e., RTs match.
2065 static int is_route_matching_for_vrf(struct bgp
*bgp_vrf
, struct bgp_info
*ri
)
2067 struct attr
*attr
= ri
->attr
;
2068 struct ecommunity
*ecom
;
2072 /* Route should have valid RT to be even considered. */
2073 if (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)))
2076 ecom
= attr
->ecommunity
;
2077 if (!ecom
|| !ecom
->size
)
2080 /* For each extended community RT, see if it matches this VNI. If any RT
2081 * matches, we're done.
2083 for (i
= 0; i
< ecom
->size
; i
++) {
2085 uint8_t type
, sub_type
;
2086 struct ecommunity_val
*eval
;
2087 struct ecommunity_val eval_tmp
;
2088 struct vrf_irt_node
*irt
;
2090 /* Only deal with RTs */
2091 pnt
= (ecom
->val
+ (i
* ECOMMUNITY_SIZE
));
2092 eval
= (struct ecommunity_val
*)(ecom
->val
2093 + (i
* ECOMMUNITY_SIZE
));
2096 if (sub_type
!= ECOMMUNITY_ROUTE_TARGET
)
2099 /* See if this RT matches specified VNIs import RTs */
2100 irt
= lookup_vrf_import_rt(eval
);
2101 if (irt
&& irt
->vrfs
)
2102 if (is_vrf_present_in_irt_vrfs(irt
->vrfs
, bgp_vrf
))
2105 /* Also check for non-exact match. In this, we mask out the AS
2107 * only check on the local-admin sub-field. This is to
2109 * VNI as the RT for EBGP peering too.
2112 if (type
== ECOMMUNITY_ENCODE_AS
2113 || type
== ECOMMUNITY_ENCODE_AS4
2114 || type
== ECOMMUNITY_ENCODE_IP
) {
2115 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
2116 mask_ecom_global_admin(&eval_tmp
, eval
);
2117 irt
= lookup_vrf_import_rt(&eval_tmp
);
2119 if (irt
&& irt
->vrfs
)
2120 if (is_vrf_present_in_irt_vrfs(irt
->vrfs
, bgp_vrf
))
2128 * Given a route entry and a VNI, see if this route entry should be
2129 * imported into the VNI i.e., RTs match.
2131 static int is_route_matching_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
,
2132 struct bgp_info
*ri
)
2134 struct attr
*attr
= ri
->attr
;
2135 struct ecommunity
*ecom
;
2139 /* Route should have valid RT to be even considered. */
2140 if (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)))
2143 ecom
= attr
->ecommunity
;
2144 if (!ecom
|| !ecom
->size
)
2147 /* For each extended community RT, see if it matches this VNI. If any RT
2148 * matches, we're done.
2150 for (i
= 0; i
< ecom
->size
; i
++) {
2152 uint8_t type
, sub_type
;
2153 struct ecommunity_val
*eval
;
2154 struct ecommunity_val eval_tmp
;
2155 struct irt_node
*irt
;
2157 /* Only deal with RTs */
2158 pnt
= (ecom
->val
+ (i
* ECOMMUNITY_SIZE
));
2159 eval
= (struct ecommunity_val
*)(ecom
->val
2160 + (i
* ECOMMUNITY_SIZE
));
2163 if (sub_type
!= ECOMMUNITY_ROUTE_TARGET
)
2166 /* See if this RT matches specified VNIs import RTs */
2167 irt
= lookup_import_rt(bgp
, eval
);
2168 if (irt
&& irt
->vnis
)
2169 if (is_vni_present_in_irt_vnis(irt
->vnis
, vpn
))
2172 /* Also check for non-exact match. In this, we mask out the AS
2174 * only check on the local-admin sub-field. This is to
2176 * VNI as the RT for EBGP peering too.
2179 if (type
== ECOMMUNITY_ENCODE_AS
2180 || type
== ECOMMUNITY_ENCODE_AS4
2181 || type
== ECOMMUNITY_ENCODE_IP
) {
2182 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
2183 mask_ecom_global_admin(&eval_tmp
, eval
);
2184 irt
= lookup_import_rt(bgp
, &eval_tmp
);
2186 if (irt
&& irt
->vnis
)
2187 if (is_vni_present_in_irt_vnis(irt
->vnis
, vpn
))
2195 * Install or uninstall mac-ip routes are appropriate for this
2198 static int install_uninstall_routes_for_vrf(struct bgp
*bgp_vrf
, int install
)
2202 struct bgp_node
*rd_rn
, *rn
;
2203 struct bgp_table
*table
;
2204 struct bgp_info
*ri
;
2206 char buf
[PREFIX_STRLEN
];
2207 struct bgp
*bgp_def
= NULL
;
2211 bgp_def
= bgp_get_default();
2215 /* Walk entire global routing table and evaluate routes which could be
2216 * imported into this VRF. Note that we need to loop through all global
2217 * routes to determine which route matches the import rt on vrf
2219 for (rd_rn
= bgp_table_top(bgp_def
->rib
[afi
][safi
]); rd_rn
;
2220 rd_rn
= bgp_route_next(rd_rn
)) {
2221 table
= (struct bgp_table
*)(rd_rn
->info
);
2225 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
2226 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
2228 /* if not mac-ip route skip this route */
2229 if (!(evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
2230 || evp
->prefix
.route_type
2231 == BGP_EVPN_IP_PREFIX_ROUTE
))
2234 /* if not a mac+ip route skip this route */
2235 if (!(IS_EVPN_PREFIX_IPADDR_V4(evp
)
2236 || IS_EVPN_PREFIX_IPADDR_V6(evp
)))
2239 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
2240 /* Consider "valid" remote routes applicable for
2243 if (!(CHECK_FLAG(ri
->flags
, BGP_INFO_VALID
)
2244 && ri
->type
== ZEBRA_ROUTE_BGP
2245 && ri
->sub_type
== BGP_ROUTE_NORMAL
))
2248 if (is_route_matching_for_vrf(bgp_vrf
, ri
)) {
2250 ret
= install_evpn_route_entry_in_vrf(
2253 ret
= uninstall_evpn_route_entry_in_vrf(
2258 "Failed to %s EVPN %s route in VRF %s",
2261 prefix2str(evp
, buf
,
2276 * Install or uninstall routes of specified type that are appropriate for this
2279 static int install_uninstall_routes_for_vni(struct bgp
*bgp
,
2280 struct bgpevpn
*vpn
,
2281 bgp_evpn_route_type rtype
,
2286 struct bgp_node
*rd_rn
, *rn
;
2287 struct bgp_table
*table
;
2288 struct bgp_info
*ri
;
2294 /* Walk entire global routing table and evaluate routes which could be
2295 * imported into this VPN. Note that we cannot just look at the routes
2297 * the VNI's RD - remote routes applicable for this VNI could have any
2300 /* EVPN routes are a 2-level table. */
2301 for (rd_rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rd_rn
;
2302 rd_rn
= bgp_route_next(rd_rn
)) {
2303 table
= (struct bgp_table
*)(rd_rn
->info
);
2307 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
2308 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
2310 if (evp
->prefix
.route_type
!= rtype
)
2313 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
2314 /* Consider "valid" remote routes applicable for
2316 if (!(CHECK_FLAG(ri
->flags
, BGP_INFO_VALID
)
2317 && ri
->type
== ZEBRA_ROUTE_BGP
2318 && ri
->sub_type
== BGP_ROUTE_NORMAL
))
2321 if (is_route_matching_for_vni(bgp
, vpn
, ri
)) {
2323 ret
= install_evpn_route_entry(
2326 ret
= uninstall_evpn_route_entry(
2331 "%u: Failed to %s EVPN %s route in VNI %u",
2335 rtype
== BGP_EVPN_MAC_IP_ROUTE
2349 /* Install any existing remote routes applicable for this VRF into VRF RIB. This
2350 * is invoked upon l3vni-add or l3vni import rt change
2352 static int install_routes_for_vrf(struct bgp
*bgp_vrf
)
2354 install_uninstall_routes_for_vrf(bgp_vrf
, 1);
2359 * Install any existing remote routes applicable for this VNI into its
2360 * routing table. This is invoked when a VNI becomes "live" or its Import
2363 static int install_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2367 /* Install type-3 routes followed by type-2 routes - the ones applicable
2370 ret
= install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_IMET_ROUTE
,
2375 return install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_MAC_IP_ROUTE
,
2379 /* uninstall routes from l3vni vrf. */
2380 static int uninstall_routes_for_vrf(struct bgp
*bgp_vrf
)
2382 install_uninstall_routes_for_vrf(bgp_vrf
, 0);
2387 * Uninstall any existing remote routes for this VNI. One scenario in which
2388 * this is invoked is upon an import RT change.
2390 static int uninstall_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2394 /* Uninstall type-2 routes followed by type-3 routes - the ones
2398 ret
= install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_MAC_IP_ROUTE
,
2403 return install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_IMET_ROUTE
,
2408 * Install or uninstall route in matching VRFs (list).
2410 static int install_uninstall_route_in_vrfs(struct bgp
*bgp_def
, afi_t afi
,
2411 safi_t safi
, struct prefix_evpn
*evp
,
2412 struct bgp_info
*ri
,
2413 struct list
*vrfs
, int install
)
2415 char buf
[PREFIX2STR_BUFFER
];
2416 struct bgp
*bgp_vrf
;
2417 struct listnode
*node
, *nnode
;
2419 /* Only type-2/type-5 routes go into a VRF */
2420 if (!(evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
2421 || evp
->prefix
.route_type
== BGP_EVPN_IP_PREFIX_ROUTE
))
2424 /* if it is type-2 route and not a mac+ip route skip this route */
2425 if ((evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
)
2426 && !(IS_EVPN_PREFIX_IPADDR_V4(evp
)
2427 || IS_EVPN_PREFIX_IPADDR_V6(evp
)))
2430 for (ALL_LIST_ELEMENTS(vrfs
, node
, nnode
, bgp_vrf
)) {
2434 ret
= install_evpn_route_entry_in_vrf(bgp_vrf
, evp
, ri
);
2436 ret
= uninstall_evpn_route_entry_in_vrf(bgp_vrf
, evp
,
2440 zlog_err("%u: Failed to %s prefix %s in VRF %s",
2442 install
? "install" : "uninstall",
2443 prefix2str(evp
, buf
, sizeof(buf
)),
2444 vrf_id_to_name(bgp_vrf
->vrf_id
));
2453 * Install or uninstall route in matching VNIs (list).
2455 static int install_uninstall_route_in_vnis(struct bgp
*bgp
, afi_t afi
,
2456 safi_t safi
, struct prefix_evpn
*evp
,
2457 struct bgp_info
*ri
,
2458 struct list
*vnis
, int install
)
2460 struct bgpevpn
*vpn
;
2461 struct listnode
*node
, *nnode
;
2463 for (ALL_LIST_ELEMENTS(vnis
, node
, nnode
, vpn
)) {
2466 if (!is_vni_live(vpn
))
2470 ret
= install_evpn_route_entry(bgp
, vpn
, evp
, ri
);
2472 ret
= uninstall_evpn_route_entry(bgp
, vpn
, evp
, ri
);
2475 zlog_err("%u: Failed to %s EVPN %s route in VNI %u",
2476 bgp
->vrf_id
, install
? "install" : "uninstall",
2477 evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
2489 * Install or uninstall route for appropriate VNIs.
2491 static int install_uninstall_evpn_route(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
2492 struct prefix
*p
, struct bgp_info
*ri
,
2495 struct prefix_evpn
*evp
= (struct prefix_evpn
*)p
;
2496 struct attr
*attr
= ri
->attr
;
2497 struct ecommunity
*ecom
;
2502 /* Only type-2 and type-3 and type-5 are supported currently */
2503 if (!(evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
2504 || evp
->prefix
.route_type
== BGP_EVPN_IMET_ROUTE
2505 || evp
->prefix
.route_type
== BGP_EVPN_IP_PREFIX_ROUTE
))
2508 /* If we don't have Route Target, nothing much to do. */
2509 if (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)))
2512 ecom
= attr
->ecommunity
;
2513 if (!ecom
|| !ecom
->size
)
2516 /* For each extended community RT, see which VNIs/VRFs match and import
2517 * the route into matching VNIs/VRFs.
2519 for (i
= 0; i
< ecom
->size
; i
++) {
2521 uint8_t type
, sub_type
;
2522 struct ecommunity_val
*eval
;
2523 struct ecommunity_val eval_tmp
;
2524 struct irt_node
*irt
; /* import rt for l2vni */
2525 struct vrf_irt_node
*vrf_irt
; /* import rt for l3vni */
2527 /* Only deal with RTs */
2528 pnt
= (ecom
->val
+ (i
* ECOMMUNITY_SIZE
));
2529 eval
= (struct ecommunity_val
*)(ecom
->val
2530 + (i
* ECOMMUNITY_SIZE
));
2533 if (sub_type
!= ECOMMUNITY_ROUTE_TARGET
)
2536 /* Import route into matching l2-vnis (type-2/type-3 routes go
2539 irt
= lookup_import_rt(bgp
, eval
);
2540 if (irt
&& irt
->vnis
)
2541 install_uninstall_route_in_vnis(bgp
, afi
, safi
, evp
, ri
,
2544 /* Import route into matching l3-vnis (type-2/type-5 routes go
2545 * into l3vni/vrf table)
2547 vrf_irt
= lookup_vrf_import_rt(eval
);
2548 if (vrf_irt
&& vrf_irt
->vrfs
)
2549 install_uninstall_route_in_vrfs(bgp
, afi
, safi
, evp
, ri
,
2550 vrf_irt
->vrfs
, import
);
2552 /* Also check for non-exact match. In this,
2553 * we mask out the AS and
2554 * only check on the local-admin sub-field.
2555 * This is to facilitate using
2556 * VNI as the RT for EBGP peering too.
2560 if (type
== ECOMMUNITY_ENCODE_AS
2561 || type
== ECOMMUNITY_ENCODE_AS4
2562 || type
== ECOMMUNITY_ENCODE_IP
) {
2563 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
2564 mask_ecom_global_admin(&eval_tmp
, eval
);
2565 irt
= lookup_import_rt(bgp
, &eval_tmp
);
2566 vrf_irt
= lookup_vrf_import_rt(&eval_tmp
);
2568 if (irt
&& irt
->vnis
)
2569 install_uninstall_route_in_vnis(bgp
, afi
, safi
, evp
, ri
,
2571 if (vrf_irt
&& vrf_irt
->vrfs
)
2572 install_uninstall_route_in_vrfs(bgp
, afi
, safi
, evp
, ri
,
2573 vrf_irt
->vrfs
, import
);
2579 /* delete and withdraw all ipv4 and ipv6 routes in the vrf table as type-5
2581 static void delete_withdraw_vrf_routes(struct bgp
*bgp_vrf
)
2583 /* delete all ipv4 routes and withdraw from peers */
2584 if (advertise_type5_routes(bgp_vrf
, AFI_IP
))
2585 bgp_evpn_withdraw_type5_routes(bgp_vrf
, AFI_IP
, SAFI_UNICAST
);
2587 /* delete all ipv6 routes and withdraw from peers */
2588 if (advertise_type5_routes(bgp_vrf
, AFI_IP6
))
2589 bgp_evpn_withdraw_type5_routes(bgp_vrf
, AFI_IP6
, SAFI_UNICAST
);
2592 /* update and advertise all ipv4 and ipv6 routes in thr vrf table as type-5
2594 static void update_advertise_vrf_routes(struct bgp
*bgp_vrf
)
2596 /* update all ipv4 routes */
2597 if (advertise_type5_routes(bgp_vrf
, AFI_IP
))
2598 bgp_evpn_advertise_type5_routes(bgp_vrf
, AFI_IP
, SAFI_UNICAST
);
2600 /* update all ipv6 routes */
2601 if (advertise_type5_routes(bgp_vrf
, AFI_IP6
))
2602 bgp_evpn_advertise_type5_routes(bgp_vrf
, AFI_IP6
, SAFI_UNICAST
);
2606 * update and advertise local routes for a VRF as type-5 routes.
2607 * This is invoked upon RD change for a VRF. Note taht the processing is only
2608 * done in the global route table using the routes which already exist in the
2611 static void update_router_id_vrf(struct bgp
*bgp_vrf
)
2613 /* skip if the RD is configured */
2614 if (is_vrf_rd_configured(bgp_vrf
))
2617 /* derive the RD for the VRF based on new router-id */
2618 bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf
);
2620 /* update advertise ipv4|ipv6 routes as type-5 routes */
2621 update_advertise_vrf_routes(bgp_vrf
);
2625 * Delete and withdraw all type-5 routes for the RD corresponding to VRF.
2626 * This is invoked upon VRF RD change. The processing is done only from global
2629 static void withdraw_router_id_vrf(struct bgp
*bgp_vrf
)
2631 /* skip if the RD is configured */
2632 if (is_vrf_rd_configured(bgp_vrf
))
2635 /* delete/withdraw ipv4|ipv6 routes as type-5 routes */
2636 delete_withdraw_vrf_routes(bgp_vrf
);
2640 * Update and advertise local routes for a VNI. Invoked upon router-id
2641 * change. Note that the processing is done only on the global route table
2642 * using routes that already exist in the per-VNI table.
2644 static int update_advertise_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2646 struct prefix_evpn p
;
2647 struct bgp_node
*rn
, *global_rn
;
2648 struct bgp_info
*ri
, *global_ri
;
2650 afi_t afi
= AFI_L2VPN
;
2651 safi_t safi
= SAFI_EVPN
;
2653 /* Locate type-3 route for VNI in the per-VNI table and use its
2654 * attributes to create and advertise the type-3 route for this VNI
2655 * in the global table.
2657 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
2658 rn
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)&p
);
2659 if (!rn
) /* unexpected */
2661 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2662 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
2663 && ri
->sub_type
== BGP_ROUTE_STATIC
)
2665 if (!ri
) /* unexpected */
2669 global_rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
2670 (struct prefix
*)&p
, &vpn
->prd
);
2671 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, attr
, 1, 0, &ri
,
2674 /* Schedule for processing and unlock node. */
2675 bgp_process(bgp
, global_rn
, afi
, safi
);
2676 bgp_unlock_node(global_rn
);
2678 /* Now, walk this VNI's route table and use the route and its attribute
2679 * to create and schedule route in global table.
2681 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
2682 rn
= bgp_route_next(rn
)) {
2683 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
2685 /* Identify MAC-IP local routes. */
2686 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
2689 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2690 if (ri
->peer
== bgp
->peer_self
2691 && ri
->type
== ZEBRA_ROUTE_BGP
2692 && ri
->sub_type
== BGP_ROUTE_STATIC
)
2697 /* Create route in global routing table using this route entry's
2701 global_rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
2702 (struct prefix
*)evp
, &vpn
->prd
);
2704 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, attr
, 1,
2707 /* Schedule for processing and unlock node. */
2708 bgp_process(bgp
, global_rn
, afi
, safi
);
2709 bgp_unlock_node(global_rn
);
2716 * Delete (and withdraw) local routes for a VNI - only from the global
2717 * table. Invoked upon router-id change.
2719 static int delete_withdraw_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2722 struct prefix_evpn p
;
2723 struct bgp_node
*global_rn
;
2724 struct bgp_info
*ri
;
2725 afi_t afi
= AFI_L2VPN
;
2726 safi_t safi
= SAFI_EVPN
;
2728 /* Delete and withdraw locally learnt type-2 routes (MACIP)
2729 * for this VNI - from the global table.
2731 ret
= delete_global_type2_routes(bgp
, vpn
);
2735 /* Remove type-3 route for this VNI from global table. */
2736 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
2737 global_rn
= bgp_afi_node_lookup(bgp
->rib
[afi
][safi
], afi
, safi
,
2738 (struct prefix
*)&p
, &vpn
->prd
);
2740 /* Delete route entry in the global EVPN table. */
2741 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, &ri
);
2743 /* Schedule for processing - withdraws to peers happen from
2747 bgp_process(bgp
, global_rn
, afi
, safi
);
2748 bgp_unlock_node(global_rn
);
2755 * Handle router-id change. Update and advertise local routes corresponding
2756 * to this VNI from peers. Note that this is invoked after updating the
2757 * router-id. The routes in the per-VNI table are used to create routes in
2758 * the global table and schedule them.
2760 static void update_router_id_vni(struct hash_backet
*backet
, struct bgp
*bgp
)
2762 struct bgpevpn
*vpn
;
2764 vpn
= (struct bgpevpn
*)backet
->data
;
2767 zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__
);
2771 /* Skip VNIs with configured RD. */
2772 if (is_rd_configured(vpn
))
2775 bgp_evpn_derive_auto_rd(bgp
, vpn
);
2776 update_advertise_vni_routes(bgp
, vpn
);
2780 * Handle router-id change. Delete and withdraw local routes corresponding
2781 * to this VNI from peers. Note that this is invoked prior to updating
2782 * the router-id and is done only on the global route table, the routes
2783 * are needed in the per-VNI table to re-advertise with new router id.
2785 static void withdraw_router_id_vni(struct hash_backet
*backet
, struct bgp
*bgp
)
2787 struct bgpevpn
*vpn
;
2789 vpn
= (struct bgpevpn
*)backet
->data
;
2792 zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__
);
2796 /* Skip VNIs with configured RD. */
2797 if (is_rd_configured(vpn
))
2800 delete_withdraw_vni_routes(bgp
, vpn
);
2804 * Process received EVPN type-2 route (advertise or withdraw).
2806 static int process_type2_route(struct peer
*peer
, afi_t afi
, safi_t safi
,
2807 struct attr
*attr
, uint8_t *pfx
, int psize
,
2808 uint32_t addpath_id
)
2810 struct prefix_rd prd
;
2811 struct prefix_evpn p
;
2812 struct bgp_route_evpn evpn
;
2814 uint8_t macaddr_len
;
2815 mpls_label_t label
[BGP_MAX_LABELS
]; /* holds the VNI(s) as in packet */
2816 uint32_t num_labels
= 0;
2820 /* Type-2 route should be either 33, 37 or 49 bytes or an
2821 * additional 3 bytes if there is a second label (VNI):
2822 * RD (8), ESI (10), Eth Tag (4), MAC Addr Len (1),
2823 * MAC Addr (6), IP len (1), IP (0, 4 or 16),
2824 * MPLS Lbl1 (3), MPLS Lbl2 (0 or 3)
2826 if (psize
!= 33 && psize
!= 37 && psize
!= 49 && psize
!= 36
2827 && psize
!= 40 && psize
!= 52) {
2828 zlog_err("%u:%s - Rx EVPN Type-2 NLRI with invalid length %d",
2829 peer
->bgp
->vrf_id
, peer
->host
, psize
);
2833 memset(&evpn
, 0, sizeof(evpn
));
2835 /* Make prefix_rd */
2836 prd
.family
= AF_UNSPEC
;
2838 memcpy(&prd
.val
, pfx
, 8);
2841 /* Make EVPN prefix. */
2842 memset(&p
, 0, sizeof(struct prefix_evpn
));
2844 p
.prefixlen
= EVPN_TYPE_2_ROUTE_PREFIXLEN
;
2845 p
.prefix
.route_type
= BGP_EVPN_MAC_IP_ROUTE
;
2847 /* Copy Ethernet Seg Identifier */
2848 memcpy(&evpn
.eth_s_id
.val
, pfx
, ESI_LEN
);
2851 /* Copy Ethernet Tag */
2852 memcpy(ð_tag
, pfx
, 4);
2853 p
.prefix
.eth_tag
= ntohl(eth_tag
);
2856 /* Get the MAC Addr len */
2857 macaddr_len
= *pfx
++;
2859 /* Get the MAC Addr */
2860 if (macaddr_len
== (ETH_ALEN
* 8)) {
2861 memcpy(&p
.prefix
.mac
.octet
, pfx
, ETH_ALEN
);
2865 "%u:%s - Rx EVPN Type-2 NLRI with unsupported MAC address length %d",
2866 peer
->bgp
->vrf_id
, peer
->host
, macaddr_len
);
2872 ipaddr_len
= *pfx
++;
2873 if (ipaddr_len
!= 0 && ipaddr_len
!= IPV4_MAX_BITLEN
2874 && ipaddr_len
!= IPV6_MAX_BITLEN
) {
2876 "%u:%s - Rx EVPN Type-2 NLRI with unsupported IP address length %d",
2877 peer
->bgp
->vrf_id
, peer
->host
, ipaddr_len
);
2882 ipaddr_len
/= 8; /* Convert to bytes. */
2883 p
.prefix
.ip
.ipa_type
= (ipaddr_len
== IPV4_MAX_BYTELEN
)
2886 memcpy(&p
.prefix
.ip
.ip
.addr
, pfx
, ipaddr_len
);
2890 /* Get the VNI(s). Stored as bytes here. */
2892 memset(label
, 0, sizeof(label
));
2893 memcpy(&label
[0], pfx
, BGP_LABEL_BYTES
);
2894 pfx
+= BGP_LABEL_BYTES
;
2895 psize
-= (33 + ipaddr_len
);
2896 /* Do we have a second VNI? */
2899 memcpy(&label
[1], pfx
, BGP_LABEL_BYTES
);
2901 * If in future, we are required to access additional fields,
2902 * we MUST increment pfx by BGP_LABEL_BYTES in before reading
2907 /* Process the route. */
2909 ret
= bgp_update(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
2910 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
2911 &prd
, &label
[0], num_labels
, 0, &evpn
);
2913 ret
= bgp_withdraw(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
2914 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
2915 &prd
, &label
[0], num_labels
, &evpn
);
2920 * Process received EVPN type-3 route (advertise or withdraw).
2922 static int process_type3_route(struct peer
*peer
, afi_t afi
, safi_t safi
,
2923 struct attr
*attr
, uint8_t *pfx
, int psize
,
2924 uint32_t addpath_id
)
2926 struct prefix_rd prd
;
2927 struct prefix_evpn p
;
2932 /* Type-3 route should be either 17 or 29 bytes: RD (8), Eth Tag (4),
2933 * IP len (1) and IP (4 or 16).
2935 if (psize
!= 17 && psize
!= 29) {
2936 zlog_err("%u:%s - Rx EVPN Type-3 NLRI with invalid length %d",
2937 peer
->bgp
->vrf_id
, peer
->host
, psize
);
2941 /* If PMSI is present, log if it is anything other than IR.
2942 * Note: We just simply ignore the values as it is not clear if
2943 * doing anything else is better.
2946 (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL
))) {
2947 if (attr
->pmsi_tnl_type
!= PMSI_TNLTYPE_INGR_REPL
) {
2948 zlog_warn("%u:%s - Rx EVPN Type-3 NLRI with unsupported PTA %d",
2949 peer
->bgp
->vrf_id
, peer
->host
,
2950 attr
->pmsi_tnl_type
);
2954 /* Make prefix_rd */
2955 prd
.family
= AF_UNSPEC
;
2957 memcpy(&prd
.val
, pfx
, 8);
2960 /* Make EVPN prefix. */
2961 memset(&p
, 0, sizeof(struct prefix_evpn
));
2963 p
.prefixlen
= EVPN_TYPE_3_ROUTE_PREFIXLEN
;
2964 p
.prefix
.route_type
= BGP_EVPN_IMET_ROUTE
;
2966 /* Copy Ethernet Tag */
2967 memcpy(ð_tag
, pfx
, 4);
2968 p
.prefix
.eth_tag
= ntohl(eth_tag
);
2972 ipaddr_len
= *pfx
++;
2973 if (ipaddr_len
== IPV4_MAX_BITLEN
) {
2974 p
.prefix
.ip
.ipa_type
= IPADDR_V4
;
2975 memcpy(&p
.prefix
.ip
.ip
.addr
, pfx
, IPV4_MAX_BYTELEN
);
2978 "%u:%s - Rx EVPN Type-3 NLRI with unsupported IP address length %d",
2979 peer
->bgp
->vrf_id
, peer
->host
, ipaddr_len
);
2983 /* Process the route. */
2985 ret
= bgp_update(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
2986 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
2987 &prd
, NULL
, 0, 0, NULL
);
2989 ret
= bgp_withdraw(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
2990 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
2991 &prd
, NULL
, 0, NULL
);
2996 * Process received EVPN type-5 route (advertise or withdraw).
2998 static int process_type5_route(struct peer
*peer
, afi_t afi
, safi_t safi
,
2999 struct attr
*attr
, uint8_t *pfx
, int psize
,
3000 uint32_t addpath_id
, int withdraw
)
3002 struct prefix_rd prd
;
3003 struct prefix_evpn p
;
3004 struct bgp_route_evpn evpn
;
3007 mpls_label_t label
; /* holds the VNI as in the packet */
3010 /* Type-5 route should be 34 or 58 bytes:
3011 * RD (8), ESI (10), Eth Tag (4), IP len (1), IP (4 or 16),
3012 * GW (4 or 16) and VNI (3).
3013 * Note that the IP and GW should both be IPv4 or both IPv6.
3015 if (psize
!= 34 && psize
!= 58) {
3016 zlog_err("%u:%s - Rx EVPN Type-5 NLRI with invalid length %d",
3017 peer
->bgp
->vrf_id
, peer
->host
, psize
);
3021 /* Make prefix_rd */
3022 prd
.family
= AF_UNSPEC
;
3024 memcpy(&prd
.val
, pfx
, 8);
3027 /* Make EVPN prefix. */
3028 memset(&p
, 0, sizeof(struct prefix_evpn
));
3030 p
.prefixlen
= EVPN_TYPE_5_ROUTE_PREFIXLEN
;
3031 p
.prefix
.route_type
= BGP_EVPN_IP_PREFIX_ROUTE
;
3033 /* Additional information outside of prefix - ESI and GW IP */
3034 memset(&evpn
, 0, sizeof(evpn
));
3037 memcpy(&evpn
.eth_s_id
.val
, pfx
, 10);
3040 /* Fetch Ethernet Tag. */
3041 memcpy(ð_tag
, pfx
, 4);
3042 p
.prefix
.eth_tag
= ntohl(eth_tag
);
3045 /* Fetch IP prefix length. */
3047 if (ippfx_len
> IPV6_MAX_BITLEN
) {
3049 "%u:%s - Rx EVPN Type-5 NLRI with invalid IP Prefix length %d",
3050 peer
->bgp
->vrf_id
, peer
->host
, ippfx_len
);
3053 p
.prefix
.ip_prefix_length
= ippfx_len
;
3055 /* Determine IPv4 or IPv6 prefix */
3056 /* Since the address and GW are from the same family, this just becomes
3057 * a simple check on the total size.
3060 SET_IPADDR_V4(&p
.prefix
.ip
);
3061 memcpy(&p
.prefix
.ip
.ipaddr_v4
, pfx
, 4);
3063 memcpy(&evpn
.gw_ip
.ipv4
, pfx
, 4);
3066 SET_IPADDR_V6(&p
.prefix
.ip
);
3067 memcpy(&p
.prefix
.ip
.ipaddr_v6
, pfx
, 16);
3069 memcpy(&evpn
.gw_ip
.ipv6
, pfx
, 16);
3073 /* Get the VNI (in MPLS label field). Stored as bytes here. */
3074 memset(&label
, 0, sizeof(label
));
3075 memcpy(&label
, pfx
, BGP_LABEL_BYTES
);
3078 * If in future, we are required to access additional fields,
3079 * we MUST increment pfx by BGP_LABEL_BYTES in before reading the next
3083 /* Process the route. */
3085 ret
= bgp_update(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
3086 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3087 &prd
, &label
, 1, 0, &evpn
);
3089 ret
= bgp_withdraw(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
3090 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
3091 &prd
, &label
, 1, &evpn
);
3096 static void evpn_mpattr_encode_type5(struct stream
*s
, struct prefix
*p
,
3097 struct prefix_rd
*prd
, mpls_label_t
*label
,
3098 uint32_t num_labels
, struct attr
*attr
)
3102 struct evpn_addr
*p_evpn_p
;
3104 memset(&temp
, 0, 16);
3105 if (p
->family
!= AF_EVPN
)
3107 p_evpn_p
= &(p
->u
.prefix_evpn
);
3109 /* len denites the total len of IP and GW-IP in the route
3110 IP and GW-IP have to be both ipv4 or ipv6
3112 if (IS_IPADDR_V4(&p_evpn_p
->ip
))
3113 len
= 8; /* IP and GWIP are both ipv4 */
3115 len
= 32; /* IP and GWIP are both ipv6 */
3116 /* Prefix contains RD, ESI, EthTag, IP length, IP, GWIP and VNI */
3117 stream_putc(s
, 8 + 10 + 4 + 1 + len
+ 3);
3118 stream_put(s
, prd
->val
, 8);
3120 stream_put(s
, &(attr
->evpn_overlay
.eth_s_id
), 10);
3122 stream_put(s
, &temp
, 10);
3123 stream_putl(s
, p_evpn_p
->eth_tag
);
3124 stream_putc(s
, p_evpn_p
->ip_prefix_length
);
3125 if (IS_IPADDR_V4(&p_evpn_p
->ip
))
3126 stream_put_ipv4(s
, p_evpn_p
->ip
.ipaddr_v4
.s_addr
);
3128 stream_put(s
, &p_evpn_p
->ip
.ipaddr_v6
, 16);
3130 if (IS_IPADDR_V4(&p_evpn_p
->ip
))
3132 attr
->evpn_overlay
.gw_ip
.ipv4
.s_addr
);
3134 stream_put(s
, &(attr
->evpn_overlay
.gw_ip
.ipv6
), 16);
3136 if (IS_IPADDR_V4(&p_evpn_p
->ip
))
3137 stream_put_ipv4(s
, 0);
3139 stream_put(s
, &temp
, 16);
3143 stream_put(s
, label
, 3);
3149 * Cleanup specific VNI upon EVPN (advertise-all-vni) being disabled.
3151 static void cleanup_vni_on_disable(struct hash_backet
*backet
, struct bgp
*bgp
)
3153 struct bgpevpn
*vpn
= (struct bgpevpn
*)backet
->data
;
3155 /* Remove EVPN routes and schedule for processing. */
3156 delete_routes_for_vni(bgp
, vpn
);
3158 /* Clear "live" flag and see if hash needs to be freed. */
3159 UNSET_FLAG(vpn
->flags
, VNI_FLAG_LIVE
);
3160 if (!is_vni_configured(vpn
))
3161 bgp_evpn_free(bgp
, vpn
);
3165 * Free a VNI entry; iterator function called during cleanup.
3167 static void free_vni_entry(struct hash_backet
*backet
, struct bgp
*bgp
)
3169 struct bgpevpn
*vpn
;
3171 vpn
= (struct bgpevpn
*)backet
->data
;
3172 delete_all_vni_routes(bgp
, vpn
);
3173 bgp_evpn_free(bgp
, vpn
);
3177 * Derive AUTO import RT for BGP VRF - L3VNI
3179 static void evpn_auto_rt_import_add_for_vrf(struct bgp
*bgp_vrf
)
3181 struct bgp
*bgp_def
= NULL
;
3183 form_auto_rt(bgp_vrf
, bgp_vrf
->l3vni
, bgp_vrf
->vrf_import_rtl
);
3184 UNSET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_IMPORT_RT_CFGD
);
3187 bgp_def
= bgp_get_default();
3190 bgp_evpn_map_vrf_to_its_rts(bgp_vrf
);
3194 * Delete AUTO import RT from BGP VRF - L3VNI
3196 static void evpn_auto_rt_import_delete_for_vrf(struct bgp
*bgp_vrf
)
3198 evpn_rt_delete_auto(bgp_vrf
, bgp_vrf
->l3vni
, bgp_vrf
->vrf_import_rtl
);
3202 * Derive AUTO export RT for BGP VRF - L3VNI
3204 static void evpn_auto_rt_export_add_for_vrf(struct bgp
*bgp_vrf
)
3206 UNSET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_EXPORT_RT_CFGD
);
3207 form_auto_rt(bgp_vrf
, bgp_vrf
->l3vni
, bgp_vrf
->vrf_export_rtl
);
3211 * Delete AUTO export RT from BGP VRF - L3VNI
3213 static void evpn_auto_rt_export_delete_for_vrf(struct bgp
*bgp_vrf
)
3215 evpn_rt_delete_auto(bgp_vrf
, bgp_vrf
->l3vni
, bgp_vrf
->vrf_export_rtl
);
3218 static void bgp_evpn_handle_export_rt_change_for_vrf(struct bgp
*bgp_vrf
)
3220 struct bgp
*bgp_def
= NULL
;
3221 struct listnode
*node
= NULL
;
3222 struct bgpevpn
*vpn
= NULL
;
3224 bgp_def
= bgp_get_default();
3228 /* update all type-5 routes */
3229 update_advertise_vrf_routes(bgp_vrf
);
3231 /* update all type-2 routes */
3232 for (ALL_LIST_ELEMENTS_RO(bgp_vrf
->l2vnis
, node
, vpn
))
3233 update_routes_for_vni(bgp_def
, vpn
);
3240 /* withdraw type-5 route corresponding to ip prefix */
3241 void bgp_evpn_withdraw_type5_route(struct bgp
*bgp_vrf
, struct prefix
*p
,
3242 afi_t afi
, safi_t safi
)
3245 struct prefix_evpn evp
;
3246 char buf
[PREFIX_STRLEN
];
3248 build_type5_prefix_from_ip_prefix(&evp
, p
);
3249 ret
= delete_evpn_type5_route(bgp_vrf
, &evp
);
3252 "%u failed to delete type-5 route for prefix %s in vrf %s",
3253 bgp_vrf
->vrf_id
, prefix2str(p
, buf
, sizeof(buf
)),
3254 vrf_id_to_name(bgp_vrf
->vrf_id
));
3258 /* withdraw all type-5 routes for an address family */
3259 void bgp_evpn_withdraw_type5_routes(struct bgp
*bgp_vrf
, afi_t afi
, safi_t safi
)
3261 struct bgp_table
*table
= NULL
;
3262 struct bgp_node
*rn
= NULL
;
3263 struct bgp_info
*ri
;
3265 table
= bgp_vrf
->rib
[afi
][safi
];
3266 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
3267 /* Only care about "selected" routes - non-imported. */
3268 /* TODO: Support for AddPath for EVPN. */
3269 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
3270 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)
3271 && (!ri
->extra
|| !ri
->extra
->parent
)) {
3272 bgp_evpn_withdraw_type5_route(bgp_vrf
, &rn
->p
,
3281 * Advertise IP prefix as type-5 route. The afi/safi and src_attr passed
3282 * to this function correspond to those of the source IP prefix (best
3283 * path in the case of the attr. In the case of a local prefix (when we
3284 * are advertising local subnets), the src_attr will be NULL.
3286 void bgp_evpn_advertise_type5_route(struct bgp
*bgp_vrf
, struct prefix
*p
,
3287 struct attr
*src_attr
, afi_t afi
,
3291 struct prefix_evpn evp
;
3292 char buf
[PREFIX_STRLEN
];
3294 build_type5_prefix_from_ip_prefix(&evp
, p
);
3295 ret
= update_evpn_type5_route(bgp_vrf
, &evp
, src_attr
);
3297 zlog_err("%u: Failed to create type-5 route for prefix %s",
3298 bgp_vrf
->vrf_id
, prefix2str(p
, buf
, sizeof(buf
)));
3301 /* Inject all prefixes of a particular address-family (currently, IPv4 or
3302 * IPv6 unicast) into EVPN as type-5 routes. This is invoked when the
3303 * advertisement is enabled.
3305 void bgp_evpn_advertise_type5_routes(struct bgp
*bgp_vrf
, afi_t afi
,
3308 struct bgp_table
*table
= NULL
;
3309 struct bgp_node
*rn
= NULL
;
3310 struct bgp_info
*ri
;
3312 table
= bgp_vrf
->rib
[afi
][safi
];
3313 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
3314 /* Need to identify the "selected" route entry to use its
3315 * attribute. Also, we only consider "non-imported" routes.
3316 * TODO: Support for AddPath for EVPN.
3318 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
3319 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)
3320 && (!ri
->extra
|| !ri
->extra
->parent
)) {
3322 /* apply the route-map */
3323 if (bgp_vrf
->adv_cmd_rmap
[afi
][safi
].map
) {
3326 ret
= route_map_apply(
3327 bgp_vrf
->adv_cmd_rmap
[afi
][safi
]
3329 &rn
->p
, RMAP_BGP
, ri
);
3330 if (ret
== RMAP_DENYMATCH
)
3333 bgp_evpn_advertise_type5_route(
3334 bgp_vrf
, &rn
->p
, ri
->attr
, afi
, safi
);
3341 void evpn_rt_delete_auto(struct bgp
*bgp
, vni_t vni
, struct list
*rtl
)
3343 struct listnode
*node
, *nnode
, *node_to_del
;
3344 struct ecommunity
*ecom
, *ecom_auto
;
3345 struct ecommunity_val eval
;
3347 encode_route_target_as((bgp
->as
& 0xFFFF), vni
, &eval
);
3349 ecom_auto
= ecommunity_new();
3350 ecommunity_add_val(ecom_auto
, &eval
);
3353 for (ALL_LIST_ELEMENTS(rtl
, node
, nnode
, ecom
)) {
3354 if (ecommunity_match(ecom
, ecom_auto
)) {
3355 ecommunity_free(&ecom
);
3361 list_delete_node(rtl
, node_to_del
);
3363 ecommunity_free(&ecom_auto
);
3366 void bgp_evpn_configure_import_rt_for_vrf(struct bgp
*bgp_vrf
,
3367 struct ecommunity
*ecomadd
)
3369 /* uninstall routes from vrf */
3370 uninstall_routes_for_vrf(bgp_vrf
);
3372 /* Cleanup the RT to VRF mapping */
3373 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf
);
3375 /* Remove auto generated RT */
3376 evpn_auto_rt_import_delete_for_vrf(bgp_vrf
);
3378 /* Add the newly configured RT to RT list */
3379 listnode_add_sort(bgp_vrf
->vrf_import_rtl
, ecomadd
);
3380 SET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_IMPORT_RT_CFGD
);
3382 /* map VRF to its RTs */
3383 bgp_evpn_map_vrf_to_its_rts(bgp_vrf
);
3385 /* install routes matching the new VRF */
3386 install_routes_for_vrf(bgp_vrf
);
3389 void bgp_evpn_unconfigure_import_rt_for_vrf(struct bgp
*bgp_vrf
,
3390 struct ecommunity
*ecomdel
)
3392 struct listnode
*node
= NULL
, *nnode
= NULL
, *node_to_del
= NULL
;
3393 struct ecommunity
*ecom
= NULL
;
3395 /* uninstall routes from vrf */
3396 uninstall_routes_for_vrf(bgp_vrf
);
3398 /* Cleanup the RT to VRF mapping */
3399 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf
);
3401 /* remove the RT from the RT list */
3402 for (ALL_LIST_ELEMENTS(bgp_vrf
->vrf_import_rtl
, node
, nnode
, ecom
)) {
3403 if (ecommunity_match(ecom
, ecomdel
)) {
3404 ecommunity_free(&ecom
);
3411 list_delete_node(bgp_vrf
->vrf_import_rtl
, node_to_del
);
3413 /* fallback to auto import rt, if this was the last RT */
3414 if (list_isempty(bgp_vrf
->vrf_import_rtl
)) {
3415 UNSET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_IMPORT_RT_CFGD
);
3416 evpn_auto_rt_import_add_for_vrf(bgp_vrf
);
3419 /* map VRFs to its RTs */
3420 bgp_evpn_map_vrf_to_its_rts(bgp_vrf
);
3422 /* install routes matching this new RT */
3423 install_routes_for_vrf(bgp_vrf
);
3426 void bgp_evpn_configure_export_rt_for_vrf(struct bgp
*bgp_vrf
,
3427 struct ecommunity
*ecomadd
)
3429 /* remove auto-generated RT */
3430 evpn_auto_rt_export_delete_for_vrf(bgp_vrf
);
3432 /* Add the new RT to the RT list */
3433 listnode_add_sort(bgp_vrf
->vrf_export_rtl
, ecomadd
);
3434 SET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_EXPORT_RT_CFGD
);
3436 bgp_evpn_handle_export_rt_change_for_vrf(bgp_vrf
);
3439 void bgp_evpn_unconfigure_export_rt_for_vrf(struct bgp
*bgp_vrf
,
3440 struct ecommunity
*ecomdel
)
3442 struct listnode
*node
= NULL
, *nnode
= NULL
, *node_to_del
= NULL
;
3443 struct ecommunity
*ecom
= NULL
;
3445 /* Remove the RT from the RT list */
3446 for (ALL_LIST_ELEMENTS(bgp_vrf
->vrf_export_rtl
, node
, nnode
, ecom
)) {
3447 if (ecommunity_match(ecom
, ecomdel
)) {
3448 ecommunity_free(&ecom
);
3455 list_delete_node(bgp_vrf
->vrf_export_rtl
, node_to_del
);
3457 /* fall back to auto-generated RT if this was the last RT */
3458 if (bgp_vrf
->vrf_export_rtl
&& list_isempty(bgp_vrf
->vrf_export_rtl
)) {
3459 UNSET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_EXPORT_RT_CFGD
);
3460 evpn_auto_rt_export_add_for_vrf(bgp_vrf
);
3463 bgp_evpn_handle_export_rt_change_for_vrf(bgp_vrf
);
3467 * Handle change to BGP router id. This is invoked twice by the change
3468 * handler, first before the router id has been changed and then after
3469 * the router id has been changed. The first invocation will result in
3470 * local routes for all VNIs/VRF being deleted and withdrawn and the next
3471 * will result in the routes being re-advertised.
3473 void bgp_evpn_handle_router_id_update(struct bgp
*bgp
, int withdraw
)
3477 /* delete and withdraw all the type-5 routes
3478 stored in the global table for this vrf
3480 withdraw_router_id_vrf(bgp
);
3482 /* delete all the VNI routes (type-2/type-3) routes for all the
3485 hash_iterate(bgp
->vnihash
,
3486 (void (*)(struct hash_backet
*,
3487 void *))withdraw_router_id_vni
,
3491 /* advertise all routes in the vrf as type-5 routes with the new
3494 update_router_id_vrf(bgp
);
3496 /* advertise all the VNI routes (type-2/type-3) routes with the
3499 hash_iterate(bgp
->vnihash
,
3500 (void (*)(struct hash_backet
*,
3501 void *))update_router_id_vni
,
3507 * Handle change to export RT - update and advertise local routes.
3509 int bgp_evpn_handle_export_rt_change(struct bgp
*bgp
, struct bgpevpn
*vpn
)
3511 return update_routes_for_vni(bgp
, vpn
);
3514 void bgp_evpn_handle_vrf_rd_change(struct bgp
*bgp_vrf
, int withdraw
)
3517 delete_withdraw_vrf_routes(bgp_vrf
);
3519 update_advertise_vrf_routes(bgp_vrf
);
3523 * Handle change to RD. This is invoked twice by the change handler,
3524 * first before the RD has been changed and then after the RD has
3525 * been changed. The first invocation will result in local routes
3526 * of this VNI being deleted and withdrawn and the next will result
3527 * in the routes being re-advertised.
3529 void bgp_evpn_handle_rd_change(struct bgp
*bgp
, struct bgpevpn
*vpn
,
3533 delete_withdraw_vni_routes(bgp
, vpn
);
3535 update_advertise_vni_routes(bgp
, vpn
);
3539 * Install routes for this VNI. Invoked upon change to Import RT.
3541 int bgp_evpn_install_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
3543 return install_routes_for_vni(bgp
, vpn
);
3547 * Uninstall all routes installed for this VNI. Invoked upon change
3550 int bgp_evpn_uninstall_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
3552 return uninstall_routes_for_vni(bgp
, vpn
);
3556 * TODO: Hardcoded for a maximum of 2 VNIs right now
3558 char *bgp_evpn_label2str(mpls_label_t
*label
, uint32_t num_labels
, char *buf
,
3563 vni1
= label2vni(label
);
3564 if (num_labels
== 2) {
3565 vni2
= label2vni(label
+ 1);
3566 snprintf(buf
, len
, "%u/%u", vni1
, vni2
);
3568 snprintf(buf
, len
, "%u", vni1
);
3573 * Function to convert evpn route to json format.
3574 * NOTE: We don't use prefix2str as the output here is a bit different.
3576 void bgp_evpn_route2json(struct prefix_evpn
*p
, json_object
*json
)
3578 char buf1
[ETHER_ADDR_STRLEN
];
3579 char buf2
[PREFIX2STR_BUFFER
];
3584 if (p
->prefix
.route_type
== BGP_EVPN_IMET_ROUTE
) {
3585 json_object_int_add(json
, "routeType", p
->prefix
.route_type
);
3586 json_object_int_add(json
, "ethTag", p
->prefix
.eth_tag
);
3587 json_object_int_add(json
, "ipLen",
3588 IS_EVPN_PREFIX_IPADDR_V4(p
)
3591 json_object_string_add(json
, "ip",
3592 inet_ntoa(p
->prefix
.ip
.ipaddr_v4
));
3593 } else if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
) {
3594 if (IS_EVPN_PREFIX_IPADDR_NONE(p
)) {
3595 json_object_int_add(json
, "routeType",
3596 p
->prefix
.route_type
);
3597 json_object_int_add(json
, "ethTag", p
->prefix
.eth_tag
);
3598 json_object_int_add(json
, "macLen", 8 * ETH_ALEN
);
3599 json_object_string_add(json
, "mac",
3600 prefix_mac2str(&p
->prefix
.mac
,
3606 family
= IS_EVPN_PREFIX_IPADDR_V4(p
) ? AF_INET
3609 json_object_int_add(json
, "routeType",
3610 p
->prefix
.route_type
);
3611 json_object_int_add(json
, "ethTag", p
->prefix
.eth_tag
);
3612 json_object_int_add(json
, "macLen", 8 * ETH_ALEN
);
3613 json_object_string_add(json
, "mac",
3614 prefix_mac2str(&p
->prefix
.mac
,
3617 json_object_int_add(json
, "ipLen",
3618 IS_EVPN_PREFIX_IPADDR_V4(p
)
3621 json_object_string_add(
3623 inet_ntop(family
, &p
->prefix
.ip
.ip
.addr
, buf2
,
3624 PREFIX2STR_BUFFER
));
3627 /* Currently, this is to cater to other AF_ETHERNET code. */
3632 * Function to convert evpn route to string.
3633 * NOTE: We don't use prefix2str as the output here is a bit different.
3635 char *bgp_evpn_route2str(struct prefix_evpn
*p
, char *buf
, int len
)
3637 char buf1
[ETHER_ADDR_STRLEN
];
3638 char buf2
[PREFIX2STR_BUFFER
];
3640 if (p
->prefix
.route_type
== BGP_EVPN_IMET_ROUTE
) {
3641 snprintf(buf
, len
, "[%d]:[%d]:[%d]:[%s]", p
->prefix
.route_type
,
3643 IS_EVPN_PREFIX_IPADDR_V4(p
) ? IPV4_MAX_BITLEN
3645 inet_ntoa(p
->prefix
.ip
.ipaddr_v4
));
3646 } else if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
) {
3647 if (IS_EVPN_PREFIX_IPADDR_NONE(p
))
3648 snprintf(buf
, len
, "[%d]:[%d]:[%d]:[%s]",
3649 p
->prefix
.route_type
,
3652 prefix_mac2str(&p
->prefix
.mac
, buf1
,
3657 family
= IS_EVPN_PREFIX_IPADDR_V4(p
) ? AF_INET
3659 snprintf(buf
, len
, "[%d]:[%d]:[%d]:[%s]:[%d]:[%s]",
3660 p
->prefix
.route_type
,
3663 prefix_mac2str(&p
->prefix
.mac
, buf1
,
3665 family
== AF_INET
? IPV4_MAX_BITLEN
3667 inet_ntop(family
, &p
->prefix
.ip
.ip
.addr
, buf2
,
3668 PREFIX2STR_BUFFER
));
3670 } else if (p
->prefix
.route_type
== BGP_EVPN_IP_PREFIX_ROUTE
) {
3671 snprintf(buf
, len
, "[%d]:[%d]:[%d]:[%s]",
3672 p
->prefix
.route_type
,
3674 p
->prefix
.ip_prefix_length
,
3675 IS_EVPN_PREFIX_IPADDR_V4(p
)
3676 ? inet_ntoa(p
->prefix
.ip
.ipaddr_v4
)
3677 : inet6_ntoa(p
->prefix
.ip
.ipaddr_v6
));
3679 /* For EVPN route types not supported yet. */
3680 snprintf(buf
, len
, "(unsupported route type %d)",
3681 p
->prefix
.route_type
);
3688 * Encode EVPN prefix in Update (MP_REACH)
3690 void bgp_evpn_encode_prefix(struct stream
*s
, struct prefix
*p
,
3691 struct prefix_rd
*prd
, mpls_label_t
*label
,
3692 uint32_t num_labels
, struct attr
*attr
,
3693 int addpath_encode
, uint32_t addpath_tx_id
)
3695 struct prefix_evpn
*evp
= (struct prefix_evpn
*)p
;
3696 int len
, ipa_len
= 0;
3699 stream_putl(s
, addpath_tx_id
);
3702 stream_putc(s
, evp
->prefix
.route_type
);
3704 switch (evp
->prefix
.route_type
) {
3705 case BGP_EVPN_MAC_IP_ROUTE
:
3706 if (IS_EVPN_PREFIX_IPADDR_V4(evp
))
3707 ipa_len
= IPV4_MAX_BYTELEN
;
3708 else if (IS_EVPN_PREFIX_IPADDR_V6(evp
))
3709 ipa_len
= IPV6_MAX_BYTELEN
;
3710 /* RD, ESI, EthTag, MAC+len, IP len, [IP], 1 VNI */
3711 len
= 8 + 10 + 4 + 1 + 6 + 1 + ipa_len
+ 3;
3712 if (ipa_len
&& num_labels
> 1) /* There are 2 VNIs */
3714 stream_putc(s
, len
);
3715 stream_put(s
, prd
->val
, 8); /* RD */
3717 stream_put(s
, &attr
->evpn_overlay
.eth_s_id
, ESI_LEN
);
3719 stream_put(s
, 0, 10);
3720 stream_putl(s
, evp
->prefix
.eth_tag
); /* Ethernet Tag ID */
3721 stream_putc(s
, 8 * ETH_ALEN
); /* Mac Addr Len - bits */
3722 stream_put(s
, evp
->prefix
.mac
.octet
, 6); /* Mac Addr */
3723 stream_putc(s
, 8 * ipa_len
); /* IP address Length */
3724 if (ipa_len
) /* IP */
3725 stream_put(s
, &evp
->prefix
.ip
.ip
.addr
, ipa_len
);
3726 /* 1st label is the L2 VNI */
3727 stream_put(s
, label
, BGP_LABEL_BYTES
);
3728 /* Include 2nd label (L3 VNI) if advertising MAC+IP */
3729 if (ipa_len
&& num_labels
> 1)
3730 stream_put(s
, label
+ 1, BGP_LABEL_BYTES
);
3733 case BGP_EVPN_IMET_ROUTE
:
3734 stream_putc(s
, 17); // TODO: length - assumes IPv4 address
3735 stream_put(s
, prd
->val
, 8); /* RD */
3736 stream_putl(s
, evp
->prefix
.eth_tag
); /* Ethernet Tag ID */
3737 stream_putc(s
, IPV4_MAX_BITLEN
); /* IP address Length - bits */
3738 /* Originating Router's IP Addr */
3739 stream_put_in_addr(s
, &evp
->prefix
.ip
.ipaddr_v4
);
3742 case BGP_EVPN_IP_PREFIX_ROUTE
:
3743 /* TODO: AddPath support. */
3744 evpn_mpattr_encode_type5(s
, p
, prd
, label
, num_labels
, attr
);
3752 int bgp_nlri_parse_evpn(struct peer
*peer
, struct attr
*attr
,
3753 struct bgp_nlri
*packet
, int withdraw
)
3759 uint32_t addpath_id
;
3760 int addpath_encoded
;
3766 /* Start processing the NLRI - there may be multiple in the MP_REACH */
3768 lim
= pnt
+ packet
->length
;
3770 safi
= packet
->safi
;
3774 (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
3775 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
3776 PEER_CAP_ADDPATH_AF_TX_RCV
));
3778 for (; pnt
< lim
; pnt
+= psize
) {
3779 /* Clear prefix structure. */
3780 memset(&p
, 0, sizeof(struct prefix
));
3782 /* Deal with path-id if AddPath is supported. */
3783 if (addpath_encoded
) {
3784 /* When packet overflow occurs return immediately. */
3785 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3788 addpath_id
= ntohl(*((uint32_t *)pnt
));
3789 pnt
+= BGP_ADDPATH_ID_LEN
;
3792 /* All EVPN NLRI types start with type and length. */
3797 psize
= rlen
= *pnt
++;
3799 /* When packet overflow occur return immediately. */
3800 if (pnt
+ psize
> lim
)
3804 case BGP_EVPN_MAC_IP_ROUTE
:
3805 if (process_type2_route(peer
, afi
, safi
,
3806 withdraw
? NULL
: attr
, pnt
,
3807 psize
, addpath_id
)) {
3809 "%u:%s - Error in processing EVPN type-2 NLRI size %d",
3810 peer
->bgp
->vrf_id
, peer
->host
, psize
);
3815 case BGP_EVPN_IMET_ROUTE
:
3816 if (process_type3_route(peer
, afi
, safi
,
3817 withdraw
? NULL
: attr
, pnt
,
3818 psize
, addpath_id
)) {
3820 "%u:%s - Error in processing EVPN type-3 NLRI size %d",
3821 peer
->bgp
->vrf_id
, peer
->host
, psize
);
3826 case BGP_EVPN_IP_PREFIX_ROUTE
:
3827 if (process_type5_route(peer
, afi
, safi
, attr
, pnt
,
3828 psize
, addpath_id
, withdraw
)) {
3830 "%u:%s - Error in processing EVPN type-5 NLRI size %d",
3831 peer
->bgp
->vrf_id
, peer
->host
, psize
);
3841 /* Packet length consistency check. */
3849 * Map the RTs (configured or automatically derived) of a VRF to the VRF.
3850 * The mapping will be used during route processing.
3851 * bgp_def: default bgp instance
3852 * bgp_vrf: specific bgp vrf instance on which RT is configured
3854 void bgp_evpn_map_vrf_to_its_rts(struct bgp
*bgp_vrf
)
3857 struct ecommunity_val
*eval
= NULL
;
3858 struct listnode
*node
= NULL
, *nnode
= NULL
;
3859 struct ecommunity
*ecom
= NULL
;
3861 for (ALL_LIST_ELEMENTS(bgp_vrf
->vrf_import_rtl
, node
, nnode
, ecom
)) {
3862 for (i
= 0; i
< ecom
->size
; i
++) {
3863 eval
= (struct ecommunity_val
*)(ecom
->val
3865 * ECOMMUNITY_SIZE
));
3866 map_vrf_to_rt(bgp_vrf
, eval
);
3872 * Unmap the RTs (configured or automatically derived) of a VRF from the VRF.
3874 void bgp_evpn_unmap_vrf_from_its_rts(struct bgp
*bgp_vrf
)
3877 struct ecommunity_val
*eval
;
3878 struct listnode
*node
, *nnode
;
3879 struct ecommunity
*ecom
;
3881 for (ALL_LIST_ELEMENTS(bgp_vrf
->vrf_import_rtl
, node
, nnode
, ecom
)) {
3882 for (i
= 0; i
< ecom
->size
; i
++) {
3883 struct vrf_irt_node
*irt
;
3884 struct ecommunity_val eval_tmp
;
3886 eval
= (struct ecommunity_val
*)(ecom
->val
3888 * ECOMMUNITY_SIZE
));
3889 /* If using "automatic" RT, we only care about the
3890 * local-admin sub-field.
3891 * This is to facilitate using VNI as the RT for EBGP
3894 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
3895 if (!CHECK_FLAG(bgp_vrf
->vrf_flags
,
3896 BGP_VRF_IMPORT_RT_CFGD
))
3897 mask_ecom_global_admin(&eval_tmp
, eval
);
3899 irt
= lookup_vrf_import_rt(&eval_tmp
);
3901 unmap_vrf_from_rt(bgp_vrf
, irt
);
3908 * Map the RTs (configured or automatically derived) of a VNI to the VNI.
3909 * The mapping will be used during route processing.
3911 void bgp_evpn_map_vni_to_its_rts(struct bgp
*bgp
, struct bgpevpn
*vpn
)
3914 struct ecommunity_val
*eval
;
3915 struct listnode
*node
, *nnode
;
3916 struct ecommunity
*ecom
;
3918 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
)) {
3919 for (i
= 0; i
< ecom
->size
; i
++) {
3920 eval
= (struct ecommunity_val
*)(ecom
->val
3922 * ECOMMUNITY_SIZE
));
3923 map_vni_to_rt(bgp
, vpn
, eval
);
3929 * Unmap the RTs (configured or automatically derived) of a VNI from the VNI.
3931 void bgp_evpn_unmap_vni_from_its_rts(struct bgp
*bgp
, struct bgpevpn
*vpn
)
3934 struct ecommunity_val
*eval
;
3935 struct listnode
*node
, *nnode
;
3936 struct ecommunity
*ecom
;
3938 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
)) {
3939 for (i
= 0; i
< ecom
->size
; i
++) {
3940 struct irt_node
*irt
;
3941 struct ecommunity_val eval_tmp
;
3943 eval
= (struct ecommunity_val
*)(ecom
->val
3945 * ECOMMUNITY_SIZE
));
3946 /* If using "automatic" RT, we only care about the
3947 * local-admin sub-field.
3948 * This is to facilitate using VNI as the RT for EBGP
3951 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
3952 if (!is_import_rt_configured(vpn
))
3953 mask_ecom_global_admin(&eval_tmp
, eval
);
3955 irt
= lookup_import_rt(bgp
, &eval_tmp
);
3957 unmap_vni_from_rt(bgp
, vpn
, irt
);
3963 * Derive Import RT automatically for VNI and map VNI to RT.
3964 * The mapping will be used during route processing.
3966 void bgp_evpn_derive_auto_rt_import(struct bgp
*bgp
, struct bgpevpn
*vpn
)
3968 form_auto_rt(bgp
, vpn
->vni
, vpn
->import_rtl
);
3969 UNSET_FLAG(vpn
->flags
, VNI_FLAG_IMPRT_CFGD
);
3972 bgp_evpn_map_vni_to_its_rts(bgp
, vpn
);
3976 * Derive Export RT automatically for VNI.
3978 void bgp_evpn_derive_auto_rt_export(struct bgp
*bgp
, struct bgpevpn
*vpn
)
3980 form_auto_rt(bgp
, vpn
->vni
, vpn
->export_rtl
);
3981 UNSET_FLAG(vpn
->flags
, VNI_FLAG_EXPRT_CFGD
);
3985 * Derive RD automatically for VNI using passed information - it
3986 * is of the form RouterId:unique-id-for-vni.
3988 void bgp_evpn_derive_auto_rd_for_vrf(struct bgp
*bgp
)
3990 form_auto_rd(bgp
->router_id
, bgp
->vrf_rd_id
, &bgp
->vrf_prd
);
3994 * Derive RD automatically for VNI using passed information - it
3995 * is of the form RouterId:unique-id-for-vni.
3997 void bgp_evpn_derive_auto_rd(struct bgp
*bgp
, struct bgpevpn
*vpn
)
4001 vpn
->prd
.family
= AF_UNSPEC
;
4002 vpn
->prd
.prefixlen
= 64;
4003 sprintf(buf
, "%s:%hu", inet_ntoa(bgp
->router_id
), vpn
->rd_id
);
4004 (void)str2prefix_rd(buf
, &vpn
->prd
);
4005 UNSET_FLAG(vpn
->flags
, VNI_FLAG_RD_CFGD
);
4011 struct bgpevpn
*bgp_evpn_lookup_vni(struct bgp
*bgp
, vni_t vni
)
4013 struct bgpevpn
*vpn
;
4016 memset(&tmp
, 0, sizeof(struct bgpevpn
));
4018 vpn
= hash_lookup(bgp
->vnihash
, &tmp
);
4023 * Create a new vpn - invoked upon configuration or zebra notification.
4025 struct bgpevpn
*bgp_evpn_new(struct bgp
*bgp
, vni_t vni
,
4026 struct in_addr originator_ip
,
4027 vrf_id_t tenant_vrf_id
)
4029 struct bgpevpn
*vpn
;
4034 vpn
= XCALLOC(MTYPE_BGP_EVPN
, sizeof(struct bgpevpn
));
4038 /* Set values - RD and RT set to defaults. */
4040 vpn
->originator_ip
= originator_ip
;
4041 vpn
->tenant_vrf_id
= tenant_vrf_id
;
4043 /* Initialize route-target import and export lists */
4044 vpn
->import_rtl
= list_new();
4045 vpn
->import_rtl
->cmp
= (int (*)(void *, void *))evpn_route_target_cmp
;
4046 vpn
->export_rtl
= list_new();
4047 vpn
->export_rtl
->cmp
= (int (*)(void *, void *))evpn_route_target_cmp
;
4048 bf_assign_index(bm
->rd_idspace
, vpn
->rd_id
);
4049 derive_rd_rt_for_vni(bgp
, vpn
);
4051 /* Initialize EVPN route table. */
4052 vpn
->route_table
= bgp_table_init(bgp
, AFI_L2VPN
, SAFI_EVPN
);
4055 if (!hash_get(bgp
->vnihash
, vpn
, hash_alloc_intern
)) {
4056 XFREE(MTYPE_BGP_EVPN
, vpn
);
4060 /* add to l2vni list on corresponding vrf */
4061 bgpevpn_link_to_l3vni(vpn
);
4063 QOBJ_REG(vpn
, bgpevpn
);
4068 * Free a given VPN - called in multiple scenarios such as zebra
4069 * notification, configuration being deleted, advertise-all-vni disabled etc.
4070 * This just frees appropriate memory, caller should have taken other
4073 void bgp_evpn_free(struct bgp
*bgp
, struct bgpevpn
*vpn
)
4075 bgpevpn_unlink_from_l3vni(vpn
);
4076 bgp_table_unlock(vpn
->route_table
);
4077 bgp_evpn_unmap_vni_from_its_rts(bgp
, vpn
);
4078 list_delete_and_null(&vpn
->import_rtl
);
4079 list_delete_and_null(&vpn
->export_rtl
);
4080 bf_release_index(bm
->rd_idspace
, vpn
->rd_id
);
4081 hash_release(bgp
->vnihash
, vpn
);
4083 XFREE(MTYPE_BGP_EVPN
, vpn
);
4087 * Import route into matching VNI(s).
4089 int bgp_evpn_import_route(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
4090 struct prefix
*p
, struct bgp_info
*ri
)
4092 return install_uninstall_evpn_route(bgp
, afi
, safi
, p
, ri
, 1);
4096 * Unimport route from matching VNI(s).
4098 int bgp_evpn_unimport_route(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
4099 struct prefix
*p
, struct bgp_info
*ri
)
4101 return install_uninstall_evpn_route(bgp
, afi
, safi
, p
, ri
, 0);
4104 /* filter routes which have martian next hops */
4105 int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp
*bgp
)
4109 struct bgp_node
*rd_rn
, *rn
;
4110 struct bgp_table
*table
;
4111 struct bgp_info
*ri
;
4116 /* Walk entire global routing table and evaluate routes which could be
4117 * imported into this VPN. Note that we cannot just look at the routes
4118 * for the VNI's RD -
4119 * remote routes applicable for this VNI could have any RD.
4121 /* EVPN routes are a 2-level table. */
4122 for (rd_rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rd_rn
;
4123 rd_rn
= bgp_route_next(rd_rn
)) {
4124 table
= (struct bgp_table
*)(rd_rn
->info
);
4128 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
4130 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
4132 /* Consider "valid" remote routes applicable for
4134 if (!(ri
->type
== ZEBRA_ROUTE_BGP
4135 && ri
->sub_type
== BGP_ROUTE_NORMAL
))
4138 if (bgp_nexthop_self(bgp
, ri
->attr
->nexthop
)) {
4140 char attr_str
[BUFSIZ
];
4141 char pbuf
[PREFIX_STRLEN
];
4143 bgp_dump_attr(ri
->attr
, attr_str
,
4146 if (bgp_debug_update(ri
->peer
, &rn
->p
,
4149 "%u: prefix %s with attr %s - DENIED due to martian or self nexthop",
4156 bgp_evpn_unimport_route(bgp
, afi
, safi
,
4159 bgp_rib_remove(rn
, ri
, ri
->peer
, afi
,
4170 * Handle del of a local MACIP.
4172 int bgp_evpn_local_macip_del(struct bgp
*bgp
, vni_t vni
, struct ethaddr
*mac
,
4175 struct bgpevpn
*vpn
;
4176 struct prefix_evpn p
;
4178 if (!bgp
->vnihash
) {
4179 zlog_err("%u: VNI hash not created", bgp
->vrf_id
);
4183 /* Lookup VNI hash - should exist. */
4184 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
4185 if (!vpn
|| !is_vni_live(vpn
)) {
4186 zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP DEL",
4187 bgp
->vrf_id
, vni
, vpn
? "not live" : "not found");
4191 /* Remove EVPN type-2 route and schedule for processing. */
4192 build_evpn_type2_prefix(&p
, mac
, ip
);
4193 delete_evpn_route(bgp
, vpn
, &p
);
4199 * Handle add of a local MACIP.
4201 int bgp_evpn_local_macip_add(struct bgp
*bgp
, vni_t vni
, struct ethaddr
*mac
,
4202 struct ipaddr
*ip
, uint8_t flags
)
4204 struct bgpevpn
*vpn
;
4205 struct prefix_evpn p
;
4207 if (!bgp
->vnihash
) {
4208 zlog_err("%u: VNI hash not created", bgp
->vrf_id
);
4212 /* Lookup VNI hash - should exist. */
4213 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
4214 if (!vpn
|| !is_vni_live(vpn
)) {
4215 zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP ADD",
4216 bgp
->vrf_id
, vni
, vpn
? "not live" : "not found");
4220 /* Create EVPN type-2 route and schedule for processing. */
4221 build_evpn_type2_prefix(&p
, mac
, ip
);
4222 if (update_evpn_route(bgp
, vpn
, &p
, flags
)) {
4223 char buf
[ETHER_ADDR_STRLEN
];
4224 char buf2
[INET6_ADDRSTRLEN
];
4227 "%u:Failed to create Type-2 route, VNI %u %s MAC %s IP %s (flags: 0x%x)",
4228 bgp
->vrf_id
, vpn
->vni
,
4229 CHECK_FLAG(flags
, ZEBRA_MACIP_TYPE_STICKY
)
4232 prefix_mac2str(mac
, buf
, sizeof(buf
)),
4233 ipaddr2str(ip
, buf2
, sizeof(buf2
)), flags
);
4240 static void link_l2vni_hash_to_l3vni(struct hash_backet
*backet
,
4241 struct bgp
*bgp_vrf
)
4243 struct bgpevpn
*vpn
= NULL
;
4244 struct bgp
*bgp_def
= NULL
;
4246 bgp_def
= bgp_get_default();
4249 vpn
= (struct bgpevpn
*)backet
->data
;
4250 if (vpn
->tenant_vrf_id
== bgp_vrf
->vrf_id
)
4251 bgpevpn_link_to_l3vni(vpn
);
4254 int bgp_evpn_local_l3vni_add(vni_t l3vni
, vrf_id_t vrf_id
, struct ethaddr
*rmac
,
4255 struct in_addr originator_ip
, int filter
)
4257 struct bgp
*bgp_vrf
= NULL
; /* bgp VRF instance */
4258 struct bgp
*bgp_def
= NULL
; /* default bgp instance */
4259 struct listnode
*node
= NULL
;
4260 struct bgpevpn
*vpn
= NULL
;
4263 /* get the default instamce - required to get the AS number for VRF
4266 bgp_def
= bgp_get_default();
4269 "Cannot process L3VNI %u ADD - default BGP instance not yet created",
4275 /* if the BGP vrf instance doesnt exist - create one */
4276 bgp_vrf
= bgp_lookup_by_name(vrf_id_to_name(vrf_id
));
4281 ret
= bgp_get(&bgp_vrf
, &as
, vrf_id_to_name(vrf_id
),
4282 BGP_INSTANCE_TYPE_VRF
);
4284 case BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
:
4285 zlog_err("'bgp multiple-instance' not present\n");
4287 case BGP_ERR_AS_MISMATCH
:
4288 zlog_err("BGP is already running; AS is %u\n", as
);
4290 case BGP_ERR_INSTANCE_MISMATCH
:
4291 zlog_err("BGP instance name and AS number mismatch\n");
4295 /* mark as auto created */
4296 SET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_AUTO
);
4299 /* associate with l3vni */
4300 bgp_vrf
->l3vni
= l3vni
;
4302 /* set the router mac - to be used in mac-ip routes for this vrf */
4303 memcpy(&bgp_vrf
->rmac
, rmac
, sizeof(struct ethaddr
));
4305 /* set the originator ip */
4306 bgp_vrf
->originator_ip
= originator_ip
;
4308 /* set the right filter - are we using l3vni only for prefix routes? */
4310 SET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY
);
4312 /* auto derive RD/RT */
4313 if (!CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_IMPORT_RT_CFGD
))
4314 evpn_auto_rt_import_add_for_vrf(bgp_vrf
);
4315 if (!CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_EXPORT_RT_CFGD
))
4316 evpn_auto_rt_export_add_for_vrf(bgp_vrf
);
4317 bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf
);
4319 /* link all corresponding l2vnis */
4320 hash_iterate(bgp_def
->vnihash
,
4321 (void (*)(struct hash_backet
*,
4322 void *))link_l2vni_hash_to_l3vni
,
4325 /* Only update all corresponding type-2 routes if we are advertising two
4326 * labels along with type-2 routes
4329 for (ALL_LIST_ELEMENTS_RO(bgp_vrf
->l2vnis
, node
, vpn
))
4330 update_routes_for_vni(bgp_def
, vpn
);
4332 /* advertise type-5 routes if needed */
4333 update_advertise_vrf_routes(bgp_vrf
);
4335 /* install all remote routes belonging to this l3vni into correspondng
4337 install_routes_for_vrf(bgp_vrf
);
4342 int bgp_evpn_local_l3vni_del(vni_t l3vni
, vrf_id_t vrf_id
)
4344 struct bgp
*bgp_vrf
= NULL
; /* bgp vrf instance */
4345 struct bgp
*bgp_def
= NULL
; /* default bgp instance */
4346 struct listnode
*node
= NULL
;
4347 struct listnode
*next
= NULL
;
4348 struct bgpevpn
*vpn
= NULL
;
4350 bgp_vrf
= bgp_lookup_by_vrf_id(vrf_id
);
4353 "Cannot process L3VNI %u Del - Could not find BGP instance",
4358 bgp_def
= bgp_get_default();
4361 "Cannot process L3VNI %u Del - Could not find default BGP instance",
4366 /* unimport remote routes from VRF, if it is AUTO vrf bgp_delete will
4367 * take care of uninstalling the routes from zebra
4369 if (!CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_AUTO
))
4370 uninstall_routes_for_vrf(bgp_vrf
);
4372 /* delete/withdraw all type-5 routes */
4373 delete_withdraw_vrf_routes(bgp_vrf
);
4375 /* remove the l3vni from vrf instance */
4378 /* remove the Rmac from the BGP vrf */
4379 memset(&bgp_vrf
->rmac
, 0, sizeof(struct ethaddr
));
4382 if (bgp_vrf
->vrf_import_rtl
&& !list_isempty(bgp_vrf
->vrf_import_rtl
)) {
4383 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf
);
4384 list_delete_all_node(bgp_vrf
->vrf_import_rtl
);
4386 if (bgp_vrf
->vrf_export_rtl
&& !list_isempty(bgp_vrf
->vrf_export_rtl
)) {
4387 list_delete_all_node(bgp_vrf
->vrf_export_rtl
);
4390 /* update all corresponding local mac-ip routes */
4391 if (!CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY
)) {
4392 for (ALL_LIST_ELEMENTS_RO(bgp_vrf
->l2vnis
, node
, vpn
)) {
4393 UNSET_FLAG(vpn
->flags
, VNI_FLAG_USE_TWO_LABELS
);
4394 update_routes_for_vni(bgp_def
, vpn
);
4398 /* If any L2VNIs point to this instance, unlink them. */
4399 for (ALL_LIST_ELEMENTS(bgp_vrf
->l2vnis
, node
, next
, vpn
))
4400 bgpevpn_unlink_from_l3vni(vpn
);
4402 /* Delete the instance if it was autocreated */
4403 if (CHECK_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_AUTO
))
4404 bgp_delete(bgp_vrf
);
4410 * Handle del of a local VNI.
4412 int bgp_evpn_local_vni_del(struct bgp
*bgp
, vni_t vni
)
4414 struct bgpevpn
*vpn
;
4416 if (!bgp
->vnihash
) {
4417 zlog_err("%u: VNI hash not created", bgp
->vrf_id
);
4421 /* Locate VNI hash */
4422 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
4424 zlog_warn("%u: VNI hash entry for VNI %u not found at DEL",
4429 /* Remove all local EVPN routes and schedule for processing (to
4430 * withdraw from peers).
4432 delete_routes_for_vni(bgp
, vpn
);
4435 * tunnel is no longer active, del tunnel ip address from tip_hash
4437 bgp_tip_del(bgp
, &vpn
->originator_ip
);
4439 /* Clear "live" flag and see if hash needs to be freed. */
4440 UNSET_FLAG(vpn
->flags
, VNI_FLAG_LIVE
);
4441 if (!is_vni_configured(vpn
))
4442 bgp_evpn_free(bgp
, vpn
);
4448 * Handle add (or update) of a local VNI. The VNI changes we care
4449 * about are for the local-tunnel-ip and the (tenant) VRF.
4451 int bgp_evpn_local_vni_add(struct bgp
*bgp
, vni_t vni
,
4452 struct in_addr originator_ip
, vrf_id_t tenant_vrf_id
)
4454 struct bgpevpn
*vpn
;
4455 struct prefix_evpn p
;
4457 if (!bgp
->vnihash
) {
4458 zlog_err("%u: VNI hash not created", bgp
->vrf_id
);
4462 /* Lookup VNI. If present and no change, exit. */
4463 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
4466 if (is_vni_live(vpn
)
4467 && IPV4_ADDR_SAME(&vpn
->originator_ip
, &originator_ip
)
4468 && vpn
->tenant_vrf_id
== tenant_vrf_id
)
4469 /* Probably some other param has changed that we don't
4473 /* Update tenant_vrf_id if it has changed. */
4474 if (vpn
->tenant_vrf_id
!= tenant_vrf_id
) {
4475 bgpevpn_unlink_from_l3vni(vpn
);
4476 vpn
->tenant_vrf_id
= tenant_vrf_id
;
4477 bgpevpn_link_to_l3vni(vpn
);
4480 /* If tunnel endpoint IP has changed, update (and delete prior
4481 * type-3 route, if needed.)
4483 if (!IPV4_ADDR_SAME(&vpn
->originator_ip
, &originator_ip
))
4484 handle_tunnel_ip_change(bgp
, vpn
, originator_ip
);
4486 /* Update all routes with new endpoint IP and/or export RT
4489 if (is_vni_live(vpn
))
4490 update_routes_for_vni(bgp
, vpn
);
4493 /* Create or update as appropriate. */
4495 vpn
= bgp_evpn_new(bgp
, vni
, originator_ip
, tenant_vrf_id
);
4498 "%u: Failed to allocate VNI entry for VNI %u - at Add",
4504 /* if the VNI is live already, there is nothing more to do */
4505 if (is_vni_live(vpn
))
4508 /* Mark as "live" */
4509 SET_FLAG(vpn
->flags
, VNI_FLAG_LIVE
);
4511 /* tunnel is now active, add tunnel-ip to db */
4512 bgp_tip_add(bgp
, &originator_ip
);
4514 /* filter routes as nexthop database has changed */
4515 bgp_filter_evpn_routes_upon_martian_nh_change(bgp
);
4517 /* Create EVPN type-3 route and schedule for processing. */
4518 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
4519 if (update_evpn_route(bgp
, vpn
, &p
, 0)) {
4520 zlog_err("%u: Type3 route creation failure for VNI %u",
4525 /* If we have learnt and retained remote routes (VTEPs, MACs) for this
4529 install_routes_for_vni(bgp
, vpn
);
4531 /* If we are advertising gateway mac-ip
4532 It needs to be conveyed again to zebra */
4533 bgp_zebra_advertise_gw_macip(bgp
, vpn
->advertise_gw_macip
, vpn
->vni
);
4539 * Cleanup EVPN information on disable - Need to delete and withdraw
4540 * EVPN routes from peers.
4542 void bgp_evpn_cleanup_on_disable(struct bgp
*bgp
)
4544 hash_iterate(bgp
->vnihash
, (void (*)(struct hash_backet
*,
4545 void *))cleanup_vni_on_disable
,
4550 * Cleanup EVPN information - invoked at the time of bgpd exit or when the
4551 * BGP instance (default) is being freed.
4553 void bgp_evpn_cleanup(struct bgp
*bgp
)
4556 hash_iterate(bgp
->vnihash
, (void (*)(struct hash_backet
*,
4557 void *))free_vni_entry
,
4559 if (bgp
->import_rt_hash
)
4560 hash_free(bgp
->import_rt_hash
);
4561 bgp
->import_rt_hash
= NULL
;
4562 if (bgp
->vrf_import_rt_hash
)
4563 hash_free(bgp
->vrf_import_rt_hash
);
4564 bgp
->vrf_import_rt_hash
= NULL
;
4566 hash_free(bgp
->vnihash
);
4567 bgp
->vnihash
= NULL
;
4568 if (bgp
->vrf_import_rtl
)
4569 list_delete_and_null(&bgp
->vrf_import_rtl
);
4570 if (bgp
->vrf_export_rtl
)
4571 list_delete_and_null(&bgp
->vrf_export_rtl
);
4573 list_delete_and_null(&bgp
->l2vnis
);
4577 * Initialization for EVPN
4580 * hash for RT to VNI
4582 void bgp_evpn_init(struct bgp
*bgp
)
4585 hash_create(vni_hash_key_make
, vni_hash_cmp
, "BGP VNI Hash");
4586 bgp
->import_rt_hash
=
4587 hash_create(import_rt_hash_key_make
, import_rt_hash_cmp
,
4588 "BGP Import RT Hash");
4589 bgp
->vrf_import_rt_hash
=
4590 hash_create(vrf_import_rt_hash_key_make
, vrf_import_rt_hash_cmp
,
4591 "BGP VRF Import RT Hash");
4592 bgp
->vrf_import_rtl
= list_new();
4593 bgp
->vrf_import_rtl
->cmp
=
4594 (int (*)(void *, void *))evpn_route_target_cmp
;
4596 bgp
->vrf_export_rtl
= list_new();
4597 bgp
->vrf_export_rtl
->cmp
=
4598 (int (*)(void *, void *))evpn_route_target_cmp
;
4599 bgp
->l2vnis
= list_new();
4600 bgp
->l2vnis
->cmp
= (int (*)(void *, void *))vni_hash_cmp
;
4603 void bgp_evpn_vrf_delete(struct bgp
*bgp_vrf
)
4605 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf
);