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_free(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;
838 /* Set up RT and ENCAP extended community. */
839 build_evpn_route_extcomm(vpn
, &attr
);
841 /* First, create (or fetch) route node within the VNI. */
842 /* NOTE: There is no RD here. */
843 rn
= bgp_node_get(vpn
->route_table
, (struct prefix
*)p
);
845 /* Create or update route entry. */
846 route_change
= update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &attr
,
851 /* Perform route selection; this is just to set the flags correctly
852 * as local route in the VNI always wins.
854 evpn_route_select_install(bgp
, vpn
, rn
);
857 /* If this is a new route or some attribute has changed, export the
858 * route to the global table. The route will be advertised to peers
859 * from there. Note that this table is a 2-level tree (RD-level +
860 * Prefix-level) similar to L3VPN routes.
863 struct bgp_info
*global_ri
;
865 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
866 (struct prefix
*)p
, &vpn
->prd
);
867 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, attr_new
, 1, 0,
870 /* Schedule for processing and unlock node. */
871 bgp_process(bgp
, rn
, afi
, safi
);
875 /* Unintern temporary. */
876 aspath_unintern(&attr
.aspath
);
882 * Delete EVPN route entry. This could be in the VNI route table
883 * or the global route table.
885 static void delete_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
886 afi_t afi
, safi_t safi
, struct bgp_node
*rn
,
887 struct bgp_info
**ri
)
889 struct bgp_info
*tmp_ri
;
893 /* Now, find matching route. */
894 for (tmp_ri
= rn
->info
; tmp_ri
; tmp_ri
= tmp_ri
->next
)
895 if (tmp_ri
->peer
== bgp
->peer_self
896 && tmp_ri
->type
== ZEBRA_ROUTE_BGP
897 && tmp_ri
->sub_type
== BGP_ROUTE_STATIC
)
902 /* Mark route for delete. */
904 bgp_info_delete(rn
, tmp_ri
);
908 * Delete EVPN route (of type based on prefix) for specified VNI and
909 * schedule for processing.
911 static int delete_evpn_route(struct bgp
*bgp
, struct bgpevpn
*vpn
,
912 struct prefix_evpn
*p
)
914 struct bgp_node
*rn
, *global_rn
;
916 afi_t afi
= AFI_L2VPN
;
917 safi_t safi
= SAFI_EVPN
;
919 /* First, locate the route node within the VNI. If it doesn't exist,
921 * is nothing further to do.
923 /* NOTE: There is no RD here. */
924 rn
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)p
);
928 /* Next, locate route node in the global EVPN routing table. Note that
929 * this table is a 2-level tree (RD-level + Prefix-level) similar to
932 global_rn
= bgp_afi_node_lookup(bgp
->rib
[afi
][safi
], afi
, safi
,
933 (struct prefix
*)p
, &vpn
->prd
);
935 /* Delete route entry in the global EVPN table. */
936 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, &ri
);
938 /* Schedule for processing - withdraws to peers happen from
942 bgp_process(bgp
, global_rn
, afi
, safi
);
943 bgp_unlock_node(global_rn
);
946 /* Delete route entry in the VNI route table. This can just be removed.
948 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &ri
);
950 bgp_info_reap(rn
, ri
);
957 * Update all type-2 (MACIP) local routes for this VNI - these should also
958 * be scheduled for advertise to peers.
960 static int update_all_type2_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
967 struct attr attr_sticky
;
968 struct attr
*attr_new
;
972 memset(&attr
, 0, sizeof(struct attr
));
973 memset(&attr_sticky
, 0, sizeof(struct attr
));
975 /* Build path-attribute - all type-2 routes for this VNI will share the
976 * same path attribute.
978 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
979 bgp_attr_default_set(&attr_sticky
, BGP_ORIGIN_IGP
);
980 attr
.nexthop
= vpn
->originator_ip
;
981 attr
.mp_nexthop_global_in
= vpn
->originator_ip
;
982 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
983 attr_sticky
.nexthop
= vpn
->originator_ip
;
984 attr_sticky
.mp_nexthop_global_in
= vpn
->originator_ip
;
985 attr_sticky
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV4
;
986 attr_sticky
.sticky
= 1;
988 /* Set up RT, ENCAP and sticky MAC extended community. */
989 build_evpn_route_extcomm(vpn
, &attr
);
990 build_evpn_route_extcomm(vpn
, &attr_sticky
);
992 /* Walk this VNI's route table and update local type-2 routes. For any
993 * routes updated, update corresponding entry in the global table too.
995 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
996 rn
= bgp_route_next(rn
)) {
997 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
998 struct bgp_node
*rd_rn
;
999 struct bgp_info
*global_ri
;
1001 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
1004 if (evpn_route_is_sticky(bgp
, rn
))
1005 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
,
1006 &attr_sticky
, 0, 1, &ri
, 0);
1008 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &attr
,
1011 /* If a local route exists for this prefix, we need to update
1012 * the global routing table too.
1017 /* Perform route selection; this is just to set the flags
1019 * as local route in the VNI always wins.
1021 evpn_route_select_install(bgp
, vpn
, rn
);
1023 attr_new
= ri
->attr
;
1025 /* Update route in global routing table. */
1026 rd_rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
1027 (struct prefix
*)evp
, &vpn
->prd
);
1029 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, rd_rn
, attr_new
, 0,
1032 /* Schedule for processing and unlock node. */
1033 bgp_process(bgp
, rd_rn
, afi
, safi
);
1034 bgp_unlock_node(rd_rn
);
1037 /* Unintern temporary. */
1038 aspath_unintern(&attr
.aspath
);
1039 aspath_unintern(&attr_sticky
.aspath
);
1045 * Delete all type-2 (MACIP) local routes for this VNI - only from the
1046 * global routing table. These are also scheduled for withdraw from peers.
1048 static int delete_global_type2_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1052 struct bgp_node
*rdrn
, *rn
;
1053 struct bgp_table
*table
;
1054 struct bgp_info
*ri
;
1059 rdrn
= bgp_node_lookup(bgp
->rib
[afi
][safi
], (struct prefix
*)&vpn
->prd
);
1060 if (rdrn
&& rdrn
->info
) {
1061 table
= (struct bgp_table
*)rdrn
->info
;
1062 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
1063 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
1065 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
1068 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &ri
);
1070 bgp_process(bgp
, rn
, afi
, safi
);
1074 /* Unlock RD node. */
1076 bgp_unlock_node(rdrn
);
1082 * Delete all type-2 (MACIP) local routes for this VNI - from the global
1083 * table as well as the per-VNI route table.
1085 static int delete_all_type2_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1089 struct bgp_node
*rn
;
1090 struct bgp_info
*ri
;
1095 /* First, walk the global route table for this VNI's type-2 local
1097 * EVPN routes are a 2-level table, first get the RD table.
1099 delete_global_type2_routes(bgp
, vpn
);
1101 /* Next, walk this VNI's route table and delete local type-2 routes. */
1102 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
1103 rn
= bgp_route_next(rn
)) {
1104 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
1106 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
1109 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, rn
, &ri
);
1111 /* Route entry in local table gets deleted immediately. */
1113 bgp_info_reap(rn
, ri
);
1120 * Delete all routes in the per-VNI route table.
1122 static int delete_all_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1124 struct bgp_node
*rn
;
1125 struct bgp_info
*ri
, *nextri
;
1127 /* Walk this VNI's route table and delete all routes. */
1128 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
1129 rn
= bgp_route_next(rn
)) {
1130 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1);
1132 bgp_info_delete(rn
, ri
);
1133 bgp_info_reap(rn
, ri
);
1141 * Update (and advertise) local routes for a VNI. Invoked upon the VNI
1142 * export RT getting modified or change to tunnel IP. Note that these
1143 * situations need the route in the per-VNI table as well as the global
1144 * table to be updated (as attributes change).
1146 static int update_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1149 struct prefix_evpn p
;
1151 /* Update and advertise the type-3 route (only one) followed by the
1152 * locally learnt type-2 routes (MACIP) - for this VNI.
1154 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
1155 ret
= update_evpn_route(bgp
, vpn
, &p
, 0);
1159 return update_all_type2_routes(bgp
, vpn
);
1163 * Delete (and withdraw) local routes for specified VNI from the global
1164 * table and per-VNI table. After this, remove all other routes from
1165 * the per-VNI table. Invoked upon the VNI being deleted or EVPN
1166 * (advertise-all-vni) being disabled.
1168 static int delete_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1171 struct prefix_evpn p
;
1173 /* Delete and withdraw locally learnt type-2 routes (MACIP)
1174 * followed by type-3 routes (only one) - for this VNI.
1176 ret
= delete_all_type2_routes(bgp
, vpn
);
1180 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
1181 ret
= delete_evpn_route(bgp
, vpn
, &p
);
1185 /* Delete all routes from the per-VNI table. */
1186 return delete_all_vni_routes(bgp
, vpn
);
1190 * There is a tunnel endpoint IP address change for this VNI,
1191 * need to re-advertise routes with the new nexthop.
1193 static int handle_tunnel_ip_change(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1194 struct in_addr originator_ip
)
1196 struct prefix_evpn p
;
1198 /* If VNI is not live, we only need to update the originator ip */
1199 if (!is_vni_live(vpn
)) {
1200 vpn
->originator_ip
= originator_ip
;
1204 /* Update the tunnel-ip hash */
1205 bgp_tip_del(bgp
, &vpn
->originator_ip
);
1206 bgp_tip_add(bgp
, &originator_ip
);
1208 /* filter routes as martian nexthop db has changed */
1209 bgp_filter_evpn_routes_upon_martian_nh_change(bgp
);
1211 /* Need to withdraw type-3 route as the originator IP is part
1214 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
1215 delete_evpn_route(bgp
, vpn
, &p
);
1217 /* Update the tunnel IP and re-advertise all routes for this VNI. */
1218 vpn
->originator_ip
= originator_ip
;
1219 return update_routes_for_vni(bgp
, vpn
);
1223 * Install route entry into the VNI routing table and invoke route selection.
1225 static int install_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1226 struct prefix_evpn
*p
,
1227 struct bgp_info
*parent_ri
)
1229 struct bgp_node
*rn
;
1230 struct bgp_info
*ri
;
1231 struct attr
*attr_new
;
1234 /* Create (or fetch) route within the VNI. */
1235 /* NOTE: There is no RD here. */
1236 rn
= bgp_node_get(vpn
->route_table
, (struct prefix
*)p
);
1238 /* Check if route entry is already present. */
1239 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1241 && (struct bgp_info
*)ri
->extra
->parent
== parent_ri
)
1245 /* Add (or update) attribute to hash. */
1246 attr_new
= bgp_attr_intern(parent_ri
->attr
);
1248 /* Create new route with its attribute. */
1249 ri
= info_make(parent_ri
->type
, parent_ri
->sub_type
, 0,
1250 parent_ri
->peer
, attr_new
, rn
);
1251 SET_FLAG(ri
->flags
, BGP_INFO_VALID
);
1252 bgp_info_extra_get(ri
);
1253 ri
->extra
->parent
= parent_ri
;
1254 if (parent_ri
->extra
)
1255 memcpy(&ri
->extra
->label
, &parent_ri
->extra
->label
,
1257 bgp_info_add(rn
, ri
);
1259 if (attrhash_cmp(ri
->attr
, parent_ri
->attr
)
1260 && !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
1261 bgp_unlock_node(rn
);
1264 /* The attribute has changed. */
1265 /* Add (or update) attribute to hash. */
1266 attr_new
= bgp_attr_intern(parent_ri
->attr
);
1268 /* Restore route, if needed. */
1269 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
1270 bgp_info_restore(rn
, ri
);
1272 /* Mark if nexthop has changed. */
1273 if (!IPV4_ADDR_SAME(&ri
->attr
->nexthop
, &attr_new
->nexthop
))
1274 SET_FLAG(ri
->flags
, BGP_INFO_IGP_CHANGED
);
1276 /* Unintern existing, set to new. */
1277 bgp_attr_unintern(&ri
->attr
);
1278 ri
->attr
= attr_new
;
1279 ri
->uptime
= bgp_clock();
1282 /* Perform route selection and update zebra, if required. */
1283 ret
= evpn_route_select_install(bgp
, vpn
, rn
);
1289 * Uninstall route entry from the VNI routing table and send message
1290 * to zebra, if appropriate.
1292 static int uninstall_evpn_route_entry(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1293 struct prefix_evpn
*p
,
1294 struct bgp_info
*parent_ri
)
1296 struct bgp_node
*rn
;
1297 struct bgp_info
*ri
;
1300 /* Locate route within the VNI. */
1301 /* NOTE: There is no RD here. */
1302 rn
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)p
);
1306 /* Find matching route entry. */
1307 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1309 && (struct bgp_info
*)ri
->extra
->parent
== parent_ri
)
1315 /* Mark entry for deletion */
1316 bgp_info_delete(rn
, ri
);
1318 /* Perform route selection and update zebra, if required. */
1319 ret
= evpn_route_select_install(bgp
, vpn
, rn
);
1321 /* Unlock route node. */
1322 bgp_unlock_node(rn
);
1328 * Given a route entry and a VNI, see if this route entry should be
1329 * imported into the VNI i.e., RTs match.
1331 static int is_route_matching_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1332 struct bgp_info
*ri
)
1334 struct attr
*attr
= ri
->attr
;
1335 struct ecommunity
*ecom
;
1339 /* Route should have valid RT to be even considered. */
1340 if (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)))
1343 ecom
= attr
->ecommunity
;
1344 if (!ecom
|| !ecom
->size
)
1347 /* For each extended community RT, see if it matches this VNI. If any RT
1348 * matches, we're done.
1350 for (i
= 0; i
< ecom
->size
; i
++) {
1352 u_char type
, sub_type
;
1353 struct ecommunity_val
*eval
;
1354 struct ecommunity_val eval_tmp
;
1355 struct irt_node
*irt
;
1357 /* Only deal with RTs */
1358 pnt
= (ecom
->val
+ (i
* ECOMMUNITY_SIZE
));
1359 eval
= (struct ecommunity_val
*)(ecom
->val
1360 + (i
* ECOMMUNITY_SIZE
));
1363 if (sub_type
!= ECOMMUNITY_ROUTE_TARGET
)
1366 /* See if this RT matches specified VNIs import RTs */
1367 irt
= lookup_import_rt(bgp
, eval
);
1368 if (irt
&& irt
->vnis
)
1369 if (is_vni_present_in_irt_vnis(irt
->vnis
, vpn
))
1372 /* Also check for non-exact match. In this, we mask out the AS
1374 * only check on the local-admin sub-field. This is to
1376 * VNI as the RT for EBGP peering too.
1379 if (type
== ECOMMUNITY_ENCODE_AS
1380 || type
== ECOMMUNITY_ENCODE_AS4
1381 || type
== ECOMMUNITY_ENCODE_IP
) {
1382 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
1383 mask_ecom_global_admin(&eval_tmp
, eval
);
1384 irt
= lookup_import_rt(bgp
, &eval_tmp
);
1386 if (irt
&& irt
->vnis
)
1387 if (is_vni_present_in_irt_vnis(irt
->vnis
, vpn
))
1395 * Install or uninstall routes of specified type that are appropriate for this
1398 static int install_uninstall_routes_for_vni(struct bgp
*bgp
,
1399 struct bgpevpn
*vpn
,
1400 bgp_evpn_route_type rtype
,
1405 struct bgp_node
*rd_rn
, *rn
;
1406 struct bgp_table
*table
;
1407 struct bgp_info
*ri
;
1413 /* Walk entire global routing table and evaluate routes which could be
1414 * imported into this VPN. Note that we cannot just look at the routes
1416 * the VNI's RD - remote routes applicable for this VNI could have any
1419 /* EVPN routes are a 2-level table. */
1420 for (rd_rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rd_rn
;
1421 rd_rn
= bgp_route_next(rd_rn
)) {
1422 table
= (struct bgp_table
*)(rd_rn
->info
);
1426 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
1427 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
1429 if (evp
->prefix
.route_type
!= rtype
)
1432 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
1433 /* Consider "valid" remote routes applicable for
1435 if (!(CHECK_FLAG(ri
->flags
, BGP_INFO_VALID
)
1436 && ri
->type
== ZEBRA_ROUTE_BGP
1437 && ri
->sub_type
== BGP_ROUTE_NORMAL
))
1440 if (is_route_matching_for_vni(bgp
, vpn
, ri
)) {
1442 ret
= install_evpn_route_entry(
1445 ret
= uninstall_evpn_route_entry(
1450 "%u: Failed to %s EVPN %s route in VNI %u",
1454 rtype
== BGP_EVPN_MAC_IP_ROUTE
1469 * Install any existing remote routes applicable for this VNI into its
1470 * routing table. This is invoked when a VNI becomes "live" or its Import
1473 static int install_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1477 /* Install type-3 routes followed by type-2 routes - the ones applicable
1480 ret
= install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_IMET_ROUTE
,
1485 return install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_MAC_IP_ROUTE
,
1490 * Uninstall any existing remote routes for this VNI. One scenario in which
1491 * this is invoked is upon an import RT change.
1493 static int uninstall_routes_for_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1497 /* Uninstall type-2 routes followed by type-3 routes - the ones
1501 ret
= install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_MAC_IP_ROUTE
,
1506 return install_uninstall_routes_for_vni(bgp
, vpn
, BGP_EVPN_IMET_ROUTE
,
1511 * Install or uninstall route in matching VNIs (list).
1513 static int install_uninstall_route_in_vnis(struct bgp
*bgp
, afi_t afi
,
1514 safi_t safi
, struct prefix_evpn
*evp
,
1515 struct bgp_info
*ri
,
1516 struct list
*vnis
, int install
)
1518 struct bgpevpn
*vpn
;
1519 struct listnode
*node
, *nnode
;
1521 for (ALL_LIST_ELEMENTS(vnis
, node
, nnode
, vpn
)) {
1524 if (!is_vni_live(vpn
))
1528 ret
= install_evpn_route_entry(bgp
, vpn
, evp
, ri
);
1530 ret
= uninstall_evpn_route_entry(bgp
, vpn
, evp
, ri
);
1533 zlog_err("%u: Failed to %s EVPN %s route in VNI %u",
1534 bgp
->vrf_id
, install
? "install" : "uninstall",
1535 evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
1547 * Install or uninstall route for appropriate VNIs.
1549 static int install_uninstall_evpn_route(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1550 struct prefix
*p
, struct bgp_info
*ri
,
1553 struct prefix_evpn
*evp
= (struct prefix_evpn
*)p
;
1554 struct attr
*attr
= ri
->attr
;
1555 struct ecommunity
*ecom
;
1560 /* Only type-2 and type-3 routes go into a L2 VNI. */
1561 if (!(evp
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
1562 || evp
->prefix
.route_type
== BGP_EVPN_IMET_ROUTE
))
1565 /* If we don't have Route Target, nothing much to do. */
1566 if (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)))
1569 ecom
= attr
->ecommunity
;
1570 if (!ecom
|| !ecom
->size
)
1573 /* For each extended community RT, see which VNIs match and import
1574 * the route into matching VNIs.
1576 for (i
= 0; i
< ecom
->size
; i
++) {
1578 u_char type
, sub_type
;
1579 struct ecommunity_val
*eval
;
1580 struct ecommunity_val eval_tmp
;
1581 struct irt_node
*irt
;
1583 /* Only deal with RTs */
1584 pnt
= (ecom
->val
+ (i
* ECOMMUNITY_SIZE
));
1585 eval
= (struct ecommunity_val
*)(ecom
->val
1586 + (i
* ECOMMUNITY_SIZE
));
1589 if (sub_type
!= ECOMMUNITY_ROUTE_TARGET
)
1592 /* Are we interested in this RT? */
1593 irt
= lookup_import_rt(bgp
, eval
);
1594 if (irt
&& irt
->vnis
)
1595 install_uninstall_route_in_vnis(bgp
, afi
, safi
, evp
, ri
,
1598 /* Also check for non-exact match. In this, we mask out the AS
1600 * only check on the local-admin sub-field. This is to
1602 * VNI as the RT for EBGP peering too.
1605 if (type
== ECOMMUNITY_ENCODE_AS
1606 || type
== ECOMMUNITY_ENCODE_AS4
1607 || type
== ECOMMUNITY_ENCODE_IP
) {
1608 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
1609 mask_ecom_global_admin(&eval_tmp
, eval
);
1610 irt
= lookup_import_rt(bgp
, &eval_tmp
);
1612 if (irt
&& irt
->vnis
)
1613 install_uninstall_route_in_vnis(bgp
, afi
, safi
, evp
, ri
,
1621 * Update and advertise local routes for a VNI. Invoked upon router-id
1622 * change. Note that the processing is done only on the global route table
1623 * using routes that already exist in the per-VNI table.
1625 static int update_advertise_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1627 struct prefix_evpn p
;
1628 struct bgp_node
*rn
, *global_rn
;
1629 struct bgp_info
*ri
, *global_ri
;
1631 afi_t afi
= AFI_L2VPN
;
1632 safi_t safi
= SAFI_EVPN
;
1634 /* Locate type-3 route for VNI in the per-VNI table and use its
1635 * attributes to create and advertise the type-3 route for this VNI
1636 * in the global table.
1638 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
1639 rn
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)&p
);
1640 if (!rn
) /* unexpected */
1642 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1643 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
1644 && ri
->sub_type
== BGP_ROUTE_STATIC
)
1646 if (!ri
) /* unexpected */
1650 global_rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
1651 (struct prefix
*)&p
, &vpn
->prd
);
1652 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, attr
, 1, 0, &ri
,
1655 /* Schedule for processing and unlock node. */
1656 bgp_process(bgp
, global_rn
, afi
, safi
);
1657 bgp_unlock_node(global_rn
);
1659 /* Now, walk this VNI's route table and use the route and its attribute
1660 * to create and schedule route in global table.
1662 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
1663 rn
= bgp_route_next(rn
)) {
1664 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
1666 /* Identify MAC-IP local routes. */
1667 if (evp
->prefix
.route_type
!= BGP_EVPN_MAC_IP_ROUTE
)
1670 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1671 if (ri
->peer
== bgp
->peer_self
1672 && ri
->type
== ZEBRA_ROUTE_BGP
1673 && ri
->sub_type
== BGP_ROUTE_STATIC
)
1678 /* Create route in global routing table using this route entry's
1682 global_rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
,
1683 (struct prefix
*)evp
, &vpn
->prd
);
1685 update_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, attr
, 1,
1688 /* Schedule for processing and unlock node. */
1689 bgp_process(bgp
, global_rn
, afi
, safi
);
1690 bgp_unlock_node(global_rn
);
1697 * Delete (and withdraw) local routes for a VNI - only from the global
1698 * table. Invoked upon router-id change.
1700 static int delete_withdraw_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1703 struct prefix_evpn p
;
1704 struct bgp_node
*global_rn
;
1705 struct bgp_info
*ri
;
1706 afi_t afi
= AFI_L2VPN
;
1707 safi_t safi
= SAFI_EVPN
;
1709 /* Delete and withdraw locally learnt type-2 routes (MACIP)
1710 * for this VNI - from the global table.
1712 ret
= delete_global_type2_routes(bgp
, vpn
);
1716 /* Remove type-3 route for this VNI from global table. */
1717 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
1718 global_rn
= bgp_afi_node_lookup(bgp
->rib
[afi
][safi
], afi
, safi
,
1719 (struct prefix
*)&p
, &vpn
->prd
);
1721 /* Delete route entry in the global EVPN table. */
1722 delete_evpn_route_entry(bgp
, vpn
, afi
, safi
, global_rn
, &ri
);
1724 /* Schedule for processing - withdraws to peers happen from
1728 bgp_process(bgp
, global_rn
, afi
, safi
);
1729 bgp_unlock_node(global_rn
);
1736 * Handle router-id change. Update and advertise local routes corresponding
1737 * to this VNI from peers. Note that this is invoked after updating the
1738 * router-id. The routes in the per-VNI table are used to create routes in
1739 * the global table and schedule them.
1741 static void update_router_id_vni(struct hash_backet
*backet
, struct bgp
*bgp
)
1743 struct bgpevpn
*vpn
;
1745 vpn
= (struct bgpevpn
*)backet
->data
;
1748 zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__
);
1752 /* Skip VNIs with configured RD. */
1753 if (is_rd_configured(vpn
))
1756 bgp_evpn_derive_auto_rd(bgp
, vpn
);
1757 update_advertise_vni_routes(bgp
, vpn
);
1761 * Handle router-id change. Delete and withdraw local routes corresponding
1762 * to this VNI from peers. Note that this is invoked prior to updating
1763 * the router-id and is done only on the global route table, the routes
1764 * are needed in the per-VNI table to re-advertise with new router id.
1766 static void withdraw_router_id_vni(struct hash_backet
*backet
, struct bgp
*bgp
)
1768 struct bgpevpn
*vpn
;
1770 vpn
= (struct bgpevpn
*)backet
->data
;
1773 zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__
);
1777 /* Skip VNIs with configured RD. */
1778 if (is_rd_configured(vpn
))
1781 delete_withdraw_vni_routes(bgp
, vpn
);
1785 * Process received EVPN type-2 route (advertise or withdraw).
1787 static int process_type2_route(struct peer
*peer
, afi_t afi
, safi_t safi
,
1788 struct attr
*attr
, u_char
*pfx
, int psize
,
1789 u_int32_t addpath_id
)
1791 struct prefix_rd prd
;
1792 struct prefix_evpn p
;
1795 mpls_label_t
*label_pnt
;
1798 /* Type-2 route should be either 33, 37 or 49 bytes or an
1799 * additional 3 bytes if there is a second label (VNI):
1800 * RD (8), ESI (10), Eth Tag (4), MAC Addr Len (1),
1801 * MAC Addr (6), IP len (1), IP (0, 4 or 16),
1802 * MPLS Lbl1 (3), MPLS Lbl2 (0 or 3)
1804 if (psize
!= 33 && psize
!= 37 && psize
!= 49 && psize
!= 36
1805 && psize
!= 40 && psize
!= 52) {
1806 zlog_err("%u:%s - Rx EVPN Type-2 NLRI with invalid length %d",
1807 peer
->bgp
->vrf_id
, peer
->host
, psize
);
1811 /* Make prefix_rd */
1812 prd
.family
= AF_UNSPEC
;
1814 memcpy(&prd
.val
, pfx
, 8);
1817 /* Make EVPN prefix. */
1818 memset(&p
, 0, sizeof(struct prefix_evpn
));
1820 p
.prefixlen
= EVPN_TYPE_2_ROUTE_PREFIXLEN
;
1821 p
.prefix
.route_type
= BGP_EVPN_MAC_IP_ROUTE
;
1823 /* Skip over Ethernet Seg Identifier for now. */
1826 /* Skip over Ethernet Tag for now. */
1829 /* Get the MAC Addr len */
1830 macaddr_len
= *pfx
++;
1832 /* Get the MAC Addr */
1833 if (macaddr_len
== (ETH_ALEN
* 8)) {
1834 memcpy(&p
.prefix
.mac
.octet
, pfx
, ETH_ALEN
);
1838 "%u:%s - Rx EVPN Type-2 NLRI with unsupported MAC address length %d",
1839 peer
->bgp
->vrf_id
, peer
->host
, macaddr_len
);
1845 ipaddr_len
= *pfx
++;
1846 if (ipaddr_len
!= 0 && ipaddr_len
!= IPV4_MAX_BITLEN
1847 && ipaddr_len
!= IPV6_MAX_BITLEN
) {
1849 "%u:%s - Rx EVPN Type-2 NLRI with unsupported IP address length %d",
1850 peer
->bgp
->vrf_id
, peer
->host
, ipaddr_len
);
1855 ipaddr_len
/= 8; /* Convert to bytes. */
1856 p
.prefix
.ip
.ipa_type
= (ipaddr_len
== IPV4_MAX_BYTELEN
)
1859 memcpy(&p
.prefix
.ip
.ip
.addr
, pfx
, ipaddr_len
);
1863 /* Get the VNI (in MPLS label field). */
1864 /* Note: We ignore the second VNI, if any. */
1865 label_pnt
= (mpls_label_t
*)pfx
;
1867 /* Process the route. */
1869 ret
= bgp_update(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
1870 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
1871 &prd
, label_pnt
, 0, NULL
);
1873 ret
= bgp_withdraw(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
1874 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
1875 &prd
, label_pnt
, NULL
);
1880 * Process received EVPN type-3 route (advertise or withdraw).
1882 static int process_type3_route(struct peer
*peer
, afi_t afi
, safi_t safi
,
1883 struct attr
*attr
, u_char
*pfx
, int psize
,
1884 u_int32_t addpath_id
)
1886 struct prefix_rd prd
;
1887 struct prefix_evpn p
;
1891 /* Type-3 route should be either 17 or 29 bytes: RD (8), Eth Tag (4),
1892 * IP len (1) and IP (4 or 16).
1894 if (psize
!= 17 && psize
!= 29) {
1895 zlog_err("%u:%s - Rx EVPN Type-3 NLRI with invalid length %d",
1896 peer
->bgp
->vrf_id
, peer
->host
, psize
);
1900 /* Make prefix_rd */
1901 prd
.family
= AF_UNSPEC
;
1903 memcpy(&prd
.val
, pfx
, 8);
1906 /* Make EVPN prefix. */
1907 memset(&p
, 0, sizeof(struct prefix_evpn
));
1909 p
.prefixlen
= EVPN_TYPE_3_ROUTE_PREFIXLEN
;
1910 p
.prefix
.route_type
= BGP_EVPN_IMET_ROUTE
;
1912 /* Skip over Ethernet Tag for now. */
1916 ipaddr_len
= *pfx
++;
1917 if (ipaddr_len
== IPV4_MAX_BITLEN
) {
1918 p
.prefix
.ip
.ipa_type
= IPADDR_V4
;
1919 memcpy(&p
.prefix
.ip
.ip
.addr
, pfx
, IPV4_MAX_BYTELEN
);
1922 "%u:%s - Rx EVPN Type-3 NLRI with unsupported IP address length %d",
1923 peer
->bgp
->vrf_id
, peer
->host
, ipaddr_len
);
1927 /* Process the route. */
1929 ret
= bgp_update(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
1930 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
1931 &prd
, NULL
, 0, NULL
);
1933 ret
= bgp_withdraw(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
1934 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
1940 * Process received EVPN type-5 route (advertise or withdraw).
1942 static int process_type5_route(struct peer
*peer
, afi_t afi
, safi_t safi
,
1943 struct attr
*attr
, u_char
*pfx
, int psize
,
1944 u_int32_t addpath_id
, int withdraw
)
1946 struct prefix_rd prd
;
1947 struct prefix_evpn p
;
1948 struct bgp_route_evpn evpn
;
1951 mpls_label_t
*label_pnt
;
1954 /* Type-5 route should be 34 or 58 bytes:
1955 * RD (8), ESI (10), Eth Tag (4), IP len (1), IP (4 or 16),
1956 * GW (4 or 16) and VNI (3).
1957 * Note that the IP and GW should both be IPv4 or both IPv6.
1959 if (psize
!= 34 && psize
!= 58) {
1960 zlog_err("%u:%s - Rx EVPN Type-5 NLRI with invalid length %d",
1961 peer
->bgp
->vrf_id
, peer
->host
, psize
);
1965 /* Make prefix_rd */
1966 prd
.family
= AF_UNSPEC
;
1968 memcpy(&prd
.val
, pfx
, 8);
1971 /* Make EVPN prefix. */
1972 memset(&p
, 0, sizeof(struct prefix_evpn
));
1974 p
.prefix
.route_type
= BGP_EVPN_IP_PREFIX_ROUTE
;
1976 /* Additional information outside of prefix - ESI and GW IP */
1977 memset(&evpn
, 0, sizeof(evpn
));
1980 memcpy(&evpn
.eth_s_id
.val
, pfx
, 10);
1983 /* Fetch Ethernet Tag. */
1984 memcpy(ð_tag
, pfx
, 4);
1985 p
.prefix
.eth_tag
= ntohl(eth_tag
);
1988 /* Fetch IP prefix length. */
1990 if (ippfx_len
> IPV6_MAX_BITLEN
) {
1992 "%u:%s - Rx EVPN Type-5 NLRI with invalid IP Prefix length %d",
1993 peer
->bgp
->vrf_id
, peer
->host
, ippfx_len
);
1996 p
.prefix
.ip_prefix_length
= ippfx_len
;
1998 /* Determine IPv4 or IPv6 prefix */
1999 /* Since the address and GW are from the same family, this just becomes
2000 * a simple check on the total size.
2003 SET_IPADDR_V4(&p
.prefix
.ip
);
2004 memcpy(&p
.prefix
.ip
.ipaddr_v4
, pfx
, 4);
2006 memcpy(&evpn
.gw_ip
.ipv4
, pfx
, 4);
2008 p
.prefixlen
= PREFIX_LEN_ROUTE_TYPE_5_IPV4
;
2010 SET_IPADDR_V6(&p
.prefix
.ip
);
2011 memcpy(&p
.prefix
.ip
.ipaddr_v6
, pfx
, 16);
2013 memcpy(&evpn
.gw_ip
.ipv6
, pfx
, 16);
2015 p
.prefixlen
= PREFIX_LEN_ROUTE_TYPE_5_IPV6
;
2018 label_pnt
= (mpls_label_t
*)pfx
;
2020 /* Process the route. */
2022 ret
= bgp_update(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
2023 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
2024 &prd
, label_pnt
, 0, &evpn
);
2026 ret
= bgp_withdraw(peer
, (struct prefix
*)&p
, addpath_id
, attr
,
2027 afi
, safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
2028 &prd
, label_pnt
, &evpn
);
2033 static void evpn_mpattr_encode_type5(struct stream
*s
, struct prefix
*p
,
2034 struct prefix_rd
*prd
, mpls_label_t
*label
,
2039 struct evpn_addr
*p_evpn_p
;
2041 memset(&temp
, 0, 16);
2042 if (p
->family
!= AF_EVPN
)
2044 p_evpn_p
= &(p
->u
.prefix_evpn
);
2046 if (IS_IPADDR_V4(&p_evpn_p
->ip
))
2049 len
= 32; /* ipv6 */
2050 stream_putc(s
, BGP_EVPN_IP_PREFIX_ROUTE
);
2051 /* Prefix contains RD, ESI, EthTag, IP length, IP, GWIP and VNI */
2052 stream_putc(s
, 8 + 10 + 4 + 1 + len
+ 3);
2053 stream_put(s
, prd
->val
, 8);
2055 stream_put(s
, &(attr
->evpn_overlay
.eth_s_id
), 10);
2057 stream_put(s
, &temp
, 10);
2058 stream_putl(s
, p_evpn_p
->eth_tag
);
2059 stream_putc(s
, p_evpn_p
->ip_prefix_length
);
2060 if (IS_IPADDR_V4(&p_evpn_p
->ip
))
2061 stream_put_ipv4(s
, p_evpn_p
->ip
.ipaddr_v4
.s_addr
);
2063 stream_put(s
, &p_evpn_p
->ip
.ipaddr_v6
, 16);
2065 if (IS_IPADDR_V4(&p_evpn_p
->ip
))
2067 attr
->evpn_overlay
.gw_ip
.ipv4
.s_addr
);
2069 stream_put(s
, &(attr
->evpn_overlay
.gw_ip
.ipv6
), 16);
2071 if (IS_IPADDR_V4(&p_evpn_p
->ip
))
2072 stream_put_ipv4(s
, 0);
2074 stream_put(s
, &temp
, 16);
2078 stream_put(s
, label
, 3);
2084 * Cleanup specific VNI upon EVPN (advertise-all-vni) being disabled.
2086 static void cleanup_vni_on_disable(struct hash_backet
*backet
, struct bgp
*bgp
)
2088 struct bgpevpn
*vpn
= (struct bgpevpn
*)backet
->data
;
2090 /* Remove EVPN routes and schedule for processing. */
2091 delete_routes_for_vni(bgp
, vpn
);
2093 /* Clear "live" flag and see if hash needs to be freed. */
2094 UNSET_FLAG(vpn
->flags
, VNI_FLAG_LIVE
);
2095 if (!is_vni_configured(vpn
))
2096 bgp_evpn_free(bgp
, vpn
);
2100 * Free a VNI entry; iterator function called during cleanup.
2102 static void free_vni_entry(struct hash_backet
*backet
, struct bgp
*bgp
)
2104 struct bgpevpn
*vpn
;
2106 vpn
= (struct bgpevpn
*)backet
->data
;
2107 delete_all_vni_routes(bgp
, vpn
);
2108 bgp_evpn_free(bgp
, vpn
);
2117 * Handle change to BGP router id. This is invoked twice by the change
2118 * handler, first before the router id has been changed and then after
2119 * the router id has been changed. The first invocation will result in
2120 * local routes for all VNIs being deleted and withdrawn and the next
2121 * will result in the routes being re-advertised.
2123 void bgp_evpn_handle_router_id_update(struct bgp
*bgp
, int withdraw
)
2126 hash_iterate(bgp
->vnihash
,
2127 (void (*)(struct hash_backet
*,
2128 void *))withdraw_router_id_vni
,
2131 hash_iterate(bgp
->vnihash
,
2132 (void (*)(struct hash_backet
*,
2133 void *))update_router_id_vni
,
2138 * Handle change to export RT - update and advertise local routes.
2140 int bgp_evpn_handle_export_rt_change(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2142 return update_routes_for_vni(bgp
, vpn
);
2146 * Handle change to RD. This is invoked twice by the change handler,
2147 * first before the RD has been changed and then after the RD has
2148 * been changed. The first invocation will result in local routes
2149 * of this VNI being deleted and withdrawn and the next will result
2150 * in the routes being re-advertised.
2152 void bgp_evpn_handle_rd_change(struct bgp
*bgp
, struct bgpevpn
*vpn
,
2156 delete_withdraw_vni_routes(bgp
, vpn
);
2158 update_advertise_vni_routes(bgp
, vpn
);
2162 * Install routes for this VNI. Invoked upon change to Import RT.
2164 int bgp_evpn_install_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2166 return install_routes_for_vni(bgp
, vpn
);
2170 * Uninstall all routes installed for this VNI. Invoked upon change
2173 int bgp_evpn_uninstall_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2175 return uninstall_routes_for_vni(bgp
, vpn
);
2179 * Function to display "tag" in route as a VNI.
2181 char *bgp_evpn_label2str(mpls_label_t
*label
, char *buf
, int len
)
2185 vni
= label2vni(label
);
2186 snprintf(buf
, len
, "%u", vni
);
2191 * Function to convert evpn route to json format.
2192 * NOTE: We don't use prefix2str as the output here is a bit different.
2194 void bgp_evpn_route2json(struct prefix_evpn
*p
, json_object
*json
)
2196 char buf1
[ETHER_ADDR_STRLEN
];
2197 char buf2
[PREFIX2STR_BUFFER
];
2202 if (p
->prefix
.route_type
== BGP_EVPN_IMET_ROUTE
) {
2203 json_object_int_add(json
, "routeType", p
->prefix
.route_type
);
2204 json_object_int_add(json
, "ethTag", 0);
2205 json_object_int_add(json
, "ipLen",
2206 IS_EVPN_PREFIX_IPADDR_V4(p
)
2209 json_object_string_add(json
, "ip",
2210 inet_ntoa(p
->prefix
.ip
.ipaddr_v4
));
2211 } else if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
) {
2212 if (IS_EVPN_PREFIX_IPADDR_NONE(p
)) {
2213 json_object_int_add(json
, "routeType",
2214 p
->prefix
.route_type
);
2215 json_object_int_add(
2217 0); /* TODO: we don't support esi yet */
2218 json_object_int_add(json
, "ethTag", 0);
2219 json_object_int_add(json
, "macLen", 8 * ETH_ALEN
);
2220 json_object_string_add(json
, "mac",
2221 prefix_mac2str(&p
->prefix
.mac
,
2227 family
= IS_EVPN_PREFIX_IPADDR_V4(p
) ? AF_INET
2230 json_object_int_add(json
, "routeType",
2231 p
->prefix
.route_type
);
2232 json_object_int_add(
2234 0); /* TODO: we don't support esi yet */
2235 json_object_int_add(json
, "ethTag", 0);
2236 json_object_int_add(json
, "macLen", 8 * ETH_ALEN
);
2237 json_object_string_add(json
, "mac",
2238 prefix_mac2str(&p
->prefix
.mac
,
2241 json_object_int_add(json
, "ipLen",
2242 IS_EVPN_PREFIX_IPADDR_V4(p
)
2245 json_object_string_add(
2247 inet_ntop(family
, &p
->prefix
.ip
.ip
.addr
, buf2
,
2248 PREFIX2STR_BUFFER
));
2251 /* Currently, this is to cater to other AF_ETHERNET code. */
2256 * Function to convert evpn route to string.
2257 * NOTE: We don't use prefix2str as the output here is a bit different.
2259 char *bgp_evpn_route2str(struct prefix_evpn
*p
, char *buf
, int len
)
2261 char buf1
[ETHER_ADDR_STRLEN
];
2262 char buf2
[PREFIX2STR_BUFFER
];
2264 if (p
->prefix
.route_type
== BGP_EVPN_IMET_ROUTE
) {
2265 snprintf(buf
, len
, "[%d]:[0]:[%d]:[%s]", p
->prefix
.route_type
,
2266 IS_EVPN_PREFIX_IPADDR_V4(p
) ? IPV4_MAX_BITLEN
2268 inet_ntoa(p
->prefix
.ip
.ipaddr_v4
));
2269 } else if (p
->prefix
.route_type
== BGP_EVPN_MAC_IP_ROUTE
) {
2270 if (IS_EVPN_PREFIX_IPADDR_NONE(p
))
2271 snprintf(buf
, len
, "[%d]:[0]:[0]:[%d]:[%s]",
2272 p
->prefix
.route_type
, 8 * ETH_ALEN
,
2273 prefix_mac2str(&p
->prefix
.mac
, buf1
,
2278 family
= IS_EVPN_PREFIX_IPADDR_V4(p
) ? AF_INET
2280 snprintf(buf
, len
, "[%d]:[0]:[0]:[%d]:[%s]:[%d]:[%s]",
2281 p
->prefix
.route_type
, 8 * ETH_ALEN
,
2282 prefix_mac2str(&p
->prefix
.mac
, buf1
,
2284 family
== AF_INET
? IPV4_MAX_BITLEN
2286 inet_ntop(family
, &p
->prefix
.ip
.ip
.addr
, buf2
,
2287 PREFIX2STR_BUFFER
));
2290 /* For EVPN route types not supported yet. */
2297 * Encode EVPN prefix in Update (MP_REACH)
2299 void bgp_evpn_encode_prefix(struct stream
*s
, struct prefix
*p
,
2300 struct prefix_rd
*prd
, mpls_label_t
*label
,
2301 struct attr
*attr
, int addpath_encode
,
2302 u_int32_t addpath_tx_id
)
2304 struct prefix_evpn
*evp
= (struct prefix_evpn
*)p
;
2308 stream_putl(s
, addpath_tx_id
);
2311 stream_putc(s
, evp
->prefix
.route_type
);
2313 switch (evp
->prefix
.route_type
) {
2314 case BGP_EVPN_MAC_IP_ROUTE
:
2315 if (IS_EVPN_PREFIX_IPADDR_V4(evp
))
2316 ipa_len
= IPV4_MAX_BYTELEN
;
2317 else if (IS_EVPN_PREFIX_IPADDR_V6(evp
))
2318 ipa_len
= IPV6_MAX_BYTELEN
;
2319 stream_putc(s
, 33 + ipa_len
); // 1 VNI
2320 stream_put(s
, prd
->val
, 8); /* RD */
2321 stream_put(s
, 0, 10); /* ESI */
2322 stream_putl(s
, 0); /* Ethernet Tag ID */
2323 stream_putc(s
, 8 * ETH_ALEN
); /* Mac Addr Len - bits */
2324 stream_put(s
, evp
->prefix
.mac
.octet
, 6); /* Mac Addr */
2325 stream_putc(s
, 8 * ipa_len
); /* IP address Length */
2327 stream_put(s
, &evp
->prefix
.ip
.ip
.addr
,
2329 stream_put(s
, label
,
2330 BGP_LABEL_BYTES
); /* VNI is contained in 'tag' */
2333 case BGP_EVPN_IMET_ROUTE
:
2334 stream_putc(s
, 17); // TODO: length - assumes IPv4 address
2335 stream_put(s
, prd
->val
, 8); /* RD */
2336 stream_putl(s
, 0); /* Ethernet Tag ID */
2337 stream_putc(s
, IPV4_MAX_BITLEN
); /* IP address Length - bits */
2338 /* Originating Router's IP Addr */
2339 stream_put_in_addr(s
, &evp
->prefix
.ip
.ipaddr_v4
);
2342 case BGP_EVPN_IP_PREFIX_ROUTE
:
2343 /* TODO: AddPath support. */
2344 evpn_mpattr_encode_type5(s
, p
, prd
, label
, attr
);
2352 int bgp_nlri_parse_evpn(struct peer
*peer
, struct attr
*attr
,
2353 struct bgp_nlri
*packet
, int withdraw
)
2359 u_int32_t addpath_id
;
2360 int addpath_encoded
;
2366 /* Check peer status. */
2367 if (peer
->status
!= Established
) {
2368 zlog_err("%u:%s - EVPN update received in state %d",
2369 peer
->bgp
->vrf_id
, peer
->host
, peer
->status
);
2373 /* Start processing the NLRI - there may be multiple in the MP_REACH */
2375 lim
= pnt
+ packet
->length
;
2377 safi
= packet
->safi
;
2381 (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
2382 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
2383 PEER_CAP_ADDPATH_AF_TX_RCV
));
2385 for (; pnt
< lim
; pnt
+= psize
) {
2386 /* Clear prefix structure. */
2387 memset(&p
, 0, sizeof(struct prefix
));
2389 /* Deal with path-id if AddPath is supported. */
2390 if (addpath_encoded
) {
2391 /* When packet overflow occurs return immediately. */
2392 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
2395 addpath_id
= ntohl(*((uint32_t *)pnt
));
2396 pnt
+= BGP_ADDPATH_ID_LEN
;
2399 /* All EVPN NLRI types start with type and length. */
2404 psize
= rlen
= *pnt
++;
2406 /* When packet overflow occur return immediately. */
2407 if (pnt
+ psize
> lim
)
2411 case BGP_EVPN_MAC_IP_ROUTE
:
2412 if (process_type2_route(peer
, afi
, safi
,
2413 withdraw
? NULL
: attr
, pnt
,
2414 psize
, addpath_id
)) {
2416 "%u:%s - Error in processing EVPN type-2 NLRI size %d",
2417 peer
->bgp
->vrf_id
, peer
->host
, psize
);
2422 case BGP_EVPN_IMET_ROUTE
:
2423 if (process_type3_route(peer
, afi
, safi
,
2424 withdraw
? NULL
: attr
, pnt
,
2425 psize
, addpath_id
)) {
2427 "%u:%s - Error in processing EVPN type-3 NLRI size %d",
2428 peer
->bgp
->vrf_id
, peer
->host
, psize
);
2433 case BGP_EVPN_IP_PREFIX_ROUTE
:
2434 if (process_type5_route(peer
, afi
, safi
, attr
, pnt
,
2435 psize
, addpath_id
, withdraw
)) {
2437 "%u:%s - Error in processing EVPN type-5 NLRI size %d",
2438 peer
->bgp
->vrf_id
, peer
->host
, psize
);
2448 /* Packet length consistency check. */
2457 * Map the RTs (configured or automatically derived) of a VNI to the VNI.
2458 * The mapping will be used during route processing.
2460 void bgp_evpn_map_vni_to_its_rts(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2463 struct ecommunity_val
*eval
;
2464 struct listnode
*node
, *nnode
;
2465 struct ecommunity
*ecom
;
2467 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
)) {
2468 for (i
= 0; i
< ecom
->size
; i
++) {
2469 eval
= (struct ecommunity_val
*)(ecom
->val
2471 * ECOMMUNITY_SIZE
));
2472 map_vni_to_rt(bgp
, vpn
, eval
);
2478 * Unmap the RTs (configured or automatically derived) of a VNI from the VNI.
2480 void bgp_evpn_unmap_vni_from_its_rts(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2483 struct ecommunity_val
*eval
;
2484 struct listnode
*node
, *nnode
;
2485 struct ecommunity
*ecom
;
2487 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
)) {
2488 for (i
= 0; i
< ecom
->size
; i
++) {
2489 struct irt_node
*irt
;
2490 struct ecommunity_val eval_tmp
;
2492 eval
= (struct ecommunity_val
*)(ecom
->val
2494 * ECOMMUNITY_SIZE
));
2495 /* If using "automatic" RT, we only care about the
2496 * local-admin sub-field.
2497 * This is to facilitate using VNI as the RT for EBGP
2500 memcpy(&eval_tmp
, eval
, ECOMMUNITY_SIZE
);
2501 if (!is_import_rt_configured(vpn
))
2502 mask_ecom_global_admin(&eval_tmp
, eval
);
2504 irt
= lookup_import_rt(bgp
, &eval_tmp
);
2506 unmap_vni_from_rt(bgp
, vpn
, irt
);
2512 * Derive Import RT automatically for VNI and map VNI to RT.
2513 * The mapping will be used during route processing.
2515 void bgp_evpn_derive_auto_rt_import(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2517 form_auto_rt(bgp
, vpn
, vpn
->import_rtl
);
2518 UNSET_FLAG(vpn
->flags
, VNI_FLAG_IMPRT_CFGD
);
2521 bgp_evpn_map_vni_to_its_rts(bgp
, vpn
);
2525 * Derive Export RT automatically for VNI.
2527 void bgp_evpn_derive_auto_rt_export(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2529 form_auto_rt(bgp
, vpn
, vpn
->export_rtl
);
2530 UNSET_FLAG(vpn
->flags
, VNI_FLAG_EXPRT_CFGD
);
2534 * Derive RD automatically for VNI using passed information - it
2535 * is of the form RouterId:unique-id-for-vni.
2537 void bgp_evpn_derive_auto_rd(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2541 vpn
->prd
.family
= AF_UNSPEC
;
2542 vpn
->prd
.prefixlen
= 64;
2543 sprintf(buf
, "%s:%hu", inet_ntoa(bgp
->router_id
), vpn
->rd_id
);
2544 str2prefix_rd(buf
, &vpn
->prd
);
2545 UNSET_FLAG(vpn
->flags
, VNI_FLAG_RD_CFGD
);
2551 struct bgpevpn
*bgp_evpn_lookup_vni(struct bgp
*bgp
, vni_t vni
)
2553 struct bgpevpn
*vpn
;
2556 memset(&tmp
, 0, sizeof(struct bgpevpn
));
2558 vpn
= hash_lookup(bgp
->vnihash
, &tmp
);
2563 * Create a new vpn - invoked upon configuration or zebra notification.
2565 struct bgpevpn
*bgp_evpn_new(struct bgp
*bgp
, vni_t vni
,
2566 struct in_addr originator_ip
)
2568 struct bgpevpn
*vpn
;
2573 vpn
= XCALLOC(MTYPE_BGP_EVPN
, sizeof(struct bgpevpn
));
2577 /* Set values - RD and RT set to defaults. */
2579 vpn
->originator_ip
= originator_ip
;
2581 /* Initialize route-target import and export lists */
2582 vpn
->import_rtl
= list_new();
2583 vpn
->import_rtl
->cmp
= (int (*)(void *, void *))evpn_route_target_cmp
;
2584 vpn
->export_rtl
= list_new();
2585 vpn
->export_rtl
->cmp
= (int (*)(void *, void *))evpn_route_target_cmp
;
2586 bf_assign_index(bgp
->rd_idspace
, vpn
->rd_id
);
2587 derive_rd_rt_for_vni(bgp
, vpn
);
2589 /* Initialize EVPN route table. */
2590 vpn
->route_table
= bgp_table_init(AFI_L2VPN
, SAFI_EVPN
);
2593 if (!hash_get(bgp
->vnihash
, vpn
, hash_alloc_intern
)) {
2594 XFREE(MTYPE_BGP_EVPN
, vpn
);
2597 QOBJ_REG(vpn
, bgpevpn
);
2602 * Free a given VPN - called in multiple scenarios such as zebra
2603 * notification, configuration being deleted, advertise-all-vni disabled etc.
2604 * This just frees appropriate memory, caller should have taken other
2607 void bgp_evpn_free(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2609 bgp_table_unlock(vpn
->route_table
);
2610 bgp_evpn_unmap_vni_from_its_rts(bgp
, vpn
);
2611 list_delete(vpn
->import_rtl
);
2612 list_delete(vpn
->export_rtl
);
2613 vpn
->import_rtl
= NULL
;
2614 vpn
->export_rtl
= NULL
;
2615 bf_release_index(bgp
->rd_idspace
, vpn
->rd_id
);
2616 hash_release(bgp
->vnihash
, vpn
);
2618 XFREE(MTYPE_BGP_EVPN
, vpn
);
2622 * Import route into matching VNI(s).
2624 int bgp_evpn_import_route(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
2625 struct prefix
*p
, struct bgp_info
*ri
)
2627 return install_uninstall_evpn_route(bgp
, afi
, safi
, p
, ri
, 1);
2631 * Unimport route from matching VNI(s).
2633 int bgp_evpn_unimport_route(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
2634 struct prefix
*p
, struct bgp_info
*ri
)
2636 return install_uninstall_evpn_route(bgp
, afi
, safi
, p
, ri
, 0);
2639 /* filter routes which have martian next hops */
2640 int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp
*bgp
)
2644 struct bgp_node
*rd_rn
, *rn
;
2645 struct bgp_table
*table
;
2646 struct bgp_info
*ri
;
2651 /* Walk entire global routing table and evaluate routes which could be
2652 * imported into this VPN. Note that we cannot just look at the routes
2653 * for the VNI's RD -
2654 * remote routes applicable for this VNI could have any RD.
2656 /* EVPN routes are a 2-level table. */
2657 for (rd_rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rd_rn
;
2658 rd_rn
= bgp_route_next(rd_rn
)) {
2659 table
= (struct bgp_table
*)(rd_rn
->info
);
2663 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
2665 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
2667 /* Consider "valid" remote routes applicable for
2669 if (!(ri
->type
== ZEBRA_ROUTE_BGP
2670 && ri
->sub_type
== BGP_ROUTE_NORMAL
))
2673 if (bgp_nexthop_self(bgp
, ri
->attr
->nexthop
)) {
2675 char attr_str
[BUFSIZ
];
2676 char pbuf
[PREFIX_STRLEN
];
2678 bgp_dump_attr(ri
->attr
, attr_str
,
2681 if (bgp_debug_update(ri
->peer
, &rn
->p
,
2684 "%u: prefix %s with attr %s - DENIED due to martian or self nexthop",
2691 bgp_evpn_unimport_route(bgp
, afi
, safi
,
2694 bgp_rib_remove(rn
, ri
, ri
->peer
, afi
,
2705 * Handle del of a local MACIP.
2707 int bgp_evpn_local_macip_del(struct bgp
*bgp
, vni_t vni
, struct ethaddr
*mac
,
2710 struct bgpevpn
*vpn
;
2711 struct prefix_evpn p
;
2713 if (!bgp
->vnihash
) {
2714 zlog_err("%u: VNI hash not created", bgp
->vrf_id
);
2718 /* Lookup VNI hash - should exist. */
2719 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
2720 if (!vpn
|| !is_vni_live(vpn
)) {
2721 zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP DEL",
2722 bgp
->vrf_id
, vni
, vpn
? "not live" : "not found");
2726 /* Remove EVPN type-2 route and schedule for processing. */
2727 build_evpn_type2_prefix(&p
, mac
, ip
);
2728 delete_evpn_route(bgp
, vpn
, &p
);
2734 * Handle add of a local MACIP.
2736 int bgp_evpn_local_macip_add(struct bgp
*bgp
, vni_t vni
, struct ethaddr
*mac
,
2737 struct ipaddr
*ip
, u_char flags
)
2739 struct bgpevpn
*vpn
;
2740 struct prefix_evpn p
;
2742 if (!bgp
->vnihash
) {
2743 zlog_err("%u: VNI hash not created", bgp
->vrf_id
);
2747 /* Lookup VNI hash - should exist. */
2748 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
2749 if (!vpn
|| !is_vni_live(vpn
)) {
2750 zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP ADD",
2751 bgp
->vrf_id
, vni
, vpn
? "not live" : "not found");
2755 /* Create EVPN type-2 route and schedule for processing. */
2756 build_evpn_type2_prefix(&p
, mac
, ip
);
2757 if (update_evpn_route(bgp
, vpn
, &p
, flags
)) {
2758 char buf
[ETHER_ADDR_STRLEN
];
2759 char buf2
[INET6_ADDRSTRLEN
];
2762 "%u:Failed to create Type-2 route, VNI %u %s MAC %s IP %s",
2763 bgp
->vrf_id
, vpn
->vni
,
2764 CHECK_FLAG(flags
, ZEBRA_MAC_TYPE_STICKY
) ? "sticky gateway"
2766 prefix_mac2str(mac
, buf
, sizeof(buf
)),
2767 ipaddr2str(ip
, buf2
, sizeof(buf2
)));
2775 * Handle del of a local VNI.
2777 int bgp_evpn_local_vni_del(struct bgp
*bgp
, vni_t vni
)
2779 struct bgpevpn
*vpn
;
2781 if (!bgp
->vnihash
) {
2782 zlog_err("%u: VNI hash not created", bgp
->vrf_id
);
2786 /* Locate VNI hash */
2787 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
2789 zlog_warn("%u: VNI hash entry for VNI %u not found at DEL",
2794 /* Remove all local EVPN routes and schedule for processing (to
2795 * withdraw from peers).
2797 delete_routes_for_vni(bgp
, vpn
);
2800 * tunnel is no longer active, del tunnel ip address from tip_hash
2802 bgp_tip_del(bgp
, &vpn
->originator_ip
);
2804 /* Clear "live" flag and see if hash needs to be freed. */
2805 UNSET_FLAG(vpn
->flags
, VNI_FLAG_LIVE
);
2806 if (!is_vni_configured(vpn
))
2807 bgp_evpn_free(bgp
, vpn
);
2813 * Handle add (or update) of a local VNI. The only VNI change we care
2814 * about is change to local-tunnel-ip.
2816 int bgp_evpn_local_vni_add(struct bgp
*bgp
, vni_t vni
,
2817 struct in_addr originator_ip
)
2819 struct bgpevpn
*vpn
;
2820 struct prefix_evpn p
;
2822 if (!bgp
->vnihash
) {
2823 zlog_err("%u: VNI hash not created", bgp
->vrf_id
);
2827 /* Lookup VNI. If present and no change, exit. */
2828 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
2830 if (is_vni_live(vpn
)
2831 && IPV4_ADDR_SAME(&vpn
->originator_ip
, &originator_ip
))
2832 /* Probably some other param has changed that we don't
2836 /* Local tunnel endpoint IP address has changed */
2837 handle_tunnel_ip_change(bgp
, vpn
, originator_ip
);
2840 /* Create or update as appropriate. */
2842 vpn
= bgp_evpn_new(bgp
, vni
, originator_ip
);
2845 "%u: Failed to allocate VNI entry for VNI %u - at Add",
2851 /* if the VNI is live already, there is nothing more to do */
2852 if (is_vni_live(vpn
))
2855 /* Mark as "live" */
2856 SET_FLAG(vpn
->flags
, VNI_FLAG_LIVE
);
2858 /* tunnel is now active, add tunnel-ip to db */
2859 bgp_tip_add(bgp
, &originator_ip
);
2861 /* filter routes as nexthop database has changed */
2862 bgp_filter_evpn_routes_upon_martian_nh_change(bgp
);
2864 /* Create EVPN type-3 route and schedule for processing. */
2865 build_evpn_type3_prefix(&p
, vpn
->originator_ip
);
2866 if (update_evpn_route(bgp
, vpn
, &p
, 0)) {
2867 zlog_err("%u: Type3 route creation failure for VNI %u",
2872 /* If we have learnt and retained remote routes (VTEPs, MACs) for this
2876 install_routes_for_vni(bgp
, vpn
);
2878 /* If we are advertising gateway mac-ip
2879 It needs to be conveyed again to zebra */
2880 bgp_zebra_advertise_gw_macip(bgp
, vpn
->advertise_gw_macip
, vpn
->vni
);
2886 * Cleanup EVPN information on disable - Need to delete and withdraw
2887 * EVPN routes from peers.
2889 void bgp_evpn_cleanup_on_disable(struct bgp
*bgp
)
2891 hash_iterate(bgp
->vnihash
, (void (*)(struct hash_backet
*,
2892 void *))cleanup_vni_on_disable
,
2897 * Cleanup EVPN information - invoked at the time of bgpd exit or when the
2898 * BGP instance (default) is being freed.
2900 void bgp_evpn_cleanup(struct bgp
*bgp
)
2903 hash_iterate(bgp
->vnihash
, (void (*)(struct hash_backet
*,
2904 void *))free_vni_entry
,
2906 if (bgp
->import_rt_hash
)
2907 hash_free(bgp
->import_rt_hash
);
2908 bgp
->import_rt_hash
= NULL
;
2910 hash_free(bgp
->vnihash
);
2911 bgp
->vnihash
= NULL
;
2912 bf_free(bgp
->rd_idspace
);
2916 * Initialization for EVPN
2919 * hash for RT to VNI
2920 * unique rd id space for auto derivation of RD for VNIs
2922 void bgp_evpn_init(struct bgp
*bgp
)
2925 hash_create(vni_hash_key_make
, vni_hash_cmp
, "BGP VNI Hash");
2926 bgp
->import_rt_hash
=
2927 hash_create(import_rt_hash_key_make
, import_rt_hash_cmp
,
2928 "BGP Import RT Hash");
2929 bf_init(bgp
->rd_idspace
, UINT16_MAX
);
2930 /*assign 0th index in the bitfield, so that we start with id 1*/
2931 bf_assign_zero_index(bgp
->rd_idspace
);