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
35 #include "bgpd/bgp_attr_evpn.h"
36 #include "bgpd/bgpd.h"
37 #include "bgpd/bgp_table.h"
38 #include "bgpd/bgp_route.h"
39 #include "bgpd/bgp_attr.h"
40 #include "bgpd/bgp_mplsvpn.h"
41 #include "bgpd/bgp_label.h"
42 #include "bgpd/bgp_evpn.h"
43 #include "bgpd/bgp_evpn_private.h"
44 #include "bgpd/bgp_ecommunity.h"
45 #include "bgpd/bgp_encap_types.h"
46 #include "bgpd/bgp_debug.h"
47 #include "bgpd/bgp_aspath.h"
48 #include "bgpd/bgp_zebra.h"
49 #include "bgpd/bgp_nexthop.h"
52 * Definitions and external declarations.
54 extern struct zclient
*zclient
;
56 DEFINE_QOBJ_TYPE(bgpevpn
)
60 * Static function declarations
62 static void delete_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
63 afi_t afi
, safi_t safi
, struct bgp_node
*rn
,
64 struct bgp_info
**ri
);
65 static int delete_all_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
);
74 static unsigned int vni_hash_key_make(void *p
)
76 struct bgpevpn
*vpn
= p
;
77 return (jhash_1word(vpn
->vni
, 0));
81 * Comparison function for vni hash
83 static int vni_hash_cmp(const void *p1
, const void *p2
)
85 const struct bgpevpn
*vpn1
= p1
;
86 const struct bgpevpn
*vpn2
= p2
;
92 return (vpn1
->vni
== vpn2
->vni
);
96 * Make import route target hash key.
98 static unsigned int import_rt_hash_key_make(void *p
)
100 struct irt_node
*irt
= p
;
101 char *pnt
= irt
->rt
.val
;
102 unsigned int key
= 0;
118 * Comparison function for import rt hash
120 static int import_rt_hash_cmp(const void *p1
, const void *p2
)
122 const struct irt_node
*irt1
= p1
;
123 const struct irt_node
*irt2
= p2
;
125 if (irt1
== NULL
&& irt2
== NULL
)
128 if (irt1
== NULL
|| irt2
== NULL
)
131 return (memcmp(irt1
->rt
.val
, irt2
->rt
.val
, ECOMMUNITY_SIZE
) == 0);
135 * Create a new import_rt
137 static struct irt_node
*import_rt_new(struct bgp
*bgp
,
138 struct ecommunity_val
*rt
)
140 struct irt_node
*irt
;
145 irt
= XCALLOC(MTYPE_BGP_EVPN_IMPORT_RT
, sizeof(struct irt_node
));
150 irt
->vnis
= list_new();
153 if (!hash_get(bgp
->import_rt_hash
, irt
, hash_alloc_intern
)) {
154 XFREE(MTYPE_BGP_EVPN_IMPORT_RT
, irt
);
162 * Free the import rt node
164 static void import_rt_free(struct bgp
*bgp
, struct irt_node
*irt
)
166 hash_release(bgp
->import_rt_hash
, irt
);
167 XFREE(MTYPE_BGP_EVPN_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 irt_node
*lookup_import_rt(struct bgp
*bgp
,
175 struct ecommunity_val
*rt
)
177 struct irt_node
*irt
;
180 memset(&tmp
, 0, sizeof(struct irt_node
));
181 memcpy(&tmp
.rt
, rt
, ECOMMUNITY_SIZE
);
182 irt
= hash_lookup(bgp
->import_rt_hash
, &tmp
);
187 * Is specified VNI present on the RT's list of "importing" VNIs?
189 static int is_vni_present_in_irt_vnis(struct list
*vnis
, struct bgpevpn
*vpn
)
191 struct listnode
*node
, *nnode
;
192 struct bgpevpn
*tmp_vpn
;
194 for (ALL_LIST_ELEMENTS(vnis
, node
, nnode
, tmp_vpn
)) {
203 * Compare Route Targets.
205 static int evpn_route_target_cmp(struct ecommunity
*ecom1
,
206 struct ecommunity
*ecom2
)
214 if (!ecom1
&& !ecom2
)
217 if (ecom1
->str
&& !ecom2
->str
)
220 if (!ecom1
->str
&& ecom2
->str
)
223 if (!ecom1
->str
&& !ecom2
->str
)
226 return strcmp(ecom1
->str
, ecom2
->str
);
230 * Mask off global-admin field of specified extended community (RT),
231 * just retain the local-admin field.
233 static inline void mask_ecom_global_admin(struct ecommunity_val
*dst
,
234 struct ecommunity_val
*src
)
240 if (type
== ECOMMUNITY_ENCODE_AS
) {
241 dst
->val
[2] = dst
->val
[3] = 0;
242 } else if (type
== ECOMMUNITY_ENCODE_AS4
243 || type
== ECOMMUNITY_ENCODE_IP
) {
244 dst
->val
[2] = dst
->val
[3] = 0;
245 dst
->val
[4] = dst
->val
[5] = 0;
250 * Map one RT to specified VNI.
252 static void map_vni_to_rt(struct bgp
*bgp
, struct bgpevpn
*vpn
,
253 struct ecommunity_val
*eval
)
255 struct irt_node
*irt
;
256 struct ecommunity_val eval_tmp
;
258 /* If using "automatic" RT, we only care about the local-admin
260 * This is to facilitate using VNI as the RT for EBGP peering too.
262 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
263 if (!is_import_rt_configured(vpn
))
264 mask_ecom_global_admin(&eval_tmp
, eval
);
266 irt
= lookup_import_rt(bgp
, &eval_tmp
);
267 if (irt
&& irt
->vnis
)
268 if (is_vni_present_in_irt_vnis(irt
->vnis
, vpn
))
269 /* Already mapped. */
273 irt
= import_rt_new(bgp
, &eval_tmp
);
277 /* Add VNI to the hash list for this RT. */
278 listnode_add(irt
->vnis
, vpn
);
282 * Unmap specified VNI from specified RT. If there are no other
283 * VNIs for this RT, then the RT hash is deleted.
285 static void unmap_vni_from_rt(struct bgp
*bgp
, struct bgpevpn
*vpn
,
286 struct irt_node
*irt
)
288 /* Delete VNI from hash list for this RT. */
289 listnode_delete(irt
->vnis
, vpn
);
290 if (!listnode_head(irt
->vnis
)) {
291 list_delete_and_null(&irt
->vnis
);
292 import_rt_free(bgp
, irt
);
297 * Create RT extended community automatically from passed information:
298 * of the form AS:VNI.
299 * NOTE: We use only the lower 16 bits of the AS. This is sufficient as
300 * the need is to get a RT value that will be unique across different
301 * VNIs but the same across routers (in the same AS) for a particular
304 static void form_auto_rt(struct bgp
*bgp
, struct bgpevpn
*vpn
, struct list
*rtl
)
306 struct ecommunity_val eval
;
307 struct ecommunity
*ecomadd
;
309 encode_route_target_as((bgp
->as
& 0xFFFF), vpn
->vni
, &eval
);
311 ecomadd
= ecommunity_new();
312 ecommunity_add_val(ecomadd
, &eval
);
313 listnode_add_sort(rtl
, ecomadd
);
317 * Derive RD and RT for a VNI automatically. Invoked at the time of
320 static void derive_rd_rt_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
322 bgp_evpn_derive_auto_rd(bgp
, vpn
);
323 bgp_evpn_derive_auto_rt_import(bgp
, vpn
);
324 bgp_evpn_derive_auto_rt_export(bgp
, vpn
);
328 * Add (update) or delete MACIP from zebra.
330 static int bgp_zebra_send_remote_macip(struct bgp
*bgp
, struct bgpevpn
*vpn
,
331 struct prefix_evpn
*p
,
332 struct in_addr remote_vtep_ip
, int add
,
337 char buf1
[ETHER_ADDR_STRLEN
];
338 char buf2
[INET6_ADDRSTRLEN
];
339 char buf3
[INET6_ADDRSTRLEN
];
342 if (!zclient
|| zclient
->sock
< 0)
345 /* Don't try to register if Zebra doesn't know of this instance. */
346 if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
352 zclient_create_header(s
, add
? ZEBRA_REMOTE_MACIP_ADD
353 : ZEBRA_REMOTE_MACIP_DEL
,
355 stream_putl(s
, vpn
->vni
);
356 stream_put(s
, &p
->prefix
.mac
.octet
, ETH_ALEN
); /* Mac Addr */
357 /* IP address length and IP address, if any. */
358 if (IS_EVPN_PREFIX_IPADDR_NONE(p
))
361 ipa_len
= IS_EVPN_PREFIX_IPADDR_V4(p
) ? IPV4_MAX_BYTELEN
363 stream_putl(s
, ipa_len
);
364 stream_put(s
, &p
->prefix
.ip
.ip
.addr
, ipa_len
);
366 stream_put_in_addr(s
, &remote_vtep_ip
);
368 /* TX MAC sticky status */
370 stream_putc(s
, sticky
);
372 stream_putw_at(s
, 0, stream_get_endp(s
));
374 if (bgp_debug_zebra(NULL
))
375 zlog_debug("Tx %s MACIP, VNI %u %sMAC %s IP %s remote VTEP %s",
376 add
? "ADD" : "DEL", vpn
->vni
,
377 sticky
? "sticky " : "",
378 prefix_mac2str(&p
->prefix
.mac
, buf1
, sizeof(buf1
)),
379 ipaddr2str(&p
->prefix
.ip
, buf3
, sizeof(buf3
)),
380 inet_ntop(AF_INET
, &remote_vtep_ip
, buf2
,
383 return zclient_send_message(zclient
);
387 * Add (update) or delete remote VTEP from zebra.
389 static int bgp_zebra_send_remote_vtep(struct bgp
*bgp
, struct bgpevpn
*vpn
,
390 struct prefix_evpn
*p
, int add
)
395 if (!zclient
|| zclient
->sock
< 0)
398 /* Don't try to register if Zebra doesn't know of this instance. */
399 if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
405 zclient_create_header(s
, add
? ZEBRA_REMOTE_VTEP_ADD
406 : ZEBRA_REMOTE_VTEP_DEL
,
408 stream_putl(s
, vpn
->vni
);
409 if (IS_EVPN_PREFIX_IPADDR_V4(p
))
410 stream_put_in_addr(s
, &p
->prefix
.ip
.ipaddr_v4
);
411 else if (IS_EVPN_PREFIX_IPADDR_V6(p
)) {
413 "Bad remote IP when trying to %s remote VTEP for VNI %u",
414 add
? "ADD" : "DEL", vpn
->vni
);
418 stream_putw_at(s
, 0, stream_get_endp(s
));
420 if (bgp_debug_zebra(NULL
))
421 zlog_debug("Tx %s Remote VTEP, VNI %u remote VTEP %s",
422 add
? "ADD" : "DEL", vpn
->vni
,
423 inet_ntoa(p
->prefix
.ip
.ipaddr_v4
));
425 return zclient_send_message(zclient
);
429 * Build extended communities for EVPN route. RT and ENCAP are
430 * applicable to all routes.
432 static void build_evpn_route_extcomm(struct bgpevpn
*vpn
, struct attr
*attr
)
434 struct ecommunity ecom_encap
;
435 struct ecommunity ecom_sticky
;
436 struct ecommunity_val eval
;
437 struct ecommunity_val eval_sticky
;
438 bgp_encap_types tnl_type
;
439 struct listnode
*node
, *nnode
;
440 struct ecommunity
*ecom
;
444 tnl_type
= BGP_ENCAP_TYPE_VXLAN
;
445 memset(&ecom_encap
, 0, sizeof(ecom_encap
));
446 encode_encap_extcomm(tnl_type
, &eval
);
448 ecom_encap
.val
= (u_int8_t
*)eval
.val
;
451 attr
->ecommunity
= ecommunity_dup(&ecom_encap
);
453 /* Add the export RTs */
454 for (ALL_LIST_ELEMENTS(vpn
->export_rtl
, node
, nnode
, ecom
))
455 attr
->ecommunity
= ecommunity_merge(attr
->ecommunity
, ecom
);
459 memset(&ecom_sticky
, 0, sizeof(ecom_sticky
));
460 encode_mac_mobility_extcomm(1, seqnum
, &eval_sticky
);
461 ecom_sticky
.size
= 1;
462 ecom_sticky
.val
= (u_int8_t
*)eval_sticky
.val
;
464 ecommunity_merge(attr
->ecommunity
, &ecom_sticky
);
467 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
);
471 * Add MAC mobility extended community to attribute.
473 static void add_mac_mobility_to_attr(u_int32_t seq_num
, struct attr
*attr
)
475 struct ecommunity ecom_tmp
;
476 struct ecommunity_val eval
;
477 u_int8_t
*ecom_val_ptr
;
484 encode_mac_mobility_extcomm(0, seq_num
, &eval
);
486 /* Find current MM ecommunity */
489 if (attr
->ecommunity
) {
490 for (i
= 0; i
< attr
->ecommunity
->size
; i
++) {
491 pnt
= attr
->ecommunity
->val
+ (i
* 8);
495 if (type
== ECOMMUNITY_ENCODE_EVPN
497 == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY
) {
499 (u_int8_t
*)(attr
->ecommunity
->val
506 /* Update the existing MM ecommunity */
508 memcpy(ecom_val_ptr
, eval
.val
, sizeof(char) * ECOMMUNITY_SIZE
);
510 /* Add MM to existing */
512 memset(&ecom_tmp
, 0, sizeof(ecom_tmp
));
514 ecom_tmp
.val
= (u_int8_t
*)eval
.val
;
517 ecommunity_merge(attr
->ecommunity
, &ecom_tmp
);
521 /* Install EVPN route into zebra. */
522 static int evpn_zebra_install(struct bgp
*bgp
, struct bgpevpn
*vpn
,
523 struct prefix_evpn
*p
,
524 struct in_addr remote_vtep_ip
, u_char sticky
)
528 if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
)
529 ret
= bgp_zebra_send_remote_macip(bgp
, vpn
, p
, remote_vtep_ip
,
532 ret
= bgp_zebra_send_remote_vtep(bgp
, vpn
, p
, 1);
537 /* Uninstall EVPN route from zebra. */
538 static int evpn_zebra_uninstall(struct bgp
*bgp
, struct bgpevpn
*vpn
,
539 struct prefix_evpn
*p
,
540 struct in_addr remote_vtep_ip
)
544 if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
)
545 ret
= bgp_zebra_send_remote_macip(bgp
, vpn
, p
, remote_vtep_ip
,
548 ret
= bgp_zebra_send_remote_vtep(bgp
, vpn
, p
, 0);
554 * Due to MAC mobility, the prior "local" best route has been supplanted
555 * by a "remote" best route. The prior route has to be deleted and withdrawn
558 static void evpn_delete_old_local_route(struct bgp
*bgp
, struct bgpevpn
*vpn
,
560 struct bgp_info
*old_local
)
562 struct bgp_node
*global_rn
;
564 afi_t afi
= AFI_L2VPN
;
565 safi_t safi
= SAFI_EVPN
;
567 /* Locate route node in the global EVPN routing table. Note that
568 * this table is a 2-level tree (RD-level + Prefix-level) similar to
571 global_rn
= bgp_afi_node_lookup(bgp
->rib
[afi
][safi
], afi
, safi
,
572 (struct prefix
*)&rn
->p
, &vpn
->prd
);
574 /* Delete route entry in the global EVPN table. */
575 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, &ri
);
577 /* Schedule for processing - withdraws to peers happen from
581 bgp_process(bgp
, global_rn
, afi
, safi
);
582 bgp_unlock_node(global_rn
);
585 /* Delete route entry in the VNI route table, caller to remove. */
586 bgp_info_delete(rn
, old_local
);
590 * Calculate the best path for an EVPN route. Install/update best path in zebra,
593 static int evpn_route_select_install(struct bgp
*bgp
, struct bgpevpn
*vpn
,
596 struct bgp_info
*old_select
, *new_select
;
597 struct bgp_info_pair old_and_new
;
598 afi_t afi
= AFI_L2VPN
;
599 safi_t safi
= SAFI_EVPN
;
602 /* Compute the best path. */
603 bgp_best_selection(bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
,
605 old_select
= old_and_new
.old
;
606 new_select
= old_and_new
.new;
608 /* If the best path hasn't changed - see if there is still something to
612 if (old_select
&& old_select
== new_select
613 && old_select
->type
== ZEBRA_ROUTE_BGP
614 && old_select
->sub_type
== BGP_ROUTE_NORMAL
615 && !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
)
616 && !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
)
617 && !bgp
->addpath_tx_used
[afi
][safi
]) {
618 if (bgp_zebra_has_route_changed(rn
, old_select
))
619 ret
= evpn_zebra_install(bgp
, vpn
,
620 (struct prefix_evpn
*)&rn
->p
,
621 old_select
->attr
->nexthop
,
622 old_select
->attr
->sticky
);
623 UNSET_FLAG(old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
624 bgp_zebra_clear_route_change_flags(rn
);
628 /* If the user did a "clear" this flag will be set */
629 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
631 /* bestpath has changed; update relevant fields and install or uninstall
632 * into the zebra RIB.
634 if (old_select
|| new_select
)
635 bgp_bump_version(rn
);
638 bgp_info_unset_flag(rn
, old_select
, BGP_INFO_SELECTED
);
640 bgp_info_set_flag(rn
, new_select
, BGP_INFO_SELECTED
);
641 bgp_info_unset_flag(rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
642 UNSET_FLAG(new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
645 if (new_select
&& new_select
->type
== ZEBRA_ROUTE_BGP
646 && new_select
->sub_type
== BGP_ROUTE_NORMAL
) {
647 ret
= evpn_zebra_install(bgp
, vpn
, (struct prefix_evpn
*)&rn
->p
,
648 new_select
->attr
->nexthop
,
649 new_select
->attr
->sticky
);
650 /* If an old best existed and it was a "local" route, the only
652 * it would be supplanted is due to MAC mobility procedures. So,
654 * need to do an implicit delete and withdraw that route from
657 if (old_select
&& old_select
->peer
== bgp
->peer_self
658 && old_select
->type
== ZEBRA_ROUTE_BGP
659 && old_select
->sub_type
== BGP_ROUTE_STATIC
)
660 evpn_delete_old_local_route(bgp
, vpn
, rn
, old_select
);
662 if (old_select
&& old_select
->type
== ZEBRA_ROUTE_BGP
663 && old_select
->sub_type
== BGP_ROUTE_NORMAL
)
664 ret
= evpn_zebra_uninstall(bgp
, vpn
,
665 (struct prefix_evpn
*)&rn
->p
,
666 old_select
->attr
->nexthop
);
669 /* Clear any route change flags. */
670 bgp_zebra_clear_route_change_flags(rn
);
672 /* Reap old select bgp_info, if it has been removed */
673 if (old_select
&& CHECK_FLAG(old_select
->flags
, BGP_INFO_REMOVED
))
674 bgp_info_reap(rn
, old_select
);
681 * Return true if the local ri for this rn has sticky set
683 static int evpn_route_is_sticky(struct bgp
*bgp
, struct bgp_node
*rn
)
685 struct bgp_info
*tmp_ri
;
686 struct bgp_info
*local_ri
;
689 for (tmp_ri
= rn
->info
; tmp_ri
; tmp_ri
= tmp_ri
->next
) {
690 if (tmp_ri
->peer
== bgp
->peer_self
691 && tmp_ri
->type
== ZEBRA_ROUTE_BGP
692 && tmp_ri
->sub_type
== BGP_ROUTE_STATIC
)
699 return local_ri
->attr
->sticky
;
703 * Create or update EVPN route entry. This could be in the VNI route table
704 * or the global route table.
706 static int update_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
707 afi_t afi
, safi_t safi
, struct bgp_node
*rn
,
708 struct attr
*attr
, int add
, int vni_table
,
709 struct bgp_info
**ri
, u_char flags
)
711 struct bgp_info
*tmp_ri
;
712 struct bgp_info
*local_ri
, *remote_ri
;
713 struct attr
*attr_new
;
714 mpls_label_t label
= MPLS_INVALID_LABEL
;
715 int route_change
= 1;
720 /* See if this is an update of an existing route, or a new add. Also,
721 * identify if already known from remote, and if so, the one with the
722 * highest sequence number; this is only when adding to the VNI routing
725 local_ri
= remote_ri
= NULL
;
726 for (tmp_ri
= rn
->info
; tmp_ri
; tmp_ri
= tmp_ri
->next
) {
727 if (tmp_ri
->peer
== bgp
->peer_self
728 && tmp_ri
->type
== ZEBRA_ROUTE_BGP
729 && tmp_ri
->sub_type
== BGP_ROUTE_STATIC
)
732 if (tmp_ri
->type
== ZEBRA_ROUTE_BGP
733 && tmp_ri
->sub_type
== BGP_ROUTE_NORMAL
734 && CHECK_FLAG(tmp_ri
->flags
, BGP_INFO_VALID
)) {
737 else if (mac_mobility_seqnum(tmp_ri
->attr
)
738 > mac_mobility_seqnum(remote_ri
->attr
))
744 /* If route doesn't exist already, create a new one, if told to.
745 * Otherwise act based on whether the attributes of the route have
748 if (!local_ri
&& !add
)
752 /* When learnt locally for the first time but already known from
753 * remote, we have to initiate appropriate MAC mobility steps.
755 * is applicable when updating the VNI routing table.
756 * We need to skip mobility steps for g/w macs (local mac on g/w
757 * SVI) advertised in EVPN.
758 * This will ensure that local routes are preferred for g/w macs
760 if (remote_ri
&& !CHECK_FLAG(flags
, ZEBRA_MAC_TYPE_GW
)) {
761 u_int32_t cur_seqnum
;
763 /* Add MM extended community to route. */
764 cur_seqnum
= mac_mobility_seqnum(remote_ri
->attr
);
765 add_mac_mobility_to_attr(cur_seqnum
+ 1, attr
);
768 /* Add (or update) attribute to hash. */
769 attr_new
= bgp_attr_intern(attr
);
771 /* Extract MAC mobility sequence number, if any. */
772 attr_new
->mm_seqnum
=
773 bgp_attr_mac_mobility_seqnum(attr_new
, &sticky
);
774 attr_new
->sticky
= sticky
;
776 /* Create new route with its attribute. */
777 tmp_ri
= info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0,
778 bgp
->peer_self
, attr_new
, rn
);
779 SET_FLAG(tmp_ri
->flags
, BGP_INFO_VALID
);
780 bgp_info_extra_get(tmp_ri
);
782 /* The VNI goes into the 'label' field of the route */
783 vni2label(vpn
->vni
, &label
);
785 memcpy(&tmp_ri
->extra
->label
, &label
, BGP_LABEL_BYTES
);
786 bgp_info_add(rn
, tmp_ri
);
789 if (attrhash_cmp(tmp_ri
->attr
, attr
)
790 && !CHECK_FLAG(tmp_ri
->flags
, BGP_INFO_REMOVED
))
793 /* The attribute has changed. */
794 /* Add (or update) attribute to hash. */
795 attr_new
= bgp_attr_intern(attr
);
796 bgp_info_set_flag(rn
, tmp_ri
, BGP_INFO_ATTR_CHANGED
);
798 /* Restore route, if needed. */
799 if (CHECK_FLAG(tmp_ri
->flags
, BGP_INFO_REMOVED
))
800 bgp_info_restore(rn
, tmp_ri
);
802 /* Unintern existing, set to new. */
803 bgp_attr_unintern(&tmp_ri
->attr
);
804 tmp_ri
->attr
= attr_new
;
805 tmp_ri
->uptime
= bgp_clock();
809 /* Return back the route entry. */
815 * Create or update EVPN route (of type based on prefix) for specified VNI
816 * and schedule for processing.
818 static int update_evpn_route(struct bgp
*bgp
, struct bgpevpn
*vpn
,
819 struct prefix_evpn
*p
, u_char flags
)
823 struct attr
*attr_new
;
825 afi_t afi
= AFI_L2VPN
;
826 safi_t safi
= SAFI_EVPN
;
829 memset(&attr
, 0, sizeof(struct attr
));
831 /* Build path-attribute for this route. */
832 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
833 attr
.nexthop
= vpn
->originator_ip
;
834 attr
.mp_nexthop_global_in
= vpn
->originator_ip
;
835 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
836 attr
.sticky
= CHECK_FLAG(flags
, ZEBRA_MAC_TYPE_STICKY
) ? 1 : 0;
837 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL
);
838 vni2label(vpn
->vni
, &(attr
.label
));
840 /* Set up RT and ENCAP extended community. */
841 build_evpn_route_extcomm(vpn
, &attr
);
843 /* First, create (or fetch) route node within the VNI. */
844 /* NOTE: There is no RD here. */
845 rn
= bgp_node_get(vpn
->route_table
, (struct prefix
*)p
);
847 /* Create or update route entry. */
848 route_change
= update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &attr
,
853 /* Perform route selection; this is just to set the flags correctly
854 * as local route in the VNI always wins.
856 evpn_route_select_install(bgp
, vpn
, rn
);
859 /* If this is a new route or some attribute has changed, export the
860 * route to the global table. The route will be advertised to peers
861 * from there. Note that this table is a 2-level tree (RD-level +
862 * Prefix-level) similar to L3VPN routes.
865 struct bgp_info
*global_ri
;
867 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
868 (struct prefix
*)p
, &vpn
->prd
);
869 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, attr_new
, 1, 0,
872 /* Schedule for processing and unlock node. */
873 bgp_process(bgp
, rn
, afi
, safi
);
877 /* Unintern temporary. */
878 aspath_unintern(&attr
.aspath
);
884 * Delete EVPN route entry. This could be in the VNI route table
885 * or the global route table.
887 static void delete_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
888 afi_t afi
, safi_t safi
, struct bgp_node
*rn
,
889 struct bgp_info
**ri
)
891 struct bgp_info
*tmp_ri
;
895 /* Now, find matching route. */
896 for (tmp_ri
= rn
->info
; tmp_ri
; tmp_ri
= tmp_ri
->next
)
897 if (tmp_ri
->peer
== bgp
->peer_self
898 && tmp_ri
->type
== ZEBRA_ROUTE_BGP
899 && tmp_ri
->sub_type
== BGP_ROUTE_STATIC
)
904 /* Mark route for delete. */
906 bgp_info_delete(rn
, tmp_ri
);
910 * Delete EVPN route (of type based on prefix) for specified VNI and
911 * schedule for processing.
913 static int delete_evpn_route(struct bgp
*bgp
, struct bgpevpn
*vpn
,
914 struct prefix_evpn
*p
)
916 struct bgp_node
*rn
, *global_rn
;
918 afi_t afi
= AFI_L2VPN
;
919 safi_t safi
= SAFI_EVPN
;
921 /* First, locate the route node within the VNI. If it doesn't exist,
923 * is nothing further to do.
925 /* NOTE: There is no RD here. */
926 rn
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)p
);
930 /* Next, locate route node in the global EVPN routing table. Note that
931 * this table is a 2-level tree (RD-level + Prefix-level) similar to
934 global_rn
= bgp_afi_node_lookup(bgp
->rib
[afi
][safi
], afi
, safi
,
935 (struct prefix
*)p
, &vpn
->prd
);
937 /* Delete route entry in the global EVPN table. */
938 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, &ri
);
940 /* Schedule for processing - withdraws to peers happen from
944 bgp_process(bgp
, global_rn
, afi
, safi
);
945 bgp_unlock_node(global_rn
);
948 /* Delete route entry in the VNI route table. This can just be removed.
950 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &ri
);
952 bgp_info_reap(rn
, ri
);
959 * Update all type-2 (MACIP) local routes for this VNI - these should also
960 * be scheduled for advertise to peers.
962 static int update_all_type2_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
969 struct attr attr_sticky
;
970 struct attr
*attr_new
;
974 memset(&attr
, 0, sizeof(struct attr
));
975 memset(&attr_sticky
, 0, sizeof(struct attr
));
977 /* Build path-attribute - all type-2 routes for this VNI will share the
978 * same path attribute.
980 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
981 bgp_attr_default_set(&attr_sticky
, BGP_ORIGIN_IGP
);
982 attr
.nexthop
= vpn
->originator_ip
;
983 attr
.mp_nexthop_global_in
= vpn
->originator_ip
;
984 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
985 attr_sticky
.nexthop
= vpn
->originator_ip
;
986 attr_sticky
.mp_nexthop_global_in
= vpn
->originator_ip
;
987 attr_sticky
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
988 attr_sticky
.sticky
= 1;
990 /* Set up RT, ENCAP and sticky MAC extended community. */
991 build_evpn_route_extcomm(vpn
, &attr
);
992 build_evpn_route_extcomm(vpn
, &attr_sticky
);
994 /* Walk this VNI's route table and update local type-2 routes. For any
995 * routes updated, update corresponding entry in the global table too.
997 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
998 rn
= bgp_route_next(rn
)) {
999 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
1000 struct bgp_node
*rd_rn
;
1001 struct bgp_info
*global_ri
;
1003 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
1006 if (evpn_route_is_sticky(bgp
, rn
))
1007 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
,
1008 &attr_sticky
, 0, 1, &ri
, 0);
1010 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &attr
,
1013 /* If a local route exists for this prefix, we need to update
1014 * the global routing table too.
1019 /* Perform route selection; this is just to set the flags
1021 * as local route in the VNI always wins.
1023 evpn_route_select_install(bgp
, vpn
, rn
);
1025 attr_new
= ri
->attr
;
1027 /* Update route in global routing table. */
1028 rd_rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
1029 (struct prefix
*)evp
, &vpn
->prd
);
1031 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rd_rn
, attr_new
, 0,
1034 /* Schedule for processing and unlock node. */
1035 bgp_process(bgp
, rd_rn
, afi
, safi
);
1036 bgp_unlock_node(rd_rn
);
1039 /* Unintern temporary. */
1040 aspath_unintern(&attr
.aspath
);
1041 aspath_unintern(&attr_sticky
.aspath
);
1047 * Delete all type-2 (MACIP) local routes for this VNI - only from the
1048 * global routing table. These are also scheduled for withdraw from peers.
1050 static int delete_global_type2_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1054 struct bgp_node
*rdrn
, *rn
;
1055 struct bgp_table
*table
;
1056 struct bgp_info
*ri
;
1061 rdrn
= bgp_node_lookup(bgp
->rib
[afi
][safi
], (struct prefix
*)&vpn
->prd
);
1062 if (rdrn
&& rdrn
->info
) {
1063 table
= (struct bgp_table
*)rdrn
->info
;
1064 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
1065 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
1067 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
1070 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &ri
);
1072 bgp_process(bgp
, rn
, afi
, safi
);
1076 /* Unlock RD node. */
1078 bgp_unlock_node(rdrn
);
1084 * Delete all type-2 (MACIP) local routes for this VNI - from the global
1085 * table as well as the per-VNI route table.
1087 static int delete_all_type2_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1091 struct bgp_node
*rn
;
1092 struct bgp_info
*ri
;
1097 /* First, walk the global route table for this VNI's type-2 local
1099 * EVPN routes are a 2-level table, first get the RD table.
1101 delete_global_type2_routes(bgp
, vpn
);
1103 /* Next, walk this VNI's route table and delete local type-2 routes. */
1104 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
1105 rn
= bgp_route_next(rn
)) {
1106 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
1108 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
1111 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &ri
);
1113 /* Route entry in local table gets deleted immediately. */
1115 bgp_info_reap(rn
, ri
);
1122 * Delete all routes in the per-VNI route table.
1124 static int delete_all_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1126 struct bgp_node
*rn
;
1127 struct bgp_info
*ri
, *nextri
;
1129 /* Walk this VNI's route table and delete all routes. */
1130 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
1131 rn
= bgp_route_next(rn
)) {
1132 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1);
1134 bgp_info_delete(rn
, ri
);
1135 bgp_info_reap(rn
, ri
);
1143 * Update (and advertise) local routes for a VNI. Invoked upon the VNI
1144 * export RT getting modified or change to tunnel IP. Note that these
1145 * situations need the route in the per-VNI table as well as the global
1146 * table to be updated (as attributes change).
1148 static int update_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1151 struct prefix_evpn p
;
1153 /* Update and advertise the type-3 route (only one) followed by the
1154 * locally learnt type-2 routes (MACIP) - for this VNI.
1156 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
1157 ret
= update_evpn_route(bgp
, vpn
, &p
, 0);
1161 return update_all_type2_routes(bgp
, vpn
);
1165 * Delete (and withdraw) local routes for specified VNI from the global
1166 * table and per-VNI table. After this, remove all other routes from
1167 * the per-VNI table. Invoked upon the VNI being deleted or EVPN
1168 * (advertise-all-vni) being disabled.
1170 static int delete_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1173 struct prefix_evpn p
;
1175 /* Delete and withdraw locally learnt type-2 routes (MACIP)
1176 * followed by type-3 routes (only one) - for this VNI.
1178 ret
= delete_all_type2_routes(bgp
, vpn
);
1182 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
1183 ret
= delete_evpn_route(bgp
, vpn
, &p
);
1187 /* Delete all routes from the per-VNI table. */
1188 return delete_all_vni_routes(bgp
, vpn
);
1192 * There is a tunnel endpoint IP address change for this VNI,
1193 * need to re-advertise routes with the new nexthop.
1195 static int handle_tunnel_ip_change(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1196 struct in_addr originator_ip
)
1198 struct prefix_evpn p
;
1200 /* If VNI is not live, we only need to update the originator ip */
1201 if (!is_vni_live(vpn
)) {
1202 vpn
->originator_ip
= originator_ip
;
1206 /* Update the tunnel-ip hash */
1207 bgp_tip_del(bgp
, &vpn
->originator_ip
);
1208 bgp_tip_add(bgp
, &originator_ip
);
1210 /* filter routes as martian nexthop db has changed */
1211 bgp_filter_evpn_routes_upon_martian_nh_change(bgp
);
1213 /* Need to withdraw type-3 route as the originator IP is part
1216 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
1217 delete_evpn_route(bgp
, vpn
, &p
);
1219 /* Update the tunnel IP and re-advertise all routes for this VNI. */
1220 vpn
->originator_ip
= originator_ip
;
1221 return update_routes_for_vni(bgp
, vpn
);
1225 * Install route entry into the VNI routing table and invoke route selection.
1227 static int install_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1228 struct prefix_evpn
*p
,
1229 struct bgp_info
*parent_ri
)
1231 struct bgp_node
*rn
;
1232 struct bgp_info
*ri
;
1233 struct attr
*attr_new
;
1236 /* Create (or fetch) route within the VNI. */
1237 /* NOTE: There is no RD here. */
1238 rn
= bgp_node_get(vpn
->route_table
, (struct prefix
*)p
);
1240 /* Check if route entry is already present. */
1241 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1243 && (struct bgp_info
*)ri
->extra
->parent
== parent_ri
)
1247 /* Add (or update) attribute to hash. */
1248 attr_new
= bgp_attr_intern(parent_ri
->attr
);
1250 /* Create new route with its attribute. */
1251 ri
= info_make(parent_ri
->type
, parent_ri
->sub_type
, 0,
1252 parent_ri
->peer
, attr_new
, rn
);
1253 SET_FLAG(ri
->flags
, BGP_INFO_VALID
);
1254 bgp_info_extra_get(ri
);
1255 ri
->extra
->parent
= parent_ri
;
1256 if (parent_ri
->extra
)
1257 memcpy(&ri
->extra
->label
, &parent_ri
->extra
->label
,
1259 bgp_info_add(rn
, ri
);
1261 if (attrhash_cmp(ri
->attr
, parent_ri
->attr
)
1262 && !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
1263 bgp_unlock_node(rn
);
1266 /* The attribute has changed. */
1267 /* Add (or update) attribute to hash. */
1268 attr_new
= bgp_attr_intern(parent_ri
->attr
);
1270 /* Restore route, if needed. */
1271 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
1272 bgp_info_restore(rn
, ri
);
1274 /* Mark if nexthop has changed. */
1275 if (!IPV4_ADDR_SAME(&ri
->attr
->nexthop
, &attr_new
->nexthop
))
1276 SET_FLAG(ri
->flags
, BGP_INFO_IGP_CHANGED
);
1278 /* Unintern existing, set to new. */
1279 bgp_attr_unintern(&ri
->attr
);
1280 ri
->attr
= attr_new
;
1281 ri
->uptime
= bgp_clock();
1284 /* Perform route selection and update zebra, if required. */
1285 ret
= evpn_route_select_install(bgp
, vpn
, rn
);
1291 * Uninstall route entry from the VNI routing table and send message
1292 * to zebra, if appropriate.
1294 static int uninstall_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1295 struct prefix_evpn
*p
,
1296 struct bgp_info
*parent_ri
)
1298 struct bgp_node
*rn
;
1299 struct bgp_info
*ri
;
1302 /* Locate route within the VNI. */
1303 /* NOTE: There is no RD here. */
1304 rn
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)p
);
1308 /* Find matching route entry. */
1309 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1311 && (struct bgp_info
*)ri
->extra
->parent
== parent_ri
)
1317 /* Mark entry for deletion */
1318 bgp_info_delete(rn
, ri
);
1320 /* Perform route selection and update zebra, if required. */
1321 ret
= evpn_route_select_install(bgp
, vpn
, rn
);
1323 /* Unlock route node. */
1324 bgp_unlock_node(rn
);
1330 * Given a route entry and a VNI, see if this route entry should be
1331 * imported into the VNI i.e., RTs match.
1333 static int is_route_matching_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1334 struct bgp_info
*ri
)
1336 struct attr
*attr
= ri
->attr
;
1337 struct ecommunity
*ecom
;
1341 /* Route should have valid RT to be even considered. */
1342 if (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)))
1345 ecom
= attr
->ecommunity
;
1346 if (!ecom
|| !ecom
->size
)
1349 /* For each extended community RT, see if it matches this VNI. If any RT
1350 * matches, we're done.
1352 for (i
= 0; i
< ecom
->size
; i
++) {
1354 u_char type
, sub_type
;
1355 struct ecommunity_val
*eval
;
1356 struct ecommunity_val eval_tmp
;
1357 struct irt_node
*irt
;
1359 /* Only deal with RTs */
1360 pnt
= (ecom
->val
+ (i
* ECOMMUNITY_SIZE
));
1361 eval
= (struct ecommunity_val
*)(ecom
->val
1362 + (i
* ECOMMUNITY_SIZE
));
1365 if (sub_type
!= ECOMMUNITY_ROUTE_TARGET
)
1368 /* See if this RT matches specified VNIs import RTs */
1369 irt
= lookup_import_rt(bgp
, eval
);
1370 if (irt
&& irt
->vnis
)
1371 if (is_vni_present_in_irt_vnis(irt
->vnis
, vpn
))
1374 /* Also check for non-exact match. In this, we mask out the AS
1376 * only check on the local-admin sub-field. This is to
1378 * VNI as the RT for EBGP peering too.
1381 if (type
== ECOMMUNITY_ENCODE_AS
1382 || type
== ECOMMUNITY_ENCODE_AS4
1383 || type
== ECOMMUNITY_ENCODE_IP
) {
1384 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
1385 mask_ecom_global_admin(&eval_tmp
, eval
);
1386 irt
= lookup_import_rt(bgp
, &eval_tmp
);
1388 if (irt
&& irt
->vnis
)
1389 if (is_vni_present_in_irt_vnis(irt
->vnis
, vpn
))
1397 * Install or uninstall routes of specified type that are appropriate for this
1400 static int install_uninstall_routes_for_vni(struct bgp
*bgp
,
1401 struct bgpevpn
*vpn
,
1402 bgp_evpn_route_type rtype
,
1407 struct bgp_node
*rd_rn
, *rn
;
1408 struct bgp_table
*table
;
1409 struct bgp_info
*ri
;
1415 /* Walk entire global routing table and evaluate routes which could be
1416 * imported into this VPN. Note that we cannot just look at the routes
1418 * the VNI's RD - remote routes applicable for this VNI could have any
1421 /* EVPN routes are a 2-level table. */
1422 for (rd_rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rd_rn
;
1423 rd_rn
= bgp_route_next(rd_rn
)) {
1424 table
= (struct bgp_table
*)(rd_rn
->info
);
1428 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
1429 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
1431 if (evp
->prefix
.route_type
!= rtype
)
1434 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
1435 /* Consider "valid" remote routes applicable for
1437 if (!(CHECK_FLAG(ri
->flags
, BGP_INFO_VALID
)
1438 && ri
->type
== ZEBRA_ROUTE_BGP
1439 && ri
->sub_type
== BGP_ROUTE_NORMAL
))
1442 if (is_route_matching_for_vni(bgp
, vpn
, ri
)) {
1444 ret
= install_evpn_route_entry(
1447 ret
= uninstall_evpn_route_entry(
1452 "%u: Failed to %s EVPN %s route in VNI %u",
1456 rtype
== BGP_EVPN_MAC_IP_ROUTE
1471 * Install any existing remote routes applicable for this VNI into its
1472 * routing table. This is invoked when a VNI becomes "live" or its Import
1475 static int install_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1479 /* Install type-3 routes followed by type-2 routes - the ones applicable
1482 ret
= install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_IMET_ROUTE
,
1487 return install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_MAC_IP_ROUTE
,
1492 * Uninstall any existing remote routes for this VNI. One scenario in which
1493 * this is invoked is upon an import RT change.
1495 static int uninstall_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1499 /* Uninstall type-2 routes followed by type-3 routes - the ones
1503 ret
= install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_MAC_IP_ROUTE
,
1508 return install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_IMET_ROUTE
,
1513 * Install or uninstall route in matching VNIs (list).
1515 static int install_uninstall_route_in_vnis(struct bgp
*bgp
, afi_t afi
,
1516 safi_t safi
, struct prefix_evpn
*evp
,
1517 struct bgp_info
*ri
,
1518 struct list
*vnis
, int install
)
1520 struct bgpevpn
*vpn
;
1521 struct listnode
*node
, *nnode
;
1523 for (ALL_LIST_ELEMENTS(vnis
, node
, nnode
, vpn
)) {
1526 if (!is_vni_live(vpn
))
1530 ret
= install_evpn_route_entry(bgp
, vpn
, evp
, ri
);
1532 ret
= uninstall_evpn_route_entry(bgp
, vpn
, evp
, ri
);
1535 zlog_err("%u: Failed to %s EVPN %s route in VNI %u",
1536 bgp
->vrf_id
, install
? "install" : "uninstall",
1537 evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
1549 * Install or uninstall route for appropriate VNIs.
1551 static int install_uninstall_evpn_route(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1552 struct prefix
*p
, struct bgp_info
*ri
,
1555 struct prefix_evpn
*evp
= (struct prefix_evpn
*)p
;
1556 struct attr
*attr
= ri
->attr
;
1557 struct ecommunity
*ecom
;
1562 /* Only type-2 and type-3 routes go into a L2 VNI. */
1563 if (!(evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
1564 || evp
->prefix
.route_type
== BGP_EVPN_IMET_ROUTE
))
1567 /* If we don't have Route Target, nothing much to do. */
1568 if (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)))
1571 ecom
= attr
->ecommunity
;
1572 if (!ecom
|| !ecom
->size
)
1575 /* For each extended community RT, see which VNIs match and import
1576 * the route into matching VNIs.
1578 for (i
= 0; i
< ecom
->size
; i
++) {
1580 u_char type
, sub_type
;
1581 struct ecommunity_val
*eval
;
1582 struct ecommunity_val eval_tmp
;
1583 struct irt_node
*irt
;
1585 /* Only deal with RTs */
1586 pnt
= (ecom
->val
+ (i
* ECOMMUNITY_SIZE
));
1587 eval
= (struct ecommunity_val
*)(ecom
->val
1588 + (i
* ECOMMUNITY_SIZE
));
1591 if (sub_type
!= ECOMMUNITY_ROUTE_TARGET
)
1594 /* Are we interested in this RT? */
1595 irt
= lookup_import_rt(bgp
, eval
);
1596 if (irt
&& irt
->vnis
)
1597 install_uninstall_route_in_vnis(bgp
, afi
, safi
, evp
, ri
,
1600 /* Also check for non-exact match. In this, we mask out the AS
1602 * only check on the local-admin sub-field. This is to
1604 * VNI as the RT for EBGP peering too.
1607 if (type
== ECOMMUNITY_ENCODE_AS
1608 || type
== ECOMMUNITY_ENCODE_AS4
1609 || type
== ECOMMUNITY_ENCODE_IP
) {
1610 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
1611 mask_ecom_global_admin(&eval_tmp
, eval
);
1612 irt
= lookup_import_rt(bgp
, &eval_tmp
);
1614 if (irt
&& irt
->vnis
)
1615 install_uninstall_route_in_vnis(bgp
, afi
, safi
, evp
, ri
,
1623 * Update and advertise local routes for a VNI. Invoked upon router-id
1624 * change. Note that the processing is done only on the global route table
1625 * using routes that already exist in the per-VNI table.
1627 static int update_advertise_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1629 struct prefix_evpn p
;
1630 struct bgp_node
*rn
, *global_rn
;
1631 struct bgp_info
*ri
, *global_ri
;
1633 afi_t afi
= AFI_L2VPN
;
1634 safi_t safi
= SAFI_EVPN
;
1636 /* Locate type-3 route for VNI in the per-VNI table and use its
1637 * attributes to create and advertise the type-3 route for this VNI
1638 * in the global table.
1640 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
1641 rn
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)&p
);
1642 if (!rn
) /* unexpected */
1644 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1645 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
1646 && ri
->sub_type
== BGP_ROUTE_STATIC
)
1648 if (!ri
) /* unexpected */
1652 global_rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
1653 (struct prefix
*)&p
, &vpn
->prd
);
1654 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, attr
, 1, 0, &ri
,
1657 /* Schedule for processing and unlock node. */
1658 bgp_process(bgp
, global_rn
, afi
, safi
);
1659 bgp_unlock_node(global_rn
);
1661 /* Now, walk this VNI's route table and use the route and its attribute
1662 * to create and schedule route in global table.
1664 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
1665 rn
= bgp_route_next(rn
)) {
1666 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
1668 /* Identify MAC-IP local routes. */
1669 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
1672 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1673 if (ri
->peer
== bgp
->peer_self
1674 && ri
->type
== ZEBRA_ROUTE_BGP
1675 && ri
->sub_type
== BGP_ROUTE_STATIC
)
1680 /* Create route in global routing table using this route entry's
1684 global_rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
1685 (struct prefix
*)evp
, &vpn
->prd
);
1687 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, attr
, 1,
1690 /* Schedule for processing and unlock node. */
1691 bgp_process(bgp
, global_rn
, afi
, safi
);
1692 bgp_unlock_node(global_rn
);
1699 * Delete (and withdraw) local routes for a VNI - only from the global
1700 * table. Invoked upon router-id change.
1702 static int delete_withdraw_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1705 struct prefix_evpn p
;
1706 struct bgp_node
*global_rn
;
1707 struct bgp_info
*ri
;
1708 afi_t afi
= AFI_L2VPN
;
1709 safi_t safi
= SAFI_EVPN
;
1711 /* Delete and withdraw locally learnt type-2 routes (MACIP)
1712 * for this VNI - from the global table.
1714 ret
= delete_global_type2_routes(bgp
, vpn
);
1718 /* Remove type-3 route for this VNI from global table. */
1719 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
1720 global_rn
= bgp_afi_node_lookup(bgp
->rib
[afi
][safi
], afi
, safi
,
1721 (struct prefix
*)&p
, &vpn
->prd
);
1723 /* Delete route entry in the global EVPN table. */
1724 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, &ri
);
1726 /* Schedule for processing - withdraws to peers happen from
1730 bgp_process(bgp
, global_rn
, afi
, safi
);
1731 bgp_unlock_node(global_rn
);
1738 * Handle router-id change. Update and advertise local routes corresponding
1739 * to this VNI from peers. Note that this is invoked after updating the
1740 * router-id. The routes in the per-VNI table are used to create routes in
1741 * the global table and schedule them.
1743 static void update_router_id_vni(struct hash_backet
*backet
, struct bgp
*bgp
)
1745 struct bgpevpn
*vpn
;
1747 vpn
= (struct bgpevpn
*)backet
->data
;
1750 zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__
);
1754 /* Skip VNIs with configured RD. */
1755 if (is_rd_configured(vpn
))
1758 bgp_evpn_derive_auto_rd(bgp
, vpn
);
1759 update_advertise_vni_routes(bgp
, vpn
);
1763 * Handle router-id change. Delete and withdraw local routes corresponding
1764 * to this VNI from peers. Note that this is invoked prior to updating
1765 * the router-id and is done only on the global route table, the routes
1766 * are needed in the per-VNI table to re-advertise with new router id.
1768 static void withdraw_router_id_vni(struct hash_backet
*backet
, struct bgp
*bgp
)
1770 struct bgpevpn
*vpn
;
1772 vpn
= (struct bgpevpn
*)backet
->data
;
1775 zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__
);
1779 /* Skip VNIs with configured RD. */
1780 if (is_rd_configured(vpn
))
1783 delete_withdraw_vni_routes(bgp
, vpn
);
1787 * Process received EVPN type-2 route (advertise or withdraw).
1789 static int process_type2_route(struct peer
*peer
, afi_t afi
, safi_t safi
,
1790 struct attr
*attr
, u_char
*pfx
, int psize
,
1791 u_int32_t addpath_id
)
1793 struct prefix_rd prd
;
1794 struct prefix_evpn p
;
1797 mpls_label_t
*label_pnt
;
1800 /* Type-2 route should be either 33, 37 or 49 bytes or an
1801 * additional 3 bytes if there is a second label (VNI):
1802 * RD (8), ESI (10), Eth Tag (4), MAC Addr Len (1),
1803 * MAC Addr (6), IP len (1), IP (0, 4 or 16),
1804 * MPLS Lbl1 (3), MPLS Lbl2 (0 or 3)
1806 if (psize
!= 33 && psize
!= 37 && psize
!= 49 && psize
!= 36
1807 && psize
!= 40 && psize
!= 52) {
1808 zlog_err("%u:%s - Rx EVPN Type-2 NLRI with invalid length %d",
1809 peer
->bgp
->vrf_id
, peer
->host
, psize
);
1813 /* Make prefix_rd */
1814 prd
.family
= AF_UNSPEC
;
1816 memcpy(&prd
.val
, pfx
, 8);
1819 /* Make EVPN prefix. */
1820 memset(&p
, 0, sizeof(struct prefix_evpn
));
1822 p
.prefixlen
= EVPN_TYPE_2_ROUTE_PREFIXLEN
;
1823 p
.prefix
.route_type
= BGP_EVPN_MAC_IP_ROUTE
;
1825 /* Skip over Ethernet Seg Identifier for now. */
1828 /* Skip over Ethernet Tag for now. */
1831 /* Get the MAC Addr len */
1832 macaddr_len
= *pfx
++;
1834 /* Get the MAC Addr */
1835 if (macaddr_len
== (ETH_ALEN
* 8)) {
1836 memcpy(&p
.prefix
.mac
.octet
, pfx
, ETH_ALEN
);
1840 "%u:%s - Rx EVPN Type-2 NLRI with unsupported MAC address length %d",
1841 peer
->bgp
->vrf_id
, peer
->host
, macaddr_len
);
1847 ipaddr_len
= *pfx
++;
1848 if (ipaddr_len
!= 0 && ipaddr_len
!= IPV4_MAX_BITLEN
1849 && ipaddr_len
!= IPV6_MAX_BITLEN
) {
1851 "%u:%s - Rx EVPN Type-2 NLRI with unsupported IP address length %d",
1852 peer
->bgp
->vrf_id
, peer
->host
, ipaddr_len
);
1857 ipaddr_len
/= 8; /* Convert to bytes. */
1858 p
.prefix
.ip
.ipa_type
= (ipaddr_len
== IPV4_MAX_BYTELEN
)
1861 memcpy(&p
.prefix
.ip
.ip
.addr
, pfx
, ipaddr_len
);
1865 /* Get the VNI (in MPLS label field). */
1866 /* Note: We ignore the second VNI, if any. */
1867 label_pnt
= (mpls_label_t
*)pfx
;
1869 /* Process the route. */
1871 ret
= bgp_update(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
1872 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
1873 &prd
, label_pnt
, 0, NULL
);
1875 ret
= bgp_withdraw(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
1876 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
1877 &prd
, label_pnt
, NULL
);
1882 * Process received EVPN type-3 route (advertise or withdraw).
1884 static int process_type3_route(struct peer
*peer
, afi_t afi
, safi_t safi
,
1885 struct attr
*attr
, u_char
*pfx
, int psize
,
1886 u_int32_t addpath_id
)
1888 struct prefix_rd prd
;
1889 struct prefix_evpn p
;
1893 /* Type-3 route should be either 17 or 29 bytes: RD (8), Eth Tag (4),
1894 * IP len (1) and IP (4 or 16).
1896 if (psize
!= 17 && psize
!= 29) {
1897 zlog_err("%u:%s - Rx EVPN Type-3 NLRI with invalid length %d",
1898 peer
->bgp
->vrf_id
, peer
->host
, psize
);
1902 /* Make prefix_rd */
1903 prd
.family
= AF_UNSPEC
;
1905 memcpy(&prd
.val
, pfx
, 8);
1908 /* Make EVPN prefix. */
1909 memset(&p
, 0, sizeof(struct prefix_evpn
));
1911 p
.prefixlen
= EVPN_TYPE_3_ROUTE_PREFIXLEN
;
1912 p
.prefix
.route_type
= BGP_EVPN_IMET_ROUTE
;
1914 /* Skip over Ethernet Tag for now. */
1918 ipaddr_len
= *pfx
++;
1919 if (ipaddr_len
== IPV4_MAX_BITLEN
) {
1920 p
.prefix
.ip
.ipa_type
= IPADDR_V4
;
1921 memcpy(&p
.prefix
.ip
.ip
.addr
, pfx
, IPV4_MAX_BYTELEN
);
1924 "%u:%s - Rx EVPN Type-3 NLRI with unsupported IP address length %d",
1925 peer
->bgp
->vrf_id
, peer
->host
, ipaddr_len
);
1929 /* Process the route. */
1931 ret
= bgp_update(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
1932 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
1933 &prd
, NULL
, 0, NULL
);
1935 ret
= bgp_withdraw(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
1936 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
1942 * Process received EVPN type-5 route (advertise or withdraw).
1944 static int process_type5_route(struct peer
*peer
, afi_t afi
, safi_t safi
,
1945 struct attr
*attr
, u_char
*pfx
, int psize
,
1946 u_int32_t addpath_id
, int withdraw
)
1948 struct prefix_rd prd
;
1949 struct prefix_evpn p
;
1950 struct bgp_route_evpn evpn
;
1953 mpls_label_t
*label_pnt
;
1956 /* Type-5 route should be 34 or 58 bytes:
1957 * RD (8), ESI (10), Eth Tag (4), IP len (1), IP (4 or 16),
1958 * GW (4 or 16) and VNI (3).
1959 * Note that the IP and GW should both be IPv4 or both IPv6.
1961 if (psize
!= 34 && psize
!= 58) {
1962 zlog_err("%u:%s - Rx EVPN Type-5 NLRI with invalid length %d",
1963 peer
->bgp
->vrf_id
, peer
->host
, psize
);
1967 /* Make prefix_rd */
1968 prd
.family
= AF_UNSPEC
;
1970 memcpy(&prd
.val
, pfx
, 8);
1973 /* Make EVPN prefix. */
1974 memset(&p
, 0, sizeof(struct prefix_evpn
));
1976 p
.prefix
.route_type
= BGP_EVPN_IP_PREFIX_ROUTE
;
1978 /* Additional information outside of prefix - ESI and GW IP */
1979 memset(&evpn
, 0, sizeof(evpn
));
1982 memcpy(&evpn
.eth_s_id
.val
, pfx
, 10);
1985 /* Fetch Ethernet Tag. */
1986 memcpy(ð_tag
, pfx
, 4);
1987 p
.prefix
.eth_tag
= ntohl(eth_tag
);
1990 /* Fetch IP prefix length. */
1992 if (ippfx_len
> IPV6_MAX_BITLEN
) {
1994 "%u:%s - Rx EVPN Type-5 NLRI with invalid IP Prefix length %d",
1995 peer
->bgp
->vrf_id
, peer
->host
, ippfx_len
);
1998 p
.prefix
.ip_prefix_length
= ippfx_len
;
2000 /* Determine IPv4 or IPv6 prefix */
2001 /* Since the address and GW are from the same family, this just becomes
2002 * a simple check on the total size.
2005 SET_IPADDR_V4(&p
.prefix
.ip
);
2006 memcpy(&p
.prefix
.ip
.ipaddr_v4
, pfx
, 4);
2008 memcpy(&evpn
.gw_ip
.ipv4
, pfx
, 4);
2010 p
.prefixlen
= PREFIX_LEN_ROUTE_TYPE_5_IPV4
;
2012 SET_IPADDR_V6(&p
.prefix
.ip
);
2013 memcpy(&p
.prefix
.ip
.ipaddr_v6
, pfx
, 16);
2015 memcpy(&evpn
.gw_ip
.ipv6
, pfx
, 16);
2017 p
.prefixlen
= PREFIX_LEN_ROUTE_TYPE_5_IPV6
;
2020 label_pnt
= (mpls_label_t
*)pfx
;
2022 /* Process the route. */
2024 ret
= bgp_update(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
2025 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
2026 &prd
, label_pnt
, 0, &evpn
);
2028 ret
= bgp_withdraw(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
2029 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
2030 &prd
, label_pnt
, &evpn
);
2035 static void evpn_mpattr_encode_type5(struct stream
*s
, struct prefix
*p
,
2036 struct prefix_rd
*prd
, mpls_label_t
*label
,
2041 struct evpn_addr
*p_evpn_p
;
2043 memset(&temp
, 0, 16);
2044 if (p
->family
!= AF_EVPN
)
2046 p_evpn_p
= &(p
->u
.prefix_evpn
);
2048 if (IS_IPADDR_V4(&p_evpn_p
->ip
))
2051 len
= 32; /* ipv6 */
2052 /* Prefix contains RD, ESI, EthTag, IP length, IP, GWIP and VNI */
2053 stream_putc(s
, 8 + 10 + 4 + 1 + len
+ 3);
2054 stream_put(s
, prd
->val
, 8);
2056 stream_put(s
, &(attr
->evpn_overlay
.eth_s_id
), 10);
2058 stream_put(s
, &temp
, 10);
2059 stream_putl(s
, p_evpn_p
->eth_tag
);
2060 stream_putc(s
, p_evpn_p
->ip_prefix_length
);
2061 if (IS_IPADDR_V4(&p_evpn_p
->ip
))
2062 stream_put_ipv4(s
, p_evpn_p
->ip
.ipaddr_v4
.s_addr
);
2064 stream_put(s
, &p_evpn_p
->ip
.ipaddr_v6
, 16);
2066 if (IS_IPADDR_V4(&p_evpn_p
->ip
))
2068 attr
->evpn_overlay
.gw_ip
.ipv4
.s_addr
);
2070 stream_put(s
, &(attr
->evpn_overlay
.gw_ip
.ipv6
), 16);
2072 if (IS_IPADDR_V4(&p_evpn_p
->ip
))
2073 stream_put_ipv4(s
, 0);
2075 stream_put(s
, &temp
, 16);
2079 stream_put(s
, label
, 3);
2085 * Cleanup specific VNI upon EVPN (advertise-all-vni) being disabled.
2087 static void cleanup_vni_on_disable(struct hash_backet
*backet
, struct bgp
*bgp
)
2089 struct bgpevpn
*vpn
= (struct bgpevpn
*)backet
->data
;
2091 /* Remove EVPN routes and schedule for processing. */
2092 delete_routes_for_vni(bgp
, vpn
);
2094 /* Clear "live" flag and see if hash needs to be freed. */
2095 UNSET_FLAG(vpn
->flags
, VNI_FLAG_LIVE
);
2096 if (!is_vni_configured(vpn
))
2097 bgp_evpn_free(bgp
, vpn
);
2101 * Free a VNI entry; iterator function called during cleanup.
2103 static void free_vni_entry(struct hash_backet
*backet
, struct bgp
*bgp
)
2105 struct bgpevpn
*vpn
;
2107 vpn
= (struct bgpevpn
*)backet
->data
;
2108 delete_all_vni_routes(bgp
, vpn
);
2109 bgp_evpn_free(bgp
, vpn
);
2118 * Handle change to BGP router id. This is invoked twice by the change
2119 * handler, first before the router id has been changed and then after
2120 * the router id has been changed. The first invocation will result in
2121 * local routes for all VNIs being deleted and withdrawn and the next
2122 * will result in the routes being re-advertised.
2124 void bgp_evpn_handle_router_id_update(struct bgp
*bgp
, int withdraw
)
2127 hash_iterate(bgp
->vnihash
,
2128 (void (*)(struct hash_backet
*,
2129 void *))withdraw_router_id_vni
,
2132 hash_iterate(bgp
->vnihash
,
2133 (void (*)(struct hash_backet
*,
2134 void *))update_router_id_vni
,
2139 * Handle change to export RT - update and advertise local routes.
2141 int bgp_evpn_handle_export_rt_change(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2143 return update_routes_for_vni(bgp
, vpn
);
2147 * Handle change to RD. This is invoked twice by the change handler,
2148 * first before the RD has been changed and then after the RD has
2149 * been changed. The first invocation will result in local routes
2150 * of this VNI being deleted and withdrawn and the next will result
2151 * in the routes being re-advertised.
2153 void bgp_evpn_handle_rd_change(struct bgp
*bgp
, struct bgpevpn
*vpn
,
2157 delete_withdraw_vni_routes(bgp
, vpn
);
2159 update_advertise_vni_routes(bgp
, vpn
);
2163 * Install routes for this VNI. Invoked upon change to Import RT.
2165 int bgp_evpn_install_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2167 return install_routes_for_vni(bgp
, vpn
);
2171 * Uninstall all routes installed for this VNI. Invoked upon change
2174 int bgp_evpn_uninstall_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2176 return uninstall_routes_for_vni(bgp
, vpn
);
2180 * Function to display "tag" in route as a VNI.
2182 char *bgp_evpn_label2str(mpls_label_t
*label
, char *buf
, int len
)
2186 vni
= label2vni(label
);
2187 snprintf(buf
, len
, "%u", vni
);
2192 * Function to convert evpn route to json format.
2193 * NOTE: We don't use prefix2str as the output here is a bit different.
2195 void bgp_evpn_route2json(struct prefix_evpn
*p
, json_object
*json
)
2197 char buf1
[ETHER_ADDR_STRLEN
];
2198 char buf2
[PREFIX2STR_BUFFER
];
2203 if (p
->prefix
.route_type
== BGP_EVPN_IMET_ROUTE
) {
2204 json_object_int_add(json
, "routeType", p
->prefix
.route_type
);
2205 json_object_int_add(json
, "ethTag", 0);
2206 json_object_int_add(json
, "ipLen",
2207 IS_EVPN_PREFIX_IPADDR_V4(p
)
2210 json_object_string_add(json
, "ip",
2211 inet_ntoa(p
->prefix
.ip
.ipaddr_v4
));
2212 } else if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
) {
2213 if (IS_EVPN_PREFIX_IPADDR_NONE(p
)) {
2214 json_object_int_add(json
, "routeType",
2215 p
->prefix
.route_type
);
2216 json_object_int_add(
2218 0); /* TODO: we don't support esi yet */
2219 json_object_int_add(json
, "ethTag", 0);
2220 json_object_int_add(json
, "macLen", 8 * ETH_ALEN
);
2221 json_object_string_add(json
, "mac",
2222 prefix_mac2str(&p
->prefix
.mac
,
2228 family
= IS_EVPN_PREFIX_IPADDR_V4(p
) ? AF_INET
2231 json_object_int_add(json
, "routeType",
2232 p
->prefix
.route_type
);
2233 json_object_int_add(
2235 0); /* TODO: we don't support esi yet */
2236 json_object_int_add(json
, "ethTag", 0);
2237 json_object_int_add(json
, "macLen", 8 * ETH_ALEN
);
2238 json_object_string_add(json
, "mac",
2239 prefix_mac2str(&p
->prefix
.mac
,
2242 json_object_int_add(json
, "ipLen",
2243 IS_EVPN_PREFIX_IPADDR_V4(p
)
2246 json_object_string_add(
2248 inet_ntop(family
, &p
->prefix
.ip
.ip
.addr
, buf2
,
2249 PREFIX2STR_BUFFER
));
2252 /* Currently, this is to cater to other AF_ETHERNET code. */
2257 * Function to convert evpn route to string.
2258 * NOTE: We don't use prefix2str as the output here is a bit different.
2260 char *bgp_evpn_route2str(struct prefix_evpn
*p
, char *buf
, int len
)
2262 char buf1
[ETHER_ADDR_STRLEN
];
2263 char buf2
[PREFIX2STR_BUFFER
];
2265 if (p
->prefix
.route_type
== BGP_EVPN_IMET_ROUTE
) {
2266 snprintf(buf
, len
, "[%d]:[0]:[%d]:[%s]", p
->prefix
.route_type
,
2267 IS_EVPN_PREFIX_IPADDR_V4(p
) ? IPV4_MAX_BITLEN
2269 inet_ntoa(p
->prefix
.ip
.ipaddr_v4
));
2270 } else if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
) {
2271 if (IS_EVPN_PREFIX_IPADDR_NONE(p
))
2272 snprintf(buf
, len
, "[%d]:[0]:[0]:[%d]:[%s]",
2273 p
->prefix
.route_type
, 8 * ETH_ALEN
,
2274 prefix_mac2str(&p
->prefix
.mac
, buf1
,
2279 family
= IS_EVPN_PREFIX_IPADDR_V4(p
) ? AF_INET
2281 snprintf(buf
, len
, "[%d]:[0]:[0]:[%d]:[%s]:[%d]:[%s]",
2282 p
->prefix
.route_type
, 8 * ETH_ALEN
,
2283 prefix_mac2str(&p
->prefix
.mac
, buf1
,
2285 family
== AF_INET
? IPV4_MAX_BITLEN
2287 inet_ntop(family
, &p
->prefix
.ip
.ip
.addr
, buf2
,
2288 PREFIX2STR_BUFFER
));
2291 /* For EVPN route types not supported yet. */
2292 snprintf(buf
, len
, "(unsupported route type %d)",
2293 p
->prefix
.route_type
);
2300 * Encode EVPN prefix in Update (MP_REACH)
2302 void bgp_evpn_encode_prefix(struct stream
*s
, struct prefix
*p
,
2303 struct prefix_rd
*prd
, mpls_label_t
*label
,
2304 struct attr
*attr
, int addpath_encode
,
2305 u_int32_t addpath_tx_id
)
2307 struct prefix_evpn
*evp
= (struct prefix_evpn
*)p
;
2311 stream_putl(s
, addpath_tx_id
);
2314 stream_putc(s
, evp
->prefix
.route_type
);
2316 switch (evp
->prefix
.route_type
) {
2317 case BGP_EVPN_MAC_IP_ROUTE
:
2318 if (IS_EVPN_PREFIX_IPADDR_V4(evp
))
2319 ipa_len
= IPV4_MAX_BYTELEN
;
2320 else if (IS_EVPN_PREFIX_IPADDR_V6(evp
))
2321 ipa_len
= IPV6_MAX_BYTELEN
;
2322 stream_putc(s
, 33 + ipa_len
); // 1 VNI
2323 stream_put(s
, prd
->val
, 8); /* RD */
2324 stream_put(s
, 0, 10); /* ESI */
2325 stream_putl(s
, 0); /* Ethernet Tag ID */
2326 stream_putc(s
, 8 * ETH_ALEN
); /* Mac Addr Len - bits */
2327 stream_put(s
, evp
->prefix
.mac
.octet
, 6); /* Mac Addr */
2328 stream_putc(s
, 8 * ipa_len
); /* IP address Length */
2330 stream_put(s
, &evp
->prefix
.ip
.ip
.addr
,
2332 stream_put(s
, label
,
2333 BGP_LABEL_BYTES
); /* VNI is contained in 'tag' */
2336 case BGP_EVPN_IMET_ROUTE
:
2337 stream_putc(s
, 17); // TODO: length - assumes IPv4 address
2338 stream_put(s
, prd
->val
, 8); /* RD */
2339 stream_putl(s
, 0); /* Ethernet Tag ID */
2340 stream_putc(s
, IPV4_MAX_BITLEN
); /* IP address Length - bits */
2341 /* Originating Router's IP Addr */
2342 stream_put_in_addr(s
, &evp
->prefix
.ip
.ipaddr_v4
);
2345 case BGP_EVPN_IP_PREFIX_ROUTE
:
2346 /* TODO: AddPath support. */
2347 evpn_mpattr_encode_type5(s
, p
, prd
, label
, attr
);
2355 int bgp_nlri_parse_evpn(struct peer
*peer
, struct attr
*attr
,
2356 struct bgp_nlri
*packet
, int withdraw
)
2362 u_int32_t addpath_id
;
2363 int addpath_encoded
;
2369 /* Check peer status. */
2370 if (peer
->status
!= Established
) {
2371 zlog_err("%u:%s - EVPN update received in state %d",
2372 peer
->bgp
->vrf_id
, peer
->host
, peer
->status
);
2376 /* Start processing the NLRI - there may be multiple in the MP_REACH */
2378 lim
= pnt
+ packet
->length
;
2380 safi
= packet
->safi
;
2384 (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
2385 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
2386 PEER_CAP_ADDPATH_AF_TX_RCV
));
2388 for (; pnt
< lim
; pnt
+= psize
) {
2389 /* Clear prefix structure. */
2390 memset(&p
, 0, sizeof(struct prefix
));
2392 /* Deal with path-id if AddPath is supported. */
2393 if (addpath_encoded
) {
2394 /* When packet overflow occurs return immediately. */
2395 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
2398 addpath_id
= ntohl(*((uint32_t *)pnt
));
2399 pnt
+= BGP_ADDPATH_ID_LEN
;
2402 /* All EVPN NLRI types start with type and length. */
2407 psize
= rlen
= *pnt
++;
2409 /* When packet overflow occur return immediately. */
2410 if (pnt
+ psize
> lim
)
2414 case BGP_EVPN_MAC_IP_ROUTE
:
2415 if (process_type2_route(peer
, afi
, safi
,
2416 withdraw
? NULL
: attr
, pnt
,
2417 psize
, addpath_id
)) {
2419 "%u:%s - Error in processing EVPN type-2 NLRI size %d",
2420 peer
->bgp
->vrf_id
, peer
->host
, psize
);
2425 case BGP_EVPN_IMET_ROUTE
:
2426 if (process_type3_route(peer
, afi
, safi
,
2427 withdraw
? NULL
: attr
, pnt
,
2428 psize
, addpath_id
)) {
2430 "%u:%s - Error in processing EVPN type-3 NLRI size %d",
2431 peer
->bgp
->vrf_id
, peer
->host
, psize
);
2436 case BGP_EVPN_IP_PREFIX_ROUTE
:
2437 if (process_type5_route(peer
, afi
, safi
, attr
, pnt
,
2438 psize
, addpath_id
, withdraw
)) {
2440 "%u:%s - Error in processing EVPN type-5 NLRI size %d",
2441 peer
->bgp
->vrf_id
, peer
->host
, psize
);
2451 /* Packet length consistency check. */
2460 * Map the RTs (configured or automatically derived) of a VNI to the VNI.
2461 * The mapping will be used during route processing.
2463 void bgp_evpn_map_vni_to_its_rts(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2466 struct ecommunity_val
*eval
;
2467 struct listnode
*node
, *nnode
;
2468 struct ecommunity
*ecom
;
2470 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
)) {
2471 for (i
= 0; i
< ecom
->size
; i
++) {
2472 eval
= (struct ecommunity_val
*)(ecom
->val
2474 * ECOMMUNITY_SIZE
));
2475 map_vni_to_rt(bgp
, vpn
, eval
);
2481 * Unmap the RTs (configured or automatically derived) of a VNI from the VNI.
2483 void bgp_evpn_unmap_vni_from_its_rts(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2486 struct ecommunity_val
*eval
;
2487 struct listnode
*node
, *nnode
;
2488 struct ecommunity
*ecom
;
2490 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
)) {
2491 for (i
= 0; i
< ecom
->size
; i
++) {
2492 struct irt_node
*irt
;
2493 struct ecommunity_val eval_tmp
;
2495 eval
= (struct ecommunity_val
*)(ecom
->val
2497 * ECOMMUNITY_SIZE
));
2498 /* If using "automatic" RT, we only care about the
2499 * local-admin sub-field.
2500 * This is to facilitate using VNI as the RT for EBGP
2503 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
2504 if (!is_import_rt_configured(vpn
))
2505 mask_ecom_global_admin(&eval_tmp
, eval
);
2507 irt
= lookup_import_rt(bgp
, &eval_tmp
);
2509 unmap_vni_from_rt(bgp
, vpn
, irt
);
2515 * Derive Import RT automatically for VNI and map VNI to RT.
2516 * The mapping will be used during route processing.
2518 void bgp_evpn_derive_auto_rt_import(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2520 form_auto_rt(bgp
, vpn
, vpn
->import_rtl
);
2521 UNSET_FLAG(vpn
->flags
, VNI_FLAG_IMPRT_CFGD
);
2524 bgp_evpn_map_vni_to_its_rts(bgp
, vpn
);
2528 * Derive Export RT automatically for VNI.
2530 void bgp_evpn_derive_auto_rt_export(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2532 form_auto_rt(bgp
, vpn
, vpn
->export_rtl
);
2533 UNSET_FLAG(vpn
->flags
, VNI_FLAG_EXPRT_CFGD
);
2537 * Derive RD automatically for VNI using passed information - it
2538 * is of the form RouterId:unique-id-for-vni.
2540 void bgp_evpn_derive_auto_rd(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2544 vpn
->prd
.family
= AF_UNSPEC
;
2545 vpn
->prd
.prefixlen
= 64;
2546 sprintf(buf
, "%s:%hu", inet_ntoa(bgp
->router_id
), vpn
->rd_id
);
2547 (void)str2prefix_rd(buf
, &vpn
->prd
);
2548 UNSET_FLAG(vpn
->flags
, VNI_FLAG_RD_CFGD
);
2554 struct bgpevpn
*bgp_evpn_lookup_vni(struct bgp
*bgp
, vni_t vni
)
2556 struct bgpevpn
*vpn
;
2559 memset(&tmp
, 0, sizeof(struct bgpevpn
));
2561 vpn
= hash_lookup(bgp
->vnihash
, &tmp
);
2566 * Create a new vpn - invoked upon configuration or zebra notification.
2568 struct bgpevpn
*bgp_evpn_new(struct bgp
*bgp
, vni_t vni
,
2569 struct in_addr originator_ip
)
2571 struct bgpevpn
*vpn
;
2576 vpn
= XCALLOC(MTYPE_BGP_EVPN
, sizeof(struct bgpevpn
));
2580 /* Set values - RD and RT set to defaults. */
2582 vpn
->originator_ip
= originator_ip
;
2584 /* Initialize route-target import and export lists */
2585 vpn
->import_rtl
= list_new();
2586 vpn
->import_rtl
->cmp
= (int (*)(void *, void *))evpn_route_target_cmp
;
2587 vpn
->export_rtl
= list_new();
2588 vpn
->export_rtl
->cmp
= (int (*)(void *, void *))evpn_route_target_cmp
;
2589 bf_assign_index(bgp
->rd_idspace
, vpn
->rd_id
);
2590 derive_rd_rt_for_vni(bgp
, vpn
);
2592 /* Initialize EVPN route table. */
2593 vpn
->route_table
= bgp_table_init(AFI_L2VPN
, SAFI_EVPN
);
2596 if (!hash_get(bgp
->vnihash
, vpn
, hash_alloc_intern
)) {
2597 XFREE(MTYPE_BGP_EVPN
, vpn
);
2600 QOBJ_REG(vpn
, bgpevpn
);
2605 * Free a given VPN - called in multiple scenarios such as zebra
2606 * notification, configuration being deleted, advertise-all-vni disabled etc.
2607 * This just frees appropriate memory, caller should have taken other
2610 void bgp_evpn_free(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2612 bgp_table_unlock(vpn
->route_table
);
2613 bgp_evpn_unmap_vni_from_its_rts(bgp
, vpn
);
2614 list_delete_and_null(&vpn
->import_rtl
);
2615 list_delete_and_null(&vpn
->export_rtl
);
2616 bf_release_index(bgp
->rd_idspace
, vpn
->rd_id
);
2617 hash_release(bgp
->vnihash
, vpn
);
2619 XFREE(MTYPE_BGP_EVPN
, vpn
);
2623 * Import route into matching VNI(s).
2625 int bgp_evpn_import_route(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
2626 struct prefix
*p
, struct bgp_info
*ri
)
2628 return install_uninstall_evpn_route(bgp
, afi
, safi
, p
, ri
, 1);
2632 * Unimport route from matching VNI(s).
2634 int bgp_evpn_unimport_route(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
2635 struct prefix
*p
, struct bgp_info
*ri
)
2637 return install_uninstall_evpn_route(bgp
, afi
, safi
, p
, ri
, 0);
2640 /* filter routes which have martian next hops */
2641 int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp
*bgp
)
2645 struct bgp_node
*rd_rn
, *rn
;
2646 struct bgp_table
*table
;
2647 struct bgp_info
*ri
;
2652 /* Walk entire global routing table and evaluate routes which could be
2653 * imported into this VPN. Note that we cannot just look at the routes
2654 * for the VNI's RD -
2655 * remote routes applicable for this VNI could have any RD.
2657 /* EVPN routes are a 2-level table. */
2658 for (rd_rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rd_rn
;
2659 rd_rn
= bgp_route_next(rd_rn
)) {
2660 table
= (struct bgp_table
*)(rd_rn
->info
);
2664 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
2666 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
2668 /* Consider "valid" remote routes applicable for
2670 if (!(ri
->type
== ZEBRA_ROUTE_BGP
2671 && ri
->sub_type
== BGP_ROUTE_NORMAL
))
2674 if (bgp_nexthop_self(bgp
, ri
->attr
->nexthop
)) {
2676 char attr_str
[BUFSIZ
];
2677 char pbuf
[PREFIX_STRLEN
];
2679 bgp_dump_attr(ri
->attr
, attr_str
,
2682 if (bgp_debug_update(ri
->peer
, &rn
->p
,
2685 "%u: prefix %s with attr %s - DENIED due to martian or self nexthop",
2692 bgp_evpn_unimport_route(bgp
, afi
, safi
,
2695 bgp_rib_remove(rn
, ri
, ri
->peer
, afi
,
2706 * Handle del of a local MACIP.
2708 int bgp_evpn_local_macip_del(struct bgp
*bgp
, vni_t vni
, struct ethaddr
*mac
,
2711 struct bgpevpn
*vpn
;
2712 struct prefix_evpn p
;
2714 if (!bgp
->vnihash
) {
2715 zlog_err("%u: VNI hash not created", bgp
->vrf_id
);
2719 /* Lookup VNI hash - should exist. */
2720 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
2721 if (!vpn
|| !is_vni_live(vpn
)) {
2722 zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP DEL",
2723 bgp
->vrf_id
, vni
, vpn
? "not live" : "not found");
2727 /* Remove EVPN type-2 route and schedule for processing. */
2728 build_evpn_type2_prefix(&p
, mac
, ip
);
2729 delete_evpn_route(bgp
, vpn
, &p
);
2735 * Handle add of a local MACIP.
2737 int bgp_evpn_local_macip_add(struct bgp
*bgp
, vni_t vni
, struct ethaddr
*mac
,
2738 struct ipaddr
*ip
, u_char flags
)
2740 struct bgpevpn
*vpn
;
2741 struct prefix_evpn p
;
2743 if (!bgp
->vnihash
) {
2744 zlog_err("%u: VNI hash not created", bgp
->vrf_id
);
2748 /* Lookup VNI hash - should exist. */
2749 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
2750 if (!vpn
|| !is_vni_live(vpn
)) {
2751 zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP ADD",
2752 bgp
->vrf_id
, vni
, vpn
? "not live" : "not found");
2756 /* Create EVPN type-2 route and schedule for processing. */
2757 build_evpn_type2_prefix(&p
, mac
, ip
);
2758 if (update_evpn_route(bgp
, vpn
, &p
, flags
)) {
2759 char buf
[ETHER_ADDR_STRLEN
];
2760 char buf2
[INET6_ADDRSTRLEN
];
2763 "%u:Failed to create Type-2 route, VNI %u %s MAC %s IP %s",
2764 bgp
->vrf_id
, vpn
->vni
,
2765 CHECK_FLAG(flags
, ZEBRA_MAC_TYPE_STICKY
) ? "sticky gateway"
2767 prefix_mac2str(mac
, buf
, sizeof(buf
)),
2768 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
2776 * Handle del of a local VNI.
2778 int bgp_evpn_local_vni_del(struct bgp
*bgp
, vni_t vni
)
2780 struct bgpevpn
*vpn
;
2782 if (!bgp
->vnihash
) {
2783 zlog_err("%u: VNI hash not created", bgp
->vrf_id
);
2787 /* Locate VNI hash */
2788 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
2790 zlog_warn("%u: VNI hash entry for VNI %u not found at DEL",
2795 /* Remove all local EVPN routes and schedule for processing (to
2796 * withdraw from peers).
2798 delete_routes_for_vni(bgp
, vpn
);
2801 * tunnel is no longer active, del tunnel ip address from tip_hash
2803 bgp_tip_del(bgp
, &vpn
->originator_ip
);
2805 /* Clear "live" flag and see if hash needs to be freed. */
2806 UNSET_FLAG(vpn
->flags
, VNI_FLAG_LIVE
);
2807 if (!is_vni_configured(vpn
))
2808 bgp_evpn_free(bgp
, vpn
);
2814 * Handle add (or update) of a local VNI. The only VNI change we care
2815 * about is change to local-tunnel-ip.
2817 int bgp_evpn_local_vni_add(struct bgp
*bgp
, vni_t vni
,
2818 struct in_addr originator_ip
)
2820 struct bgpevpn
*vpn
;
2821 struct prefix_evpn p
;
2823 if (!bgp
->vnihash
) {
2824 zlog_err("%u: VNI hash not created", bgp
->vrf_id
);
2828 /* Lookup VNI. If present and no change, exit. */
2829 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
2831 if (is_vni_live(vpn
)
2832 && IPV4_ADDR_SAME(&vpn
->originator_ip
, &originator_ip
))
2833 /* Probably some other param has changed that we don't
2837 /* Local tunnel endpoint IP address has changed */
2838 handle_tunnel_ip_change(bgp
, vpn
, originator_ip
);
2841 /* Create or update as appropriate. */
2843 vpn
= bgp_evpn_new(bgp
, vni
, originator_ip
);
2846 "%u: Failed to allocate VNI entry for VNI %u - at Add",
2852 /* if the VNI is live already, there is nothing more to do */
2853 if (is_vni_live(vpn
))
2856 /* Mark as "live" */
2857 SET_FLAG(vpn
->flags
, VNI_FLAG_LIVE
);
2859 /* tunnel is now active, add tunnel-ip to db */
2860 bgp_tip_add(bgp
, &originator_ip
);
2862 /* filter routes as nexthop database has changed */
2863 bgp_filter_evpn_routes_upon_martian_nh_change(bgp
);
2865 /* Create EVPN type-3 route and schedule for processing. */
2866 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
2867 if (update_evpn_route(bgp
, vpn
, &p
, 0)) {
2868 zlog_err("%u: Type3 route creation failure for VNI %u",
2873 /* If we have learnt and retained remote routes (VTEPs, MACs) for this
2877 install_routes_for_vni(bgp
, vpn
);
2879 /* If we are advertising gateway mac-ip
2880 It needs to be conveyed again to zebra */
2881 bgp_zebra_advertise_gw_macip(bgp
, vpn
->advertise_gw_macip
, vpn
->vni
);
2887 * Cleanup EVPN information on disable - Need to delete and withdraw
2888 * EVPN routes from peers.
2890 void bgp_evpn_cleanup_on_disable(struct bgp
*bgp
)
2892 hash_iterate(bgp
->vnihash
, (void (*)(struct hash_backet
*,
2893 void *))cleanup_vni_on_disable
,
2898 * Cleanup EVPN information - invoked at the time of bgpd exit or when the
2899 * BGP instance (default) is being freed.
2901 void bgp_evpn_cleanup(struct bgp
*bgp
)
2904 hash_iterate(bgp
->vnihash
, (void (*)(struct hash_backet
*,
2905 void *))free_vni_entry
,
2907 if (bgp
->import_rt_hash
)
2908 hash_free(bgp
->import_rt_hash
);
2909 bgp
->import_rt_hash
= NULL
;
2911 hash_free(bgp
->vnihash
);
2912 bgp
->vnihash
= NULL
;
2913 bf_free(bgp
->rd_idspace
);
2917 * Initialization for EVPN
2920 * hash for RT to VNI
2921 * unique rd id space for auto derivation of RD for VNIs
2923 void bgp_evpn_init(struct bgp
*bgp
)
2926 hash_create(vni_hash_key_make
, vni_hash_cmp
, "BGP VNI Hash");
2927 bgp
->import_rt_hash
=
2928 hash_create(import_rt_hash_key_make
, import_rt_hash_cmp
,
2929 "BGP Import RT Hash");
2930 bf_init(bgp
->rd_idspace
, UINT16_MAX
);
2931 /*assign 0th index in the bitfield, so that we start with id 1*/
2932 bf_assign_zero_index(bgp
->rd_idspace
);