]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_evpn.c
bgpd, lib: Cleanup CI warnings from system
[mirror_frr.git] / bgpd / bgp_evpn.c
CommitLineData
7ef5a232 1/* Ethernet-VPN Packet and vty Processing File
896014f4 2 * Copyright (C) 2016 6WIND
128ea8ab 3 * Copyright (C) 2017 Cumulus Networks, Inc.
896014f4 4 *
128ea8ab 5 * This file is part of FRR.
896014f4
DL
6 *
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
10 * later version.
11 *
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.
16 *
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
20 */
7ef5a232 21
7ef5a232
PG
22#include <zebra.h>
23
24#include "command.h"
25#include "filter.h"
26#include "prefix.h"
27#include "log.h"
28#include "memory.h"
29#include "stream.h"
14c1a7bf 30#include "hash.h"
31#include "jhash.h"
128ea8ab 32#include "zclient.h"
7ef5a232
PG
33
34#include "bgpd/bgp_attr_evpn.h"
35#include "bgpd/bgpd.h"
36#include "bgpd/bgp_table.h"
37#include "bgpd/bgp_route.h"
38#include "bgpd/bgp_attr.h"
39#include "bgpd/bgp_mplsvpn.h"
9bedbb1e 40#include "bgpd/bgp_label.h"
7ef5a232 41#include "bgpd/bgp_evpn.h"
14c1a7bf 42#include "bgpd/bgp_evpn_private.h"
43#include "bgpd/bgp_ecommunity.h"
128ea8ab 44#include "bgpd/bgp_encap_types.h"
45#include "bgpd/bgp_debug.h"
46#include "bgpd/bgp_aspath.h"
d7d97010 47#include "bgpd/bgp_zebra.h"
db0e1937 48#include "bgpd/bgp_nexthop.h"
128ea8ab 49
50/*
51 * Definitions and external declarations.
52 */
53extern struct zclient *zclient;
54
55DEFINE_QOBJ_TYPE(bgpevpn)
50f74cf1 56DEFINE_QOBJ_TYPE(evpnes)
128ea8ab 57
58
59/*
60 * Static function declarations
61 */
50f74cf1 62static void delete_evpn_route_entry(struct bgp *bgp,
63 afi_t afi, safi_t safi,
64 struct bgp_node *rn,
d62a17ae 65 struct bgp_info **ri);
66static int delete_all_vni_routes(struct bgp *bgp, struct bgpevpn *vpn);
14c1a7bf 67
68/*
69 * Private functions.
70 */
71
50f74cf1 72/* compare two IPV4 VTEP IPs */
73static int evpn_vtep_ip_cmp(const void *p1, const void *p2)
74{
75 const struct in_addr *ip1 = p1;
76 const struct in_addr *ip2 = p2;
77
78 if (!ip1 && !ip2)
79 return 1;
80 if (!ip1 || !ip2)
81 return 0;
82 return (ip1->s_addr == ip2->s_addr);
83}
84
85/*
86 * Make hash key for ESI.
87 */
88static unsigned int esi_hash_keymake(void *p)
89{
90 struct evpnes *pes = p;
91 const void *pnt = (void *)pes->esi.val;
92
93 return jhash(pnt, ESI_BYTES, 0xa5a5a55a);
94}
95
96/*
97 * Compare two ESIs.
98 */
99static int esi_cmp(const void *p1, const void *p2)
100{
101 const struct evpnes *pes1 = p1;
102 const struct evpnes *pes2 = p2;
103
104 if (pes1 == NULL && pes2 == NULL)
105 return 1;
106
107 if (pes1 == NULL || pes2 == NULL)
108 return 0;
109
110 return (memcmp(pes1->esi.val, pes2->esi.val, ESI_BYTES) == 0);
111}
112
14c1a7bf 113/*
114 * Make vni hash key.
115 */
d62a17ae 116static unsigned int vni_hash_key_make(void *p)
14c1a7bf 117{
d62a17ae 118 struct bgpevpn *vpn = p;
119 return (jhash_1word(vpn->vni, 0));
14c1a7bf 120}
121
122/*
123 * Comparison function for vni hash
124 */
d62a17ae 125static int vni_hash_cmp(const void *p1, const void *p2)
14c1a7bf 126{
d62a17ae 127 const struct bgpevpn *vpn1 = p1;
128 const struct bgpevpn *vpn2 = p2;
14c1a7bf 129
d62a17ae 130 if (!vpn1 && !vpn2)
131 return 1;
132 if (!vpn1 || !vpn2)
133 return 0;
134 return (vpn1->vni == vpn2->vni);
14c1a7bf 135}
136
10ebe1ab
MK
137/*
138 * Make vrf import route target hash key.
139 */
140static unsigned int vrf_import_rt_hash_key_make(void *p)
141{
142 struct vrf_irt_node *irt = p;
143 char *pnt = irt->rt.val;
5a1b3fb5
DS
144
145 return jhash(pnt, 8, 0x5abc1234);
10ebe1ab
MK
146}
147
148/*
149 * Comparison function for vrf import rt hash
150 */
151static int vrf_import_rt_hash_cmp(const void *p1, const void *p2)
152{
153 const struct vrf_irt_node *irt1 = p1;
154 const struct vrf_irt_node *irt2 = p2;
155
156 if (irt1 == NULL && irt2 == NULL)
157 return 1;
158
159 if (irt1 == NULL || irt2 == NULL)
160 return 0;
161
162 return (memcmp(irt1->rt.val, irt2->rt.val, ECOMMUNITY_SIZE) == 0);
163}
164
165/*
166 * Create a new vrf import_rt in default instance
167 */
168static struct vrf_irt_node *vrf_import_rt_new(struct ecommunity_val *rt)
169{
170 struct bgp *bgp_def = NULL;
171 struct vrf_irt_node *irt;
172
173 bgp_def = bgp_get_default();
174 if (!bgp_def) {
175 zlog_err("vrf import rt new - def instance not created yet");
176 return NULL;
177 }
178
179 irt = XCALLOC(MTYPE_BGP_EVPN_VRF_IMPORT_RT,
180 sizeof(struct vrf_irt_node));
181 if (!irt)
182 return NULL;
183
184 irt->rt = *rt;
185 irt->vrfs = list_new();
186
187 /* Add to hash */
188 if (!hash_get(bgp_def->vrf_import_rt_hash, irt, hash_alloc_intern)) {
189 XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT, irt);
190 return NULL;
191 }
192
193 return irt;
194}
195
196/*
197 * Free the vrf import rt node
198 */
199static void vrf_import_rt_free(struct vrf_irt_node *irt)
200{
201 struct bgp *bgp_def = NULL;
202
203 bgp_def = bgp_get_default();
204 if (!bgp_def) {
205 zlog_err("vrf import rt free - def instance not created yet");
206 return;
207 }
208
209 hash_release(bgp_def->vrf_import_rt_hash, irt);
5d9cbca2 210 list_delete_and_null(&irt->vrfs);
10ebe1ab
MK
211 XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT, irt);
212}
213
214/*
215 * Function to lookup Import RT node - used to map a RT to set of
216 * VNIs importing routes with that RT.
217 */
218static struct vrf_irt_node *lookup_vrf_import_rt(struct ecommunity_val *rt)
219{
220 struct bgp *bgp_def = NULL;
221 struct vrf_irt_node *irt;
222 struct vrf_irt_node tmp;
223
224 bgp_def = bgp_get_default();
225 if (!bgp_def) {
226 zlog_err("vrf import rt lookup - def instance not created yet");
227 return NULL;
228 }
229
230 memset(&tmp, 0, sizeof(struct vrf_irt_node));
231 memcpy(&tmp.rt, rt, ECOMMUNITY_SIZE);
232 irt = hash_lookup(bgp_def->vrf_import_rt_hash, &tmp);
233 return irt;
234}
235
236/*
237 * Is specified VRF present on the RT's list of "importing" VRFs?
238 */
996c9314 239static int is_vrf_present_in_irt_vrfs(struct list *vrfs, struct bgp *bgp_vrf)
10ebe1ab
MK
240{
241 struct listnode *node = NULL, *nnode = NULL;
242 struct bgp *tmp_bgp_vrf = NULL;
243
244 for (ALL_LIST_ELEMENTS(vrfs, node, nnode, tmp_bgp_vrf)) {
245 if (tmp_bgp_vrf == bgp_vrf)
246 return 1;
247 }
248 return 0;
249}
250
14c1a7bf 251/*
252 * Make import route target hash key.
253 */
d62a17ae 254static unsigned int import_rt_hash_key_make(void *p)
14c1a7bf 255{
d62a17ae 256 struct irt_node *irt = p;
257 char *pnt = irt->rt.val;
5a1b3fb5
DS
258
259 return jhash(pnt, 8, 0xdeadbeef);
14c1a7bf 260}
261
262/*
263 * Comparison function for import rt hash
264 */
d62a17ae 265static int import_rt_hash_cmp(const void *p1, const void *p2)
14c1a7bf 266{
d62a17ae 267 const struct irt_node *irt1 = p1;
268 const struct irt_node *irt2 = p2;
14c1a7bf 269
d62a17ae 270 if (irt1 == NULL && irt2 == NULL)
271 return 1;
14c1a7bf 272
d62a17ae 273 if (irt1 == NULL || irt2 == NULL)
274 return 0;
14c1a7bf 275
d62a17ae 276 return (memcmp(irt1->rt.val, irt2->rt.val, ECOMMUNITY_SIZE) == 0);
14c1a7bf 277}
278
7724c0a1 279/*
128ea8ab 280 * Create a new import_rt
281 */
d62a17ae 282static struct irt_node *import_rt_new(struct bgp *bgp,
283 struct ecommunity_val *rt)
128ea8ab 284{
d62a17ae 285 struct irt_node *irt;
128ea8ab 286
d62a17ae 287 if (!bgp)
288 return NULL;
128ea8ab 289
d62a17ae 290 irt = XCALLOC(MTYPE_BGP_EVPN_IMPORT_RT, sizeof(struct irt_node));
291 if (!irt)
292 return NULL;
128ea8ab 293
d62a17ae 294 irt->rt = *rt;
295 irt->vnis = list_new();
128ea8ab 296
d62a17ae 297 /* Add to hash */
298 if (!hash_get(bgp->import_rt_hash, irt, hash_alloc_intern)) {
299 XFREE(MTYPE_BGP_EVPN_IMPORT_RT, irt);
300 return NULL;
301 }
128ea8ab 302
d62a17ae 303 return irt;
128ea8ab 304}
305
306/*
307 * Free the import rt node
7724c0a1 308 */
d62a17ae 309static void import_rt_free(struct bgp *bgp, struct irt_node *irt)
7724c0a1 310{
d62a17ae 311 hash_release(bgp->import_rt_hash, irt);
b1ab0dfe 312 list_delete_and_null(&irt->vnis);
d62a17ae 313 XFREE(MTYPE_BGP_EVPN_IMPORT_RT, irt);
7724c0a1 314}
315
14c1a7bf 316/*
128ea8ab 317 * Function to lookup Import RT node - used to map a RT to set of
318 * VNIs importing routes with that RT.
319 */
d62a17ae 320static struct irt_node *lookup_import_rt(struct bgp *bgp,
321 struct ecommunity_val *rt)
128ea8ab 322{
d62a17ae 323 struct irt_node *irt;
324 struct irt_node tmp;
128ea8ab 325
d62a17ae 326 memset(&tmp, 0, sizeof(struct irt_node));
327 memcpy(&tmp.rt, rt, ECOMMUNITY_SIZE);
328 irt = hash_lookup(bgp->import_rt_hash, &tmp);
329 return irt;
128ea8ab 330}
331
332/*
333 * Is specified VNI present on the RT's list of "importing" VNIs?
334 */
d62a17ae 335static int is_vni_present_in_irt_vnis(struct list *vnis, struct bgpevpn *vpn)
128ea8ab 336{
d62a17ae 337 struct listnode *node, *nnode;
338 struct bgpevpn *tmp_vpn;
128ea8ab 339
d62a17ae 340 for (ALL_LIST_ELEMENTS(vnis, node, nnode, tmp_vpn)) {
341 if (tmp_vpn == vpn)
342 return 1;
343 }
128ea8ab 344
d62a17ae 345 return 0;
128ea8ab 346}
347
348/*
349 * Compare Route Targets.
350 */
d62a17ae 351static int evpn_route_target_cmp(struct ecommunity *ecom1,
352 struct ecommunity *ecom2)
128ea8ab 353{
d62a17ae 354 if (ecom1 && !ecom2)
355 return -1;
128ea8ab 356
d62a17ae 357 if (!ecom1 && ecom2)
358 return 1;
128ea8ab 359
d62a17ae 360 if (!ecom1 && !ecom2)
361 return 0;
128ea8ab 362
d62a17ae 363 if (ecom1->str && !ecom2->str)
364 return -1;
128ea8ab 365
d62a17ae 366 if (!ecom1->str && ecom2->str)
367 return 1;
128ea8ab 368
d62a17ae 369 if (!ecom1->str && !ecom2->str)
370 return 0;
128ea8ab 371
d62a17ae 372 return strcmp(ecom1->str, ecom2->str);
128ea8ab 373}
374
987d8198
DS
375static void evpn_xxport_delete_ecomm(void *val)
376{
377 struct ecommunity *ecomm = val;
378 ecommunity_free(&ecomm);
379}
380
128ea8ab 381/*
382 * Mask off global-admin field of specified extended community (RT),
383 * just retain the local-admin field.
384 */
d62a17ae 385static inline void mask_ecom_global_admin(struct ecommunity_val *dst,
386 struct ecommunity_val *src)
128ea8ab 387{
d7c0a89a 388 uint8_t type;
128ea8ab 389
d62a17ae 390 type = src->val[0];
391 dst->val[0] = 0;
392 if (type == ECOMMUNITY_ENCODE_AS) {
393 dst->val[2] = dst->val[3] = 0;
394 } else if (type == ECOMMUNITY_ENCODE_AS4
395 || type == ECOMMUNITY_ENCODE_IP) {
396 dst->val[2] = dst->val[3] = 0;
397 dst->val[4] = dst->val[5] = 0;
398 }
128ea8ab 399}
400
10ebe1ab
MK
401/*
402 * Map one RT to specified VRF.
403 * bgp_vrf = BGP vrf instance
404 */
996c9314 405static void map_vrf_to_rt(struct bgp *bgp_vrf, struct ecommunity_val *eval)
10ebe1ab
MK
406{
407 struct vrf_irt_node *irt = NULL;
408 struct ecommunity_val eval_tmp;
409
410 /* If using "automatic" RT,
411 * we only care about the local-admin sub-field.
412 * This is to facilitate using L3VNI(VRF-VNI)
413 * as the RT for EBGP peering too.
414 */
415 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
996c9314 416 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD))
10ebe1ab
MK
417 mask_ecom_global_admin(&eval_tmp, eval);
418
419 irt = lookup_vrf_import_rt(&eval_tmp);
e066d6d0
DS
420 if (irt && is_vrf_present_in_irt_vrfs(irt->vrfs, bgp_vrf))
421 /* Already mapped. */
422 return;
10ebe1ab 423
e066d6d0 424 if (!irt)
10ebe1ab 425 irt = vrf_import_rt_new(&eval_tmp);
10ebe1ab
MK
426
427 /* Add VRF to the list for this RT. */
428 listnode_add(irt->vrfs, bgp_vrf);
429}
430
431/*
432 * Unmap specified VRF from specified RT. If there are no other
433 * VRFs for this RT, then the RT hash is deleted.
434 * bgp_vrf: BGP VRF specific instance
435 */
996c9314 436static void unmap_vrf_from_rt(struct bgp *bgp_vrf, struct vrf_irt_node *irt)
10ebe1ab
MK
437{
438 /* Delete VRF from list for this RT. */
439 listnode_delete(irt->vrfs, bgp_vrf);
440 if (!listnode_head(irt->vrfs)) {
10ebe1ab
MK
441 vrf_import_rt_free(irt);
442 }
443}
444
128ea8ab 445/*
446 * Map one RT to specified VNI.
14c1a7bf 447 */
d62a17ae 448static void map_vni_to_rt(struct bgp *bgp, struct bgpevpn *vpn,
449 struct ecommunity_val *eval)
128ea8ab 450{
d62a17ae 451 struct irt_node *irt;
452 struct ecommunity_val eval_tmp;
128ea8ab 453
d62a17ae 454 /* If using "automatic" RT, we only care about the local-admin
455 * sub-field.
456 * This is to facilitate using VNI as the RT for EBGP peering too.
457 */
458 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
459 if (!is_import_rt_configured(vpn))
460 mask_ecom_global_admin(&eval_tmp, eval);
128ea8ab 461
d62a17ae 462 irt = lookup_import_rt(bgp, &eval_tmp);
b1ab0dfe 463 if (irt)
d62a17ae 464 if (is_vni_present_in_irt_vnis(irt->vnis, vpn))
465 /* Already mapped. */
466 return;
128ea8ab 467
d62a17ae 468 if (!irt) {
469 irt = import_rt_new(bgp, &eval_tmp);
470 assert(irt);
471 }
128ea8ab 472
d62a17ae 473 /* Add VNI to the hash list for this RT. */
474 listnode_add(irt->vnis, vpn);
128ea8ab 475}
476
477/*
478 * Unmap specified VNI from specified RT. If there are no other
479 * VNIs for this RT, then the RT hash is deleted.
480 */
d62a17ae 481static void unmap_vni_from_rt(struct bgp *bgp, struct bgpevpn *vpn,
482 struct irt_node *irt)
14c1a7bf 483{
d62a17ae 484 /* Delete VNI from hash list for this RT. */
485 listnode_delete(irt->vnis, vpn);
486 if (!listnode_head(irt->vnis)) {
d62a17ae 487 import_rt_free(bgp, irt);
488 }
14c1a7bf 489}
490
128ea8ab 491/*
492 * Create RT extended community automatically from passed information:
493 * of the form AS:VNI.
494 * NOTE: We use only the lower 16 bits of the AS. This is sufficient as
495 * the need is to get a RT value that will be unique across different
496 * VNIs but the same across routers (in the same AS) for a particular
497 * VNI.
498 */
c581d8b0 499static void form_auto_rt(struct bgp *bgp, vni_t vni, struct list *rtl)
128ea8ab 500{
d62a17ae 501 struct ecommunity_val eval;
502 struct ecommunity *ecomadd;
128ea8ab 503
bf1061d8
VB
504 if (bgp->advertise_autort_rfc8365)
505 vni |= EVPN_AUTORT_VXLAN;
c581d8b0 506 encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
128ea8ab 507
d62a17ae 508 ecomadd = ecommunity_new();
509 ecommunity_add_val(ecomadd, &eval);
510 listnode_add_sort(rtl, ecomadd);
128ea8ab 511}
14c1a7bf 512
513/*
128ea8ab 514 * Derive RD and RT for a VNI automatically. Invoked at the time of
515 * creation of a VNI.
516 */
d62a17ae 517static void derive_rd_rt_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 518{
d62a17ae 519 bgp_evpn_derive_auto_rd(bgp, vpn);
520 bgp_evpn_derive_auto_rt_import(bgp, vpn);
521 bgp_evpn_derive_auto_rt_export(bgp, vpn);
128ea8ab 522}
523
1ec31309 524/*
525 * Convert nexthop (remote VTEP IP) into an IPv6 address.
526 */
527static void evpn_convert_nexthop_to_ipv6(struct attr *attr)
528{
529 if (BGP_ATTR_NEXTHOP_AFI_IP6(attr))
530 return;
531 ipv4_to_ipv4_mapped_ipv6(&attr->mp_nexthop_global, attr->nexthop);
532 attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
533}
534
128ea8ab 535/*
536 * Add (update) or delete MACIP from zebra.
14c1a7bf 537 */
d62a17ae 538static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
539 struct prefix_evpn *p,
540 struct in_addr remote_vtep_ip, int add,
d7c0a89a 541 uint8_t flags)
d62a17ae 542{
543 struct stream *s;
544 int ipa_len;
545 char buf1[ETHER_ADDR_STRLEN];
546 char buf2[INET6_ADDRSTRLEN];
547 char buf3[INET6_ADDRSTRLEN];
548
549 /* Check socket. */
550 if (!zclient || zclient->sock < 0)
551 return 0;
552
553 /* Don't try to register if Zebra doesn't know of this instance. */
554 if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
555 return 0;
556
557 s = zclient->obuf;
558 stream_reset(s);
559
996c9314
LB
560 zclient_create_header(
561 s, add ? ZEBRA_REMOTE_MACIP_ADD : ZEBRA_REMOTE_MACIP_DEL,
562 bgp->vrf_id);
d62a17ae 563 stream_putl(s, vpn->vni);
3714a385 564 stream_put(s, &p->prefix.macip_addr.mac.octet, ETH_ALEN); /* Mac Addr */
d62a17ae 565 /* IP address length and IP address, if any. */
3714a385 566 if (is_evpn_prefix_ipaddr_none(p))
d62a17ae 567 stream_putl(s, 0);
568 else {
3714a385 569 ipa_len = is_evpn_prefix_ipaddr_v4(p) ? IPV4_MAX_BYTELEN
d62a17ae 570 : IPV6_MAX_BYTELEN;
571 stream_putl(s, ipa_len);
3714a385 572 stream_put(s, &p->prefix.macip_addr.ip.ip.addr, ipa_len);
d62a17ae 573 }
574 stream_put_in_addr(s, &remote_vtep_ip);
575
ead40654 576 /* TX flags - MAC sticky status and/or gateway mac */
d62a17ae 577 if (add)
ead40654 578 stream_putc(s, flags);
d62a17ae 579
580 stream_putw_at(s, 0, stream_get_endp(s));
581
582 if (bgp_debug_zebra(NULL))
996c9314
LB
583 zlog_debug(
584 "Tx %s MACIP, VNI %u MAC %s IP %s (flags: 0x%x) remote VTEP %s",
585 add ? "ADD" : "DEL", vpn->vni,
3714a385 586 prefix_mac2str(&p->prefix.macip_addr.mac,
587 buf1, sizeof(buf1)),
588 ipaddr2str(&p->prefix.macip_addr.ip,
589 buf3, sizeof(buf3)), flags,
996c9314
LB
590 inet_ntop(AF_INET, &remote_vtep_ip, buf2,
591 sizeof(buf2)));
d62a17ae 592
593 return zclient_send_message(zclient);
7ef5a232 594}
b18825eb 595
128ea8ab 596/*
597 * Add (update) or delete remote VTEP from zebra.
598 */
d62a17ae 599static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
600 struct prefix_evpn *p, int add)
128ea8ab 601{
d62a17ae 602 struct stream *s;
128ea8ab 603
d62a17ae 604 /* Check socket. */
605 if (!zclient || zclient->sock < 0)
606 return 0;
128ea8ab 607
d62a17ae 608 /* Don't try to register if Zebra doesn't know of this instance. */
609 if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
610 return 0;
128ea8ab 611
d62a17ae 612 s = zclient->obuf;
613 stream_reset(s);
128ea8ab 614
996c9314
LB
615 zclient_create_header(
616 s, add ? ZEBRA_REMOTE_VTEP_ADD : ZEBRA_REMOTE_VTEP_DEL,
617 bgp->vrf_id);
d62a17ae 618 stream_putl(s, vpn->vni);
3714a385 619 if (is_evpn_prefix_ipaddr_v4(p))
620 stream_put_in_addr(s, &p->prefix.imet_addr.ip.ipaddr_v4);
621 else if (is_evpn_prefix_ipaddr_v6(p)) {
d62a17ae 622 zlog_err(
623 "Bad remote IP when trying to %s remote VTEP for VNI %u",
624 add ? "ADD" : "DEL", vpn->vni);
625 return -1;
626 }
128ea8ab 627
d62a17ae 628 stream_putw_at(s, 0, stream_get_endp(s));
128ea8ab 629
d62a17ae 630 if (bgp_debug_zebra(NULL))
631 zlog_debug("Tx %s Remote VTEP, VNI %u remote VTEP %s",
632 add ? "ADD" : "DEL", vpn->vni,
3714a385 633 inet_ntoa(p->prefix.imet_addr.ip.ipaddr_v4));
128ea8ab 634
d62a17ae 635 return zclient_send_message(zclient);
128ea8ab 636}
637
50f74cf1 638/*
639 * Build extended community for EVPN ES (type-4) route
640 */
641static void build_evpn_type4_route_extcomm(struct evpnes *es,
642 struct attr *attr)
643{
644 struct ecommunity ecom_encap;
645 struct ecommunity ecom_es_rt;
646 struct ecommunity_val eval;
647 struct ecommunity_val eval_es_rt;
648 bgp_encap_types tnl_type;
649 struct ethaddr mac;
650
651 /* Encap */
652 tnl_type = BGP_ENCAP_TYPE_VXLAN;
653 memset(&ecom_encap, 0, sizeof(ecom_encap));
654 encode_encap_extcomm(tnl_type, &eval);
655 ecom_encap.size = 1;
656 ecom_encap.val = (uint8_t *)eval.val;
657 attr->ecommunity = ecommunity_dup(&ecom_encap);
658
659 /* ES import RT */
660 memset(&mac, 0, sizeof(struct ethaddr));
661 memset(&ecom_es_rt, 0, sizeof(ecom_es_rt));
662 es_get_system_mac(&es->esi, &mac);
663 encode_es_rt_extcomm(&eval_es_rt, &mac);
664 ecom_es_rt.size = 1;
665 ecom_es_rt.val = (uint8_t *)eval_es_rt.val;
666 attr->ecommunity =
667 ecommunity_merge(attr->ecommunity, &ecom_es_rt);
668
669 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
670}
671
342dd0c6 672/*
673 * Build extended communities for EVPN prefix route.
674 */
675static void build_evpn_type5_route_extcomm(struct bgp *bgp_vrf,
676 struct attr *attr)
677{
678 struct ecommunity ecom_encap;
679 struct ecommunity ecom_rmac;
680 struct ecommunity_val eval;
681 struct ecommunity_val eval_rmac;
682 bgp_encap_types tnl_type;
683 struct listnode *node, *nnode;
684 struct ecommunity *ecom;
685 struct list *vrf_export_rtl = NULL;
686
687 /* Encap */
688 tnl_type = BGP_ENCAP_TYPE_VXLAN;
689 memset(&ecom_encap, 0, sizeof(ecom_encap));
690 encode_encap_extcomm(tnl_type, &eval);
691 ecom_encap.size = 1;
d7c0a89a 692 ecom_encap.val = (uint8_t *)eval.val;
342dd0c6 693
694 /* Add Encap */
695 attr->ecommunity = ecommunity_dup(&ecom_encap);
696
697 /* Add the export RTs for L3VNI/VRF */
698 vrf_export_rtl = bgp_vrf->vrf_export_rtl;
699 if (vrf_export_rtl && !list_isempty(vrf_export_rtl)) {
700 for (ALL_LIST_ELEMENTS(vrf_export_rtl, node, nnode, ecom))
996c9314
LB
701 attr->ecommunity =
702 ecommunity_merge(attr->ecommunity, ecom);
342dd0c6 703 }
704
705 /* add the router mac extended community */
706 if (!is_zero_mac(&attr->rmac)) {
707 memset(&ecom_rmac, 0, sizeof(ecom_rmac));
708 encode_rmac_extcomm(&eval_rmac, &attr->rmac);
709 ecom_rmac.size = 1;
710 ecom_rmac.val = (uint8_t *)eval_rmac.val;
996c9314
LB
711 attr->ecommunity =
712 ecommunity_merge(attr->ecommunity, &ecom_rmac);
342dd0c6 713 }
714
715 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
716}
717
128ea8ab 718/*
1ec31309 719 * Build extended communities for EVPN route.
720 * This function is applicable for type-2 and type-3 routes. The layer-2 RT
721 * and ENCAP extended communities are applicable for all routes.
722 * The default gateway extended community and MAC mobility (sticky) extended
723 * community are added as needed based on passed settings - only for type-2
724 * routes. Likewise, the layer-3 RT and Router MAC extended communities are
725 * added, if present, based on passed settings - only for non-link-local
726 * type-2 routes.
128ea8ab 727 */
7ec156a9 728static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
1ec31309 729 int add_l3_ecomm)
128ea8ab 730{
d62a17ae 731 struct ecommunity ecom_encap;
732 struct ecommunity ecom_sticky;
ead40654 733 struct ecommunity ecom_default_gw;
bc59a672 734 struct ecommunity ecom_rmac;
d62a17ae 735 struct ecommunity_val eval;
736 struct ecommunity_val eval_sticky;
ead40654 737 struct ecommunity_val eval_default_gw;
bc59a672 738 struct ecommunity_val eval_rmac;
d62a17ae 739 bgp_encap_types tnl_type;
740 struct listnode *node, *nnode;
741 struct ecommunity *ecom;
d7c0a89a 742 uint32_t seqnum;
7a3e76f1 743 struct list *vrf_export_rtl = NULL;
128ea8ab 744
d62a17ae 745 /* Encap */
746 tnl_type = BGP_ENCAP_TYPE_VXLAN;
747 memset(&ecom_encap, 0, sizeof(ecom_encap));
748 encode_encap_extcomm(tnl_type, &eval);
749 ecom_encap.size = 1;
d7c0a89a 750 ecom_encap.val = (uint8_t *)eval.val;
128ea8ab 751
d62a17ae 752 /* Add Encap */
753 attr->ecommunity = ecommunity_dup(&ecom_encap);
128ea8ab 754
7a3e76f1 755 /* Add the export RTs for L2VNI */
d62a17ae 756 for (ALL_LIST_ELEMENTS(vpn->export_rtl, node, nnode, ecom))
757 attr->ecommunity = ecommunity_merge(attr->ecommunity, ecom);
128ea8ab 758
1ec31309 759 /* Add the export RTs for L3VNI if told to - caller determines
760 * when this should be done.
523cafc4 761 */
1ec31309 762 if (add_l3_ecomm) {
7ec156a9
MK
763 vrf_export_rtl = bgpevpn_get_vrf_export_rtl(vpn);
764 if (vrf_export_rtl && !list_isempty(vrf_export_rtl)) {
765 for (ALL_LIST_ELEMENTS(vrf_export_rtl, node, nnode,
766 ecom))
996c9314
LB
767 attr->ecommunity = ecommunity_merge(
768 attr->ecommunity, ecom);
7ec156a9 769 }
f1f8b53c 770 }
7a3e76f1 771
1ec31309 772 /* Add MAC mobility (sticky) if needed. */
d62a17ae 773 if (attr->sticky) {
774 seqnum = 0;
775 memset(&ecom_sticky, 0, sizeof(ecom_sticky));
776 encode_mac_mobility_extcomm(1, seqnum, &eval_sticky);
777 ecom_sticky.size = 1;
d7c0a89a 778 ecom_sticky.val = (uint8_t *)eval_sticky.val;
d62a17ae 779 attr->ecommunity =
780 ecommunity_merge(attr->ecommunity, &ecom_sticky);
781 }
c85c03c7 782
1ec31309 783 /* Add RMAC, if told to. */
784 if (add_l3_ecomm) {
bc59a672
MK
785 memset(&ecom_rmac, 0, sizeof(ecom_rmac));
786 encode_rmac_extcomm(&eval_rmac, &attr->rmac);
787 ecom_rmac.size = 1;
788 ecom_rmac.val = (uint8_t *)eval_rmac.val;
996c9314
LB
789 attr->ecommunity =
790 ecommunity_merge(attr->ecommunity, &ecom_rmac);
bc59a672
MK
791 }
792
1ec31309 793 /* Add default gateway, if needed. */
ead40654
MK
794 if (attr->default_gw) {
795 memset(&ecom_default_gw, 0, sizeof(ecom_default_gw));
796 encode_default_gw_extcomm(&eval_default_gw);
797 ecom_default_gw.size = 1;
798 ecom_default_gw.val = (uint8_t *)eval_default_gw.val;
996c9314
LB
799 attr->ecommunity =
800 ecommunity_merge(attr->ecommunity, &ecom_default_gw);
ead40654
MK
801 }
802
d62a17ae 803 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
128ea8ab 804}
805
806/*
807 * Add MAC mobility extended community to attribute.
808 */
d7c0a89a 809static void add_mac_mobility_to_attr(uint32_t seq_num, struct attr *attr)
d62a17ae 810{
811 struct ecommunity ecom_tmp;
812 struct ecommunity_val eval;
d7c0a89a 813 uint8_t *ecom_val_ptr;
d62a17ae 814 int i;
d7c0a89a 815 uint8_t *pnt;
d62a17ae 816 int type = 0;
817 int sub_type = 0;
818
819 /* Build MM */
820 encode_mac_mobility_extcomm(0, seq_num, &eval);
821
822 /* Find current MM ecommunity */
421bb26a 823 ecom_val_ptr = NULL;
d62a17ae 824
825 if (attr->ecommunity) {
826 for (i = 0; i < attr->ecommunity->size; i++) {
827 pnt = attr->ecommunity->val + (i * 8);
828 type = *pnt++;
829 sub_type = *pnt++;
830
831 if (type == ECOMMUNITY_ENCODE_EVPN
832 && sub_type
833 == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY) {
d7c0a89a
QY
834 ecom_val_ptr = (uint8_t *)(attr->ecommunity->val
835 + (i * 8));
d62a17ae 836 break;
837 }
838 }
839 }
840
841 /* Update the existing MM ecommunity */
421bb26a
MK
842 if (ecom_val_ptr) {
843 memcpy(ecom_val_ptr, eval.val, sizeof(char) * ECOMMUNITY_SIZE);
d62a17ae 844 }
845 /* Add MM to existing */
846 else {
847 memset(&ecom_tmp, 0, sizeof(ecom_tmp));
848 ecom_tmp.size = 1;
d7c0a89a 849 ecom_tmp.val = (uint8_t *)eval.val;
d62a17ae 850
f9a78910
DS
851 if (attr->ecommunity)
852 attr->ecommunity =
853 ecommunity_merge(attr->ecommunity, &ecom_tmp);
854 else
855 attr->ecommunity = ecommunity_dup(&ecom_tmp);
d62a17ae 856 }
128ea8ab 857}
858
859/* Install EVPN route into zebra. */
d62a17ae 860static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn,
861 struct prefix_evpn *p,
d7c0a89a 862 struct in_addr remote_vtep_ip, uint8_t flags)
128ea8ab 863{
d62a17ae 864 int ret;
128ea8ab 865
d62a17ae 866 if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
867 ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip,
ead40654 868 1, flags);
d62a17ae 869 else
870 ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 1);
128ea8ab 871
d62a17ae 872 return ret;
128ea8ab 873}
874
875/* Uninstall EVPN route from zebra. */
d62a17ae 876static int evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn,
877 struct prefix_evpn *p,
878 struct in_addr remote_vtep_ip)
128ea8ab 879{
d62a17ae 880 int ret;
128ea8ab 881
d62a17ae 882 if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
883 ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip,
884 0, 0);
885 else
886 ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 0);
128ea8ab 887
d62a17ae 888 return ret;
128ea8ab 889}
890
891/*
892 * Due to MAC mobility, the prior "local" best route has been supplanted
893 * by a "remote" best route. The prior route has to be deleted and withdrawn
894 * from peers.
895 */
d62a17ae 896static void evpn_delete_old_local_route(struct bgp *bgp, struct bgpevpn *vpn,
897 struct bgp_node *rn,
898 struct bgp_info *old_local)
128ea8ab 899{
d62a17ae 900 struct bgp_node *global_rn;
901 struct bgp_info *ri;
902 afi_t afi = AFI_L2VPN;
903 safi_t safi = SAFI_EVPN;
128ea8ab 904
d62a17ae 905 /* Locate route node in the global EVPN routing table. Note that
906 * this table is a 2-level tree (RD-level + Prefix-level) similar to
907 * L3VPN routes.
908 */
909 global_rn = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi,
910 (struct prefix *)&rn->p, &vpn->prd);
911 if (global_rn) {
912 /* Delete route entry in the global EVPN table. */
50f74cf1 913 delete_evpn_route_entry(bgp, afi, safi, global_rn, &ri);
128ea8ab 914
d62a17ae 915 /* Schedule for processing - withdraws to peers happen from
916 * this table.
917 */
918 if (ri)
919 bgp_process(bgp, global_rn, afi, safi);
920 bgp_unlock_node(global_rn);
921 }
128ea8ab 922
d62a17ae 923 /* Delete route entry in the VNI route table, caller to remove. */
924 bgp_info_delete(rn, old_local);
128ea8ab 925}
926
50f74cf1 927static struct in_addr *es_vtep_new(struct in_addr vtep)
928{
929 struct in_addr *ip;
930
931 ip = XCALLOC(MTYPE_BGP_EVPN_ES_VTEP, sizeof(struct in_addr));
932 if (!ip)
933 return NULL;
934
935 ip->s_addr = vtep.s_addr;
936 return ip;
937}
938
939static void es_vtep_free(struct in_addr *ip)
940{
941 XFREE(MTYPE_BGP_EVPN_ES_VTEP, ip);
942}
943
944/* check if VTEP is already part of the list */
945static int is_vtep_present_in_list(struct list *list,
946 struct in_addr vtep)
947{
948 struct listnode *node = NULL;
949 struct in_addr *tmp;
950
951 for (ALL_LIST_ELEMENTS_RO(list, node, tmp)) {
952 if (tmp->s_addr == vtep.s_addr)
953 return 1;
954 }
955 return 0;
956}
957
2bb9eff4
DS
958/*
959 * Best path for ES route was changed,
960 * update the list of VTEPs for this ES
961 */
50f74cf1 962static int evpn_es_install_vtep(struct bgp *bgp,
963 struct evpnes *es,
964 struct prefix_evpn *p,
965 struct in_addr rvtep)
966{
967 struct in_addr *vtep_ip;
968
969 if (is_vtep_present_in_list(es->vtep_list, rvtep))
970 return 0;
971
972
973 vtep_ip = es_vtep_new(rvtep);
974 if (vtep_ip)
975 listnode_add_sort(es->vtep_list, vtep_ip);
976 return 0;
977}
978
2bb9eff4
DS
979/*
980 * Best path for ES route was changed,
981 * update the list of VTEPs for this ES
982 */
50f74cf1 983static int evpn_es_uninstall_vtep(struct bgp *bgp,
984 struct evpnes *es,
985 struct prefix_evpn *p,
986 struct in_addr rvtep)
987{
988 struct listnode *node, *nnode, *node_to_del = NULL;
989 struct in_addr *tmp;
990
991 for (ALL_LIST_ELEMENTS(es->vtep_list, node, nnode, tmp)) {
992 if (tmp->s_addr == rvtep.s_addr) {
993 es_vtep_free(tmp);
994 node_to_del = node;
995 }
996 }
997
998 if (node_to_del)
999 list_delete_node(es->vtep_list, node_to_del);
1000
1001 return 0;
1002}
1003
1004/*
1005 * Calculate the best path for a ES(type-4) route.
1006 */
1007static int evpn_es_route_select_install(struct bgp *bgp,
1008 struct evpnes *es,
1009 struct bgp_node *rn)
1010{
1011 int ret = 0;
1012 afi_t afi = AFI_L2VPN;
1013 safi_t safi = SAFI_EVPN;
1014 struct bgp_info *old_select; /* old best */
1015 struct bgp_info *new_select; /* new best */
1016 struct bgp_info_pair old_and_new;
1017
1018 /* Compute the best path. */
1019 bgp_best_selection(bgp, rn, &bgp->maxpaths[afi][safi],
1020 &old_and_new, afi, safi);
1021 old_select = old_and_new.old;
1022 new_select = old_and_new.new;
1023
2bb9eff4
DS
1024 /*
1025 * If the best path hasn't changed - see if something needs to be
50f74cf1 1026 * updated
1027 */
1028 if (old_select && old_select == new_select
1029 && old_select->type == ZEBRA_ROUTE_BGP
1030 && old_select->sub_type == BGP_ROUTE_IMPORTED
1031 && !CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR)
1032 && !CHECK_FLAG(old_select->flags, BGP_INFO_ATTR_CHANGED)
1033 && !bgp->addpath_tx_used[afi][safi]) {
1034 if (bgp_zebra_has_route_changed(rn, old_select)) {
1035 ret = evpn_es_install_vtep(bgp, es,
1036 (struct prefix_evpn *)&rn->p,
1037 old_select->attr->nexthop);
1038 }
1039 UNSET_FLAG(old_select->flags, BGP_INFO_MULTIPATH_CHG);
1040 bgp_zebra_clear_route_change_flags(rn);
1041 return ret;
1042 }
1043
1044 /* If the user did a "clear" this flag will be set */
1045 UNSET_FLAG(rn->flags, BGP_NODE_USER_CLEAR);
1046
2bb9eff4
DS
1047 /*
1048 * bestpath has changed; update relevant fields and install or uninstall
50f74cf1 1049 * into the zebra RIB.
1050 */
1051 if (old_select || new_select)
1052 bgp_bump_version(rn);
1053
1054 if (old_select)
1055 bgp_info_unset_flag(rn, old_select, BGP_INFO_SELECTED);
1056 if (new_select) {
1057 bgp_info_set_flag(rn, new_select, BGP_INFO_SELECTED);
1058 bgp_info_unset_flag(rn, new_select, BGP_INFO_ATTR_CHANGED);
1059 UNSET_FLAG(new_select->flags, BGP_INFO_MULTIPATH_CHG);
1060 }
1061
1062 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
1063 && new_select->sub_type == BGP_ROUTE_IMPORTED) {
1064 ret = evpn_es_install_vtep(bgp, es,
1065 (struct prefix_evpn *)&rn->p,
1066 new_select->attr->nexthop);
1067 } else {
1068 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
1069 && old_select->sub_type == BGP_ROUTE_IMPORTED)
2bb9eff4
DS
1070 ret = evpn_es_uninstall_vtep(
1071 bgp, es, (struct prefix_evpn *)&rn->p,
1072 old_select->attr->nexthop);
50f74cf1 1073 }
1074
1075 /* Clear any route change flags. */
1076 bgp_zebra_clear_route_change_flags(rn);
1077
1078 /* Reap old select bgp_info, if it has been removed */
1079 if (old_select && CHECK_FLAG(old_select->flags, BGP_INFO_REMOVED))
1080 bgp_info_reap(rn, old_select);
1081
1082 return ret;
1083}
1084
128ea8ab 1085/*
1086 * Calculate the best path for an EVPN route. Install/update best path in zebra,
1087 * if appropriate.
1088 */
d62a17ae 1089static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
1090 struct bgp_node *rn)
1091{
1092 struct bgp_info *old_select, *new_select;
1093 struct bgp_info_pair old_and_new;
1094 afi_t afi = AFI_L2VPN;
1095 safi_t safi = SAFI_EVPN;
1096 int ret = 0;
d7c0a89a 1097 uint8_t flags = 0;
d62a17ae 1098
1099 /* Compute the best path. */
1100 bgp_best_selection(bgp, rn, &bgp->maxpaths[afi][safi], &old_and_new,
1101 afi, safi);
1102 old_select = old_and_new.old;
1103 new_select = old_and_new.new;
1104
1105 /* If the best path hasn't changed - see if there is still something to
1106 * update
1107 * to zebra RIB.
1108 */
1109 if (old_select && old_select == new_select
1110 && old_select->type == ZEBRA_ROUTE_BGP
90f4f482 1111 && old_select->sub_type == BGP_ROUTE_IMPORTED
d62a17ae 1112 && !CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR)
1113 && !CHECK_FLAG(old_select->flags, BGP_INFO_ATTR_CHANGED)
1114 && !bgp->addpath_tx_used[afi][safi]) {
ead40654
MK
1115 if (bgp_zebra_has_route_changed(rn, old_select)) {
1116 if (old_select->attr->sticky)
1117 SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
1118 if (old_select->attr->default_gw)
1119 SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
996c9314
LB
1120 ret = evpn_zebra_install(
1121 bgp, vpn, (struct prefix_evpn *)&rn->p,
1122 old_select->attr->nexthop, flags);
ead40654 1123 }
d62a17ae 1124 UNSET_FLAG(old_select->flags, BGP_INFO_MULTIPATH_CHG);
1125 bgp_zebra_clear_route_change_flags(rn);
1126 return ret;
1127 }
1128
1129 /* If the user did a "clear" this flag will be set */
1130 UNSET_FLAG(rn->flags, BGP_NODE_USER_CLEAR);
1131
1132 /* bestpath has changed; update relevant fields and install or uninstall
1133 * into the zebra RIB.
1134 */
1135 if (old_select || new_select)
1136 bgp_bump_version(rn);
1137
1138 if (old_select)
1139 bgp_info_unset_flag(rn, old_select, BGP_INFO_SELECTED);
1140 if (new_select) {
1141 bgp_info_set_flag(rn, new_select, BGP_INFO_SELECTED);
1142 bgp_info_unset_flag(rn, new_select, BGP_INFO_ATTR_CHANGED);
1143 UNSET_FLAG(new_select->flags, BGP_INFO_MULTIPATH_CHG);
1144 }
1145
1146 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
90f4f482 1147 && new_select->sub_type == BGP_ROUTE_IMPORTED) {
ead40654
MK
1148 flags = 0;
1149 if (new_select->attr->sticky)
1150 SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
1151 if (new_select->attr->default_gw)
1152 SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
d62a17ae 1153 ret = evpn_zebra_install(bgp, vpn, (struct prefix_evpn *)&rn->p,
996c9314 1154 new_select->attr->nexthop, flags);
d62a17ae 1155 /* If an old best existed and it was a "local" route, the only
1156 * reason
1157 * it would be supplanted is due to MAC mobility procedures. So,
1158 * we
1159 * need to do an implicit delete and withdraw that route from
1160 * peers.
1161 */
1162 if (old_select && old_select->peer == bgp->peer_self
1163 && old_select->type == ZEBRA_ROUTE_BGP
1164 && old_select->sub_type == BGP_ROUTE_STATIC)
1165 evpn_delete_old_local_route(bgp, vpn, rn, old_select);
1166 } else {
1167 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
90f4f482 1168 && old_select->sub_type == BGP_ROUTE_IMPORTED)
d62a17ae 1169 ret = evpn_zebra_uninstall(bgp, vpn,
1170 (struct prefix_evpn *)&rn->p,
1171 old_select->attr->nexthop);
1172 }
1173
1174 /* Clear any route change flags. */
1175 bgp_zebra_clear_route_change_flags(rn);
1176
1177 /* Reap old select bgp_info, if it has been removed */
1178 if (old_select && CHECK_FLAG(old_select->flags, BGP_INFO_REMOVED))
1179 bgp_info_reap(rn, old_select);
1180
1181 return ret;
128ea8ab 1182}
1183
ead40654
MK
1184/*
1185 * Return true if the local ri for this rn is of type gateway mac
1186 */
1187static int evpn_route_is_def_gw(struct bgp *bgp, struct bgp_node *rn)
1188{
996c9314
LB
1189 struct bgp_info *tmp_ri = NULL;
1190 struct bgp_info *local_ri = NULL;
ead40654
MK
1191
1192 local_ri = NULL;
1193 for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) {
1194 if (tmp_ri->peer == bgp->peer_self
1195 && tmp_ri->type == ZEBRA_ROUTE_BGP
1196 && tmp_ri->sub_type == BGP_ROUTE_STATIC)
1197 local_ri = tmp_ri;
1198 }
1199
1200 if (!local_ri)
1201 return 0;
1202
1203 return local_ri->attr->default_gw;
1204}
1205
c85c03c7 1206
1207/*
1208 * Return true if the local ri for this rn has sticky set
1209 */
d62a17ae 1210static int evpn_route_is_sticky(struct bgp *bgp, struct bgp_node *rn)
c85c03c7 1211{
d62a17ae 1212 struct bgp_info *tmp_ri;
1213 struct bgp_info *local_ri;
c85c03c7 1214
d62a17ae 1215 local_ri = NULL;
1216 for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) {
1217 if (tmp_ri->peer == bgp->peer_self
1218 && tmp_ri->type == ZEBRA_ROUTE_BGP
1219 && tmp_ri->sub_type == BGP_ROUTE_STATIC)
1220 local_ri = tmp_ri;
1221 }
c85c03c7 1222
d62a17ae 1223 if (!local_ri)
1224 return 0;
c85c03c7 1225
d62a17ae 1226 return local_ri->attr->sticky;
c85c03c7 1227}
1228
50f74cf1 1229/*
1230 * create or update EVPN type4 route entry.
1231 * This could be in the ES table or the global table.
1232 * TODO: handle remote ES (type4) routes as well
1233 */
1234static int update_evpn_type4_route_entry(struct bgp *bgp,
1235 struct evpnes *es,
1236 afi_t afi, safi_t safi,
1237 struct bgp_node *rn,
1238 struct attr *attr,
1239 int add,
1240 struct bgp_info **ri,
1241 int *route_changed)
1242{
1243 char buf[ESI_STR_LEN];
1244 char buf1[INET6_ADDRSTRLEN];
1245 struct bgp_info *tmp_ri = NULL;
1246 struct bgp_info *local_ri = NULL; /* local route entry if any */
1247 struct bgp_info *remote_ri = NULL; /* remote route entry if any */
1248 struct attr *attr_new = NULL;
1249 struct prefix_evpn *evp = NULL;
1250
1251 *ri = NULL;
1252 *route_changed = 1;
1253 evp = (struct prefix_evpn *)&rn->p;
1254
1255 /* locate the local and remote entries if any */
1256 for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) {
1257 if (tmp_ri->peer == bgp->peer_self &&
1258 tmp_ri->type == ZEBRA_ROUTE_BGP &&
1259 tmp_ri->sub_type == BGP_ROUTE_STATIC)
1260 local_ri = tmp_ri;
1261 if (tmp_ri->type == ZEBRA_ROUTE_BGP &&
1262 tmp_ri->sub_type == BGP_ROUTE_IMPORTED &&
1263 CHECK_FLAG(tmp_ri->flags, BGP_INFO_VALID))
1264 remote_ri = tmp_ri;
1265 }
1266
1267 /* we don't expect to see a remote_ri at this point.
1268 * An ES route has esi + vtep_ip as the key,
1269 * We shouldn't see the same route from any other vtep.
1270 */
1271 if (remote_ri) {
1272 zlog_err(
1273 "%u ERROR: local es route for ESI: %s Vtep %s also learnt from remote",
1274 bgp->vrf_id,
1275 esi_to_str(&evp->prefix.es_addr.esi, buf, sizeof(buf)),
1276 ipaddr2str(&es->originator_ip, buf1, sizeof(buf1)));
1277 return -1;
1278 }
1279
1280 if (!local_ri && !add)
1281 return 0;
1282
1283 /* create or update the entry */
1284 if (!local_ri) {
1285
1286 /* Add or update attribute to hash */
1287 attr_new = bgp_attr_intern(attr);
1288
1289 /* Create new route with its attribute. */
1290 tmp_ri = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC,
1291 0, bgp->peer_self, attr_new, rn);
1292 SET_FLAG(tmp_ri->flags, BGP_INFO_VALID);
1293
1294 /* add the newly created path to the route-node */
1295 bgp_info_add(rn, tmp_ri);
1296 } else {
1297 tmp_ri = local_ri;
1298 if (attrhash_cmp(tmp_ri->attr, attr)
1299 && !CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED))
1300 *route_changed = 0;
1301 else {
1302 /* The attribute has changed.
1303 * Add (or update) attribute to hash. */
1304 attr_new = bgp_attr_intern(attr);
1305 bgp_info_set_flag(rn, tmp_ri, BGP_INFO_ATTR_CHANGED);
1306
1307 /* Restore route, if needed. */
1308 if (CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED))
1309 bgp_info_restore(rn, tmp_ri);
1310
1311 /* Unintern existing, set to new. */
1312 bgp_attr_unintern(&tmp_ri->attr);
1313 tmp_ri->attr = attr_new;
1314 tmp_ri->uptime = bgp_clock();
1315 }
1316 }
1317
1318 /* Return back the route entry. */
1319 *ri = tmp_ri;
1320 return 0;
1321}
1322
1323/* update evpn es (type-4) route */
1324static int update_evpn_type4_route(struct bgp *bgp,
1325 struct evpnes *es,
1326 struct prefix_evpn *p)
1327{
1328 int ret = 0;
1329 int route_changed = 0;
1330 char buf[ESI_STR_LEN];
1331 char buf1[INET6_ADDRSTRLEN];
1332 afi_t afi = AFI_L2VPN;
1333 safi_t safi = SAFI_EVPN;
1334 struct attr attr;
1335 struct attr *attr_new = NULL;
1336 struct bgp_node *rn = NULL;
1337 struct bgp_info *ri = NULL;
1338
1339 memset(&attr, 0, sizeof(struct attr));
1340
1341 /* Build path-attribute for this route. */
1342 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
1343 attr.nexthop = es->originator_ip.ipaddr_v4;
1344 attr.mp_nexthop_global_in = es->originator_ip.ipaddr_v4;
1345 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
1346
1347 /* Set up extended community. */
1348 build_evpn_type4_route_extcomm(es, &attr);
1349
1350 /* First, create (or fetch) route node within the ESI. */
1351 /* NOTE: There is no RD here. */
1352 rn = bgp_node_get(es->route_table, (struct prefix *)p);
1353
1354 /* Create or update route entry. */
1355 ret = update_evpn_type4_route_entry(bgp, es, afi, safi, rn,
1356 &attr, 1, &ri,
1357 &route_changed);
1358 if (ret != 0) {
1359 zlog_err("%u ERROR: Failed to updated ES route ESI: %s VTEP %s",
1360 bgp->vrf_id,
1361 esi_to_str(&p->prefix.es_addr.esi, buf, sizeof(buf)),
1362 ipaddr2str(&es->originator_ip, buf1, sizeof(buf1)));
1363 }
1364
1365 assert(ri);
1366 attr_new = ri->attr;
1367
1368 /* Perform route selection;
1369 * this is just to set the flags correctly
1370 * as local route in the ES always wins.
1371 */
1372 evpn_es_route_select_install(bgp, es, rn);
1373 bgp_unlock_node(rn);
1374
1375 /* If this is a new route or some attribute has changed, export the
1376 * route to the global table. The route will be advertised to peers
1377 * from there. Note that this table is a 2-level tree (RD-level +
1378 * Prefix-level) similar to L3VPN routes.
1379 */
1380 if (route_changed) {
1381 struct bgp_info *global_ri;
1382
1383 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
1384 (struct prefix *)p, &es->prd);
1385 update_evpn_type4_route_entry(bgp, es, afi, safi,
1386 rn, attr_new,
1387 1, &global_ri,
1388 &route_changed);
1389
1390 /* Schedule for processing and unlock node. */
1391 bgp_process(bgp, rn, afi, safi);
1392 bgp_unlock_node(rn);
1393 }
1394
1395 /* Unintern temporary. */
1396 aspath_unintern(&attr.aspath);
1397 return 0;
1398}
1399
342dd0c6 1400static int update_evpn_type5_route_entry(struct bgp *bgp_def,
1401 struct bgp *bgp_vrf, afi_t afi,
1402 safi_t safi, struct bgp_node *rn,
5424b7ba 1403 struct attr *attr, int *route_changed)
342dd0c6 1404{
1405 struct attr *attr_new = NULL;
1406 struct bgp_info *ri = NULL;
1407 mpls_label_t label = MPLS_INVALID_LABEL;
1408 struct bgp_info *local_ri = NULL;
1409 struct bgp_info *tmp_ri = NULL;
1410
5424b7ba 1411 *route_changed = 0;
342dd0c6 1412 /* locate the local route entry if any */
1413 for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) {
1414 if (tmp_ri->peer == bgp_def->peer_self
1415 && tmp_ri->type == ZEBRA_ROUTE_BGP
1416 && tmp_ri->sub_type == BGP_ROUTE_STATIC)
1417 local_ri = tmp_ri;
1418 }
1419
2bb9eff4
DS
1420 /*
1421 * create a new route entry if one doesnt exist.
1422 * Otherwise see if route attr has changed
523cafc4 1423 */
342dd0c6 1424 if (!local_ri) {
1425
5424b7ba
MK
1426 /* route has changed as this is the first entry */
1427 *route_changed = 1;
1428
342dd0c6 1429 /* Add (or update) attribute to hash. */
1430 attr_new = bgp_attr_intern(attr);
1431
1432 /* create the route info from attribute */
1433 ri = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0,
1434 bgp_def->peer_self, attr_new, rn);
1435 SET_FLAG(ri->flags, BGP_INFO_VALID);
1436
b57ba6d2 1437 /* Type-5 routes advertise the L3-VNI */
342dd0c6 1438 bgp_info_extra_get(ri);
1439 vni2label(bgp_vrf->l3vni, &label);
b57ba6d2
MK
1440 memcpy(&ri->extra->label, &label, sizeof(label));
1441 ri->extra->num_labels = 1;
342dd0c6 1442
1443 /* add the route entry to route node*/
1444 bgp_info_add(rn, ri);
1445 } else {
1446
1447 tmp_ri = local_ri;
1448 if (!attrhash_cmp(tmp_ri->attr, attr)) {
5424b7ba
MK
1449
1450 /* attribute changed */
1451 *route_changed = 1;
1452
342dd0c6 1453 /* The attribute has changed. */
1454 /* Add (or update) attribute to hash. */
1455 attr_new = bgp_attr_intern(attr);
1456 bgp_info_set_flag(rn, tmp_ri, BGP_INFO_ATTR_CHANGED);
1457
1458 /* Restore route, if needed. */
1459 if (CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED))
1460 bgp_info_restore(rn, tmp_ri);
1461
1462 /* Unintern existing, set to new. */
1463 bgp_attr_unintern(&tmp_ri->attr);
1464 tmp_ri->attr = attr_new;
1465 tmp_ri->uptime = bgp_clock();
1466 }
1467 }
1468 return 0;
1469}
1470
1471/* update evpn type-5 route entry */
996c9314
LB
1472static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp,
1473 struct attr *src_attr)
342dd0c6 1474{
1475 afi_t afi = AFI_L2VPN;
1476 safi_t safi = SAFI_EVPN;
1477 struct attr attr;
1478 struct bgp_node *rn = NULL;
1479 struct bgp *bgp_def = NULL;
5424b7ba 1480 int route_changed = 0;
342dd0c6 1481
1482 bgp_def = bgp_get_default();
1483 if (!bgp_def)
faafdfa8 1484 return 0;
342dd0c6 1485
2f69f6d3 1486 /* Build path attribute for this route - use the source attr, if
1487 * present, else treat as locally originated.
1488 */
1489 if (src_attr)
1490 bgp_attr_dup(&attr, src_attr);
1491 else {
1492 memset(&attr, 0, sizeof(struct attr));
1493 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
1494 }
1495 /* Set nexthop to ourselves and fill in the Router MAC. */
342dd0c6 1496 attr.nexthop = bgp_vrf->originator_ip;
1497 attr.mp_nexthop_global_in = bgp_vrf->originator_ip;
1498 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
1499 memcpy(&attr.rmac, &bgp_vrf->rmac, sizeof(struct ethaddr));
1500
1501 /* Setup RT and encap extended community */
1502 build_evpn_type5_route_extcomm(bgp_vrf, &attr);
1503
1504 /* get the route node in global table */
1505 rn = bgp_afi_node_get(bgp_def->rib[afi][safi], afi, safi,
996c9314 1506 (struct prefix *)evp, &bgp_vrf->vrf_prd);
342dd0c6 1507 assert(rn);
1508
1509 /* create or update the route entry within the route node */
996c9314
LB
1510 update_evpn_type5_route_entry(bgp_def, bgp_vrf, afi, safi, rn, &attr,
1511 &route_changed);
342dd0c6 1512
1513 /* schedule for processing and unlock node */
5424b7ba
MK
1514 if (route_changed) {
1515 bgp_process(bgp_def, rn, afi, safi);
1516 bgp_unlock_node(rn);
1517 }
342dd0c6 1518
1519 /* uninten temporary */
5ee65f6f 1520 if (!src_attr)
1521 aspath_unintern(&attr.aspath);
342dd0c6 1522 return 0;
1523}
1524
128ea8ab 1525/*
1526 * Create or update EVPN route entry. This could be in the VNI route table
1527 * or the global route table.
1528 */
d62a17ae 1529static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
1530 afi_t afi, safi_t safi, struct bgp_node *rn,
1531 struct attr *attr, int add, int vni_table,
d7c0a89a 1532 struct bgp_info **ri, uint8_t flags)
d62a17ae 1533{
1534 struct bgp_info *tmp_ri;
1535 struct bgp_info *local_ri, *remote_ri;
1536 struct attr *attr_new;
b57ba6d2 1537 mpls_label_t label[BGP_MAX_LABELS];
d7c0a89a 1538 uint32_t num_labels = 1;
d62a17ae 1539 int route_change = 1;
d7c0a89a 1540 uint8_t sticky = 0;
b57ba6d2 1541 struct prefix_evpn *evp;
d62a17ae 1542
1543 *ri = NULL;
b57ba6d2
MK
1544 evp = (struct prefix_evpn *)&rn->p;
1545 memset(&label, 0, sizeof(label));
d62a17ae 1546
1547 /* See if this is an update of an existing route, or a new add. Also,
1548 * identify if already known from remote, and if so, the one with the
1549 * highest sequence number; this is only when adding to the VNI routing
1550 * table.
1551 */
1552 local_ri = remote_ri = NULL;
1553 for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) {
1554 if (tmp_ri->peer == bgp->peer_self
1555 && tmp_ri->type == ZEBRA_ROUTE_BGP
1556 && tmp_ri->sub_type == BGP_ROUTE_STATIC)
1557 local_ri = tmp_ri;
1558 if (vni_table) {
1559 if (tmp_ri->type == ZEBRA_ROUTE_BGP
90f4f482 1560 && tmp_ri->sub_type == BGP_ROUTE_IMPORTED
d62a17ae 1561 && CHECK_FLAG(tmp_ri->flags, BGP_INFO_VALID)) {
1562 if (!remote_ri)
1563 remote_ri = tmp_ri;
1564 else if (mac_mobility_seqnum(tmp_ri->attr)
1565 > mac_mobility_seqnum(remote_ri->attr))
1566 remote_ri = tmp_ri;
1567 }
1568 }
1569 }
1570
1571 /* If route doesn't exist already, create a new one, if told to.
1572 * Otherwise act based on whether the attributes of the route have
1573 * changed or not.
1574 */
1575 if (!local_ri && !add)
1576 return 0;
1577
1578 if (!local_ri) {
1579 /* When learnt locally for the first time but already known from
1580 * remote, we have to initiate appropriate MAC mobility steps.
50f74cf1 1581 * This is applicable when updating the VNI routing table.
1a98c087
MK
1582 * We need to skip mobility steps for g/w macs (local mac on g/w
1583 * SVI) advertised in EVPN.
1584 * This will ensure that local routes are preferred for g/w macs
d62a17ae 1585 */
ead40654 1586 if (remote_ri && !CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) {
d7c0a89a 1587 uint32_t cur_seqnum;
d62a17ae 1588
1589 /* Add MM extended community to route. */
1590 cur_seqnum = mac_mobility_seqnum(remote_ri->attr);
1591 add_mac_mobility_to_attr(cur_seqnum + 1, attr);
1592 }
1593
1594 /* Add (or update) attribute to hash. */
1595 attr_new = bgp_attr_intern(attr);
1596
1597 /* Extract MAC mobility sequence number, if any. */
1598 attr_new->mm_seqnum =
1599 bgp_attr_mac_mobility_seqnum(attr_new, &sticky);
1600 attr_new->sticky = sticky;
1601
1602 /* Create new route with its attribute. */
1603 tmp_ri = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0,
1604 bgp->peer_self, attr_new, rn);
1605 SET_FLAG(tmp_ri->flags, BGP_INFO_VALID);
1606 bgp_info_extra_get(tmp_ri);
1607
1608 /* The VNI goes into the 'label' field of the route */
b57ba6d2 1609 vni2label(vpn->vni, &label[0]);
c48d9f5f
MK
1610
1611 /* Type-2 routes may carry a second VNI - the L3-VNI.
1612 * Only attach second label if we are advertising two labels for
1613 * type-2 routes.
1614 */
996c9314
LB
1615 if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
1616 && CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) {
b57ba6d2
MK
1617 vni_t l3vni;
1618
1619 l3vni = bgpevpn_get_l3vni(vpn);
1620 if (l3vni) {
1621 vni2label(l3vni, &label[1]);
1622 num_labels++;
1623 }
1624 }
d62a17ae 1625
b57ba6d2
MK
1626 memcpy(&tmp_ri->extra->label, label, sizeof(label));
1627 tmp_ri->extra->num_labels = num_labels;
d62a17ae 1628 bgp_info_add(rn, tmp_ri);
1629 } else {
1630 tmp_ri = local_ri;
1631 if (attrhash_cmp(tmp_ri->attr, attr)
1632 && !CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED))
1633 route_change = 0;
1634 else {
c48d9f5f
MK
1635 /*
1636 * The attributes have changed, type-2 routes needs to
1637 * be advertised with right labels.
1638 */
1639 vni2label(vpn->vni, &label[0]);
996c9314
LB
1640 if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
1641 && CHECK_FLAG(vpn->flags,
1642 VNI_FLAG_USE_TWO_LABELS)) {
c48d9f5f
MK
1643 vni_t l3vni;
1644
1645 l3vni = bgpevpn_get_l3vni(vpn);
1646 if (l3vni) {
1647 vni2label(l3vni, &label[1]);
1648 num_labels++;
1649 }
1650 }
1651 memcpy(&tmp_ri->extra->label, label, sizeof(label));
1652 tmp_ri->extra->num_labels = num_labels;
1653
d62a17ae 1654 /* The attribute has changed. */
1655 /* Add (or update) attribute to hash. */
1656 attr_new = bgp_attr_intern(attr);
1657 bgp_info_set_flag(rn, tmp_ri, BGP_INFO_ATTR_CHANGED);
1658
1659 /* Restore route, if needed. */
1660 if (CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED))
1661 bgp_info_restore(rn, tmp_ri);
1662
1663 /* Unintern existing, set to new. */
1664 bgp_attr_unintern(&tmp_ri->attr);
1665 tmp_ri->attr = attr_new;
1666 tmp_ri->uptime = bgp_clock();
1667 }
1668 }
1669
1670 /* Return back the route entry. */
1671 *ri = tmp_ri;
1672 return route_change;
128ea8ab 1673}
1674
1675/*
1676 * Create or update EVPN route (of type based on prefix) for specified VNI
1677 * and schedule for processing.
1678 */
d62a17ae 1679static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
d7c0a89a 1680 struct prefix_evpn *p, uint8_t flags)
128ea8ab 1681{
d62a17ae 1682 struct bgp_node *rn;
1683 struct attr attr;
1684 struct attr *attr_new;
1ec31309 1685 int add_l3_ecomm = 0;
d62a17ae 1686 struct bgp_info *ri;
1687 afi_t afi = AFI_L2VPN;
1688 safi_t safi = SAFI_EVPN;
1689 int route_change;
128ea8ab 1690
d62a17ae 1691 memset(&attr, 0, sizeof(struct attr));
128ea8ab 1692
d62a17ae 1693 /* Build path-attribute for this route. */
1694 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
1695 attr.nexthop = vpn->originator_ip;
1696 attr.mp_nexthop_global_in = vpn->originator_ip;
1697 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
317f1fe0 1698 attr.sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY) ? 1 : 0;
ead40654 1699 attr.default_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW) ? 1 : 0;
be41eb68
MK
1700
1701 /* PMSI is only needed for type-3 routes */
1702 if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE)
1703 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL);
1704
1ec31309 1705 /* router mac is only needed for type-2 routes here. */
be41eb68
MK
1706 if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
1707 bgpevpn_get_rmac(vpn, &attr.rmac);
a21bd7a3 1708 vni2label(vpn->vni, &(attr.label));
128ea8ab 1709
1ec31309 1710 /* Include L3 VNI related RTs and RMAC for type-2 routes, if they're
1711 * IPv4 or IPv6 global addresses and we're advertising L3VNI with
1712 * these routes.
1713 */
1714 if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE &&
3714a385 1715 (is_evpn_prefix_ipaddr_v4(p) ||
1716 !IN6_IS_ADDR_LINKLOCAL(&p->prefix.macip_addr.ip.ipaddr_v6)) &&
1ec31309 1717 CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS))
1718 add_l3_ecomm = 1;
1719
1720 /* Set up extended community. */
1721 build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm);
128ea8ab 1722
d62a17ae 1723 /* First, create (or fetch) route node within the VNI. */
1724 /* NOTE: There is no RD here. */
1725 rn = bgp_node_get(vpn->route_table, (struct prefix *)p);
128ea8ab 1726
d62a17ae 1727 /* Create or update route entry. */
1728 route_change = update_evpn_route_entry(bgp, vpn, afi, safi, rn, &attr,
1a98c087 1729 1, 1, &ri, flags);
d62a17ae 1730 assert(ri);
1731 attr_new = ri->attr;
128ea8ab 1732
d62a17ae 1733 /* Perform route selection; this is just to set the flags correctly
1734 * as local route in the VNI always wins.
1735 */
1736 evpn_route_select_install(bgp, vpn, rn);
1737 bgp_unlock_node(rn);
128ea8ab 1738
d62a17ae 1739 /* If this is a new route or some attribute has changed, export the
1740 * route to the global table. The route will be advertised to peers
1741 * from there. Note that this table is a 2-level tree (RD-level +
1742 * Prefix-level) similar to L3VPN routes.
1743 */
1744 if (route_change) {
1745 struct bgp_info *global_ri;
128ea8ab 1746
d62a17ae 1747 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
1748 (struct prefix *)p, &vpn->prd);
1749 update_evpn_route_entry(bgp, vpn, afi, safi, rn, attr_new, 1, 0,
1a98c087 1750 &global_ri, flags);
128ea8ab 1751
d62a17ae 1752 /* Schedule for processing and unlock node. */
1753 bgp_process(bgp, rn, afi, safi);
1754 bgp_unlock_node(rn);
1755 }
128ea8ab 1756
d62a17ae 1757 /* Unintern temporary. */
1758 aspath_unintern(&attr.aspath);
128ea8ab 1759
d62a17ae 1760 return 0;
128ea8ab 1761}
1762
50f74cf1 1763/*
1764 * Delete EVPN route entry.
1765 * The entry can be in ESI/VNI table or the global table.
1766 */
1767static void delete_evpn_route_entry(struct bgp *bgp,
1768 afi_t afi, safi_t safi,
1769 struct bgp_node *rn,
1770 struct bgp_info **ri)
342dd0c6 1771{
50f74cf1 1772 struct bgp_info *tmp_ri;
342dd0c6 1773
1774 *ri = NULL;
1775
50f74cf1 1776 /* Now, find matching route. */
342dd0c6 1777 for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next)
50f74cf1 1778 if (tmp_ri->peer == bgp->peer_self
342dd0c6 1779 && tmp_ri->type == ZEBRA_ROUTE_BGP
1780 && tmp_ri->sub_type == BGP_ROUTE_STATIC)
1781 break;
1782
1783 *ri = tmp_ri;
1784
1785 /* Mark route for delete. */
1786 if (tmp_ri)
1787 bgp_info_delete(rn, tmp_ri);
1788}
1789
50f74cf1 1790
1791
1792/* Delete EVPN ES (type-4) route */
1793static int delete_evpn_type4_route(struct bgp *bgp,
1794 struct evpnes *es,
1795 struct prefix_evpn *p)
1796{
1797 afi_t afi = AFI_L2VPN;
1798 safi_t safi = SAFI_EVPN;
1799 struct bgp_info *ri;
1800 struct bgp_node *rn = NULL; /* rn in esi table */
1801 struct bgp_node *global_rn = NULL; /* rn in global table */
1802
1803 /* First, locate the route node within the ESI.
1804 * If it doesn't exist, ther is nothing to do.
1805 * Note: there is no RD here.
1806 */
1807 rn = bgp_node_lookup(es->route_table, (struct prefix *)p);
2bb9eff4 1808 if (!rn)
50f74cf1 1809 return 0;
1810
1811 /* Next, locate route node in the global EVPN routing table.
1812 * Note that this table is a 2-level tree (RD-level + Prefix-level)
1813 */
1814 global_rn = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi,
1815 (struct prefix *)p, &es->prd);
1816 if (global_rn) {
1817
1818 /* Delete route entry in the global EVPN table. */
1819 delete_evpn_route_entry(bgp, afi, safi,
1820 global_rn, &ri);
1821
1822 /* Schedule for processing - withdraws to peers happen from
1823 * this table.
1824 */
1825 if (ri)
1826 bgp_process(bgp, global_rn, afi, safi);
1827 bgp_unlock_node(global_rn);
1828 }
1829
1830 /*
1831 * Delete route entry in the ESI route table.
1832 * This can just be removed.
1833 */
1834 delete_evpn_route_entry(bgp, afi, safi, rn, &ri);
1835 if (ri)
1836 bgp_info_reap(rn, ri);
1837 bgp_unlock_node(rn);
1838 return 0;
1839}
1840
342dd0c6 1841/* Delete EVPN type5 route */
996c9314 1842static int delete_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp)
342dd0c6 1843{
1844 afi_t afi = AFI_L2VPN;
1845 safi_t safi = SAFI_EVPN;
1846 struct bgp_node *rn = NULL;
1847 struct bgp_info *ri = NULL;
1848 struct bgp *bgp_def = NULL; /* default bgp instance */
1849
1850 bgp_def = bgp_get_default();
1851 if (!bgp_def)
faafdfa8 1852 return 0;
342dd0c6 1853
1854 /* locate the global route entry for this type-5 prefix */
1855 rn = bgp_afi_node_lookup(bgp_def->rib[afi][safi], afi, safi,
1856 (struct prefix *)evp, &bgp_vrf->vrf_prd);
1857 if (!rn)
1858 return 0;
1859
50f74cf1 1860 delete_evpn_route_entry(bgp_def, afi, safi, rn, &ri);
342dd0c6 1861 if (ri)
1862 bgp_process(bgp_def, rn, afi, safi);
1863 bgp_unlock_node(rn);
1864 return 0;
1865}
1866
128ea8ab 1867/*
1868 * Delete EVPN route (of type based on prefix) for specified VNI and
1869 * schedule for processing.
1870 */
d62a17ae 1871static int delete_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
1872 struct prefix_evpn *p)
1873{
1874 struct bgp_node *rn, *global_rn;
1875 struct bgp_info *ri;
1876 afi_t afi = AFI_L2VPN;
1877 safi_t safi = SAFI_EVPN;
1878
1879 /* First, locate the route node within the VNI. If it doesn't exist,
1880 * there
1881 * is nothing further to do.
1882 */
1883 /* NOTE: There is no RD here. */
1884 rn = bgp_node_lookup(vpn->route_table, (struct prefix *)p);
1885 if (!rn)
1886 return 0;
1887
1888 /* Next, locate route node in the global EVPN routing table. Note that
1889 * this table is a 2-level tree (RD-level + Prefix-level) similar to
1890 * L3VPN routes.
1891 */
1892 global_rn = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi,
1893 (struct prefix *)p, &vpn->prd);
1894 if (global_rn) {
1895 /* Delete route entry in the global EVPN table. */
50f74cf1 1896 delete_evpn_route_entry(bgp, afi, safi, global_rn, &ri);
d62a17ae 1897
1898 /* Schedule for processing - withdraws to peers happen from
1899 * this table.
1900 */
1901 if (ri)
1902 bgp_process(bgp, global_rn, afi, safi);
1903 bgp_unlock_node(global_rn);
1904 }
1905
1906 /* Delete route entry in the VNI route table. This can just be removed.
1907 */
50f74cf1 1908 delete_evpn_route_entry(bgp, afi, safi, rn, &ri);
d62a17ae 1909 if (ri)
1910 bgp_info_reap(rn, ri);
1911 bgp_unlock_node(rn);
1912
1913 return 0;
128ea8ab 1914}
1915
1916/*
1917 * Update all type-2 (MACIP) local routes for this VNI - these should also
1918 * be scheduled for advertise to peers.
1919 */
d62a17ae 1920static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
1921{
1922 afi_t afi;
1923 safi_t safi;
1924 struct bgp_node *rn;
1925 struct bgp_info *ri;
1926 struct attr attr;
1927 struct attr attr_sticky;
ead40654 1928 struct attr attr_def_gw;
1ec31309 1929 struct attr attr_ip6_ll;
d62a17ae 1930 struct attr *attr_new;
1ec31309 1931 int add_l3_ecomm = 0;
d62a17ae 1932
1933 afi = AFI_L2VPN;
1934 safi = SAFI_EVPN;
1935 memset(&attr, 0, sizeof(struct attr));
1936 memset(&attr_sticky, 0, sizeof(struct attr));
ead40654 1937 memset(&attr_def_gw, 0, sizeof(struct attr));
1ec31309 1938 memset(&attr_ip6_ll, 0, sizeof(struct attr));
d62a17ae 1939
1ec31309 1940 /* Build path-attribute - multiple type-2 routes for this VNI will share
1941 * the same path attribute, but we need separate structures for sticky
1942 * MACs, default gateway and IPv6 link-local addresses (no L3 RT/RMAC).
d62a17ae 1943 */
1944 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
1945 bgp_attr_default_set(&attr_sticky, BGP_ORIGIN_IGP);
ead40654 1946 bgp_attr_default_set(&attr_def_gw, BGP_ORIGIN_IGP);
d62a17ae 1947 attr.nexthop = vpn->originator_ip;
1948 attr.mp_nexthop_global_in = vpn->originator_ip;
1949 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
bc59a672 1950 bgpevpn_get_rmac(vpn, &attr.rmac);
d62a17ae 1951 attr_sticky.nexthop = vpn->originator_ip;
1952 attr_sticky.mp_nexthop_global_in = vpn->originator_ip;
1953 attr_sticky.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
1954 attr_sticky.sticky = 1;
bc59a672 1955 bgpevpn_get_rmac(vpn, &attr_sticky.rmac);
ead40654
MK
1956 attr_def_gw.nexthop = vpn->originator_ip;
1957 attr_def_gw.mp_nexthop_global_in = vpn->originator_ip;
1958 attr_def_gw.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
1959 attr_def_gw.default_gw = 1;
1960 bgpevpn_get_rmac(vpn, &attr_def_gw.rmac);
1ec31309 1961 bgp_attr_default_set(&attr_ip6_ll, BGP_ORIGIN_IGP);
1962 attr_ip6_ll.nexthop = vpn->originator_ip;
1963 attr_ip6_ll.mp_nexthop_global_in = vpn->originator_ip;
1964 attr_ip6_ll.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
1965
1966 /* Add L3 VNI RTs and RMAC for non IPv6 link-local attributes if
1967 * using L3 VNI for type-2 routes also.
1968 */
1969 if (CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS))
1970 add_l3_ecomm = 1;
1971
1972 build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm);
1973 build_evpn_route_extcomm(vpn, &attr_sticky, add_l3_ecomm);
1974 build_evpn_route_extcomm(vpn, &attr_def_gw, add_l3_ecomm);
1975 build_evpn_route_extcomm(vpn, &attr_ip6_ll, 0);
d62a17ae 1976
1977 /* Walk this VNI's route table and update local type-2 routes. For any
1978 * routes updated, update corresponding entry in the global table too.
1979 */
1980 for (rn = bgp_table_top(vpn->route_table); rn;
1981 rn = bgp_route_next(rn)) {
1982 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
1983 struct bgp_node *rd_rn;
1984 struct bgp_info *global_ri;
1985
1986 if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
1987 continue;
1988
3714a385 1989 if (is_evpn_prefix_ipaddr_v6(evp) &&
1990 IN6_IS_ADDR_LINKLOCAL(&evp->prefix.macip_addr.ip.ipaddr_v6))
1ec31309 1991 update_evpn_route_entry(bgp, vpn, afi, safi, rn,
1992 &attr_ip6_ll, 0, 1, &ri, 0);
1993 else {
7ec156a9
MK
1994 if (evpn_route_is_sticky(bgp, rn))
1995 update_evpn_route_entry(bgp, vpn, afi, safi, rn,
996c9314
LB
1996 &attr_sticky, 0, 1, &ri,
1997 0);
ead40654
MK
1998 else if (evpn_route_is_def_gw(bgp, rn))
1999 update_evpn_route_entry(bgp, vpn, afi, safi, rn,
996c9314
LB
2000 &attr_def_gw, 0, 1, &ri,
2001 0);
7ec156a9
MK
2002 else
2003 update_evpn_route_entry(bgp, vpn, afi, safi, rn,
2004 &attr, 0, 1, &ri, 0);
7ec156a9 2005 }
d62a17ae 2006
2007 /* If a local route exists for this prefix, we need to update
2008 * the global routing table too.
2009 */
2010 if (!ri)
2011 continue;
2012
2013 /* Perform route selection; this is just to set the flags
2014 * correctly
2015 * as local route in the VNI always wins.
2016 */
2017 evpn_route_select_install(bgp, vpn, rn);
2018
2019 attr_new = ri->attr;
2020
2021 /* Update route in global routing table. */
2022 rd_rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
2023 (struct prefix *)evp, &vpn->prd);
2024 assert(rd_rn);
2025 update_evpn_route_entry(bgp, vpn, afi, safi, rd_rn, attr_new, 0,
1a98c087 2026 0, &global_ri, 0);
d62a17ae 2027
2028 /* Schedule for processing and unlock node. */
2029 bgp_process(bgp, rd_rn, afi, safi);
2030 bgp_unlock_node(rd_rn);
2031 }
2032
2033 /* Unintern temporary. */
2034 aspath_unintern(&attr.aspath);
2035 aspath_unintern(&attr_sticky.aspath);
ead40654 2036 aspath_unintern(&attr_def_gw.aspath);
1ec31309 2037 aspath_unintern(&attr_ip6_ll.aspath);
d62a17ae 2038
2039 return 0;
128ea8ab 2040}
2041
2042/*
2043 * Delete all type-2 (MACIP) local routes for this VNI - only from the
2044 * global routing table. These are also scheduled for withdraw from peers.
2045 */
d62a17ae 2046static int delete_global_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 2047{
d62a17ae 2048 afi_t afi;
2049 safi_t safi;
2050 struct bgp_node *rdrn, *rn;
2051 struct bgp_table *table;
2052 struct bgp_info *ri;
128ea8ab 2053
d62a17ae 2054 afi = AFI_L2VPN;
2055 safi = SAFI_EVPN;
128ea8ab 2056
d62a17ae 2057 rdrn = bgp_node_lookup(bgp->rib[afi][safi], (struct prefix *)&vpn->prd);
2058 if (rdrn && rdrn->info) {
2059 table = (struct bgp_table *)rdrn->info;
2060 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
2061 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
128ea8ab 2062
d62a17ae 2063 if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
2064 continue;
128ea8ab 2065
50f74cf1 2066 delete_evpn_route_entry(bgp, afi, safi, rn, &ri);
d62a17ae 2067 if (ri)
2068 bgp_process(bgp, rn, afi, safi);
2069 }
2070 }
128ea8ab 2071
d62a17ae 2072 /* Unlock RD node. */
2073 if (rdrn)
2074 bgp_unlock_node(rdrn);
128ea8ab 2075
d62a17ae 2076 return 0;
128ea8ab 2077}
2078
2079/*
2080 * Delete all type-2 (MACIP) local routes for this VNI - from the global
2081 * table as well as the per-VNI route table.
2082 */
d62a17ae 2083static int delete_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 2084{
d62a17ae 2085 afi_t afi;
2086 safi_t safi;
2087 struct bgp_node *rn;
2088 struct bgp_info *ri;
128ea8ab 2089
d62a17ae 2090 afi = AFI_L2VPN;
2091 safi = SAFI_EVPN;
128ea8ab 2092
d62a17ae 2093 /* First, walk the global route table for this VNI's type-2 local
2094 * routes.
2095 * EVPN routes are a 2-level table, first get the RD table.
2096 */
2097 delete_global_type2_routes(bgp, vpn);
128ea8ab 2098
d62a17ae 2099 /* Next, walk this VNI's route table and delete local type-2 routes. */
2100 for (rn = bgp_table_top(vpn->route_table); rn;
2101 rn = bgp_route_next(rn)) {
2102 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
128ea8ab 2103
d62a17ae 2104 if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
2105 continue;
128ea8ab 2106
50f74cf1 2107 delete_evpn_route_entry(bgp, afi, safi, rn, &ri);
128ea8ab 2108
d62a17ae 2109 /* Route entry in local table gets deleted immediately. */
2110 if (ri)
2111 bgp_info_reap(rn, ri);
2112 }
128ea8ab 2113
d62a17ae 2114 return 0;
128ea8ab 2115}
2116
50f74cf1 2117/*
2118 * Delete all routes in per ES route-table
2119 */
2120static int delete_all_es_routes(struct bgp *bgp, struct evpnes *es)
2121{
2122 struct bgp_node *rn;
2123 struct bgp_info *ri, *nextri;
2124
2125 /* Walk this ES's route table and delete all routes. */
2126 for (rn = bgp_table_top(es->route_table); rn;
2127 rn = bgp_route_next(rn)) {
2128 for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1);
2129 ri = nextri) {
2130 bgp_info_delete(rn, ri);
2131 bgp_info_reap(rn, ri);
2132 }
2133 }
2134
2135 return 0;
2136}
2137
128ea8ab 2138/*
2139 * Delete all routes in the per-VNI route table.
2140 */
d62a17ae 2141static int delete_all_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 2142{
d62a17ae 2143 struct bgp_node *rn;
2144 struct bgp_info *ri, *nextri;
128ea8ab 2145
d62a17ae 2146 /* Walk this VNI's route table and delete all routes. */
2147 for (rn = bgp_table_top(vpn->route_table); rn;
2148 rn = bgp_route_next(rn)) {
2149 for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1);
2150 ri = nextri) {
2151 bgp_info_delete(rn, ri);
2152 bgp_info_reap(rn, ri);
2153 }
2154 }
128ea8ab 2155
d62a17ae 2156 return 0;
128ea8ab 2157}
2158
2159/*
2160 * Update (and advertise) local routes for a VNI. Invoked upon the VNI
2161 * export RT getting modified or change to tunnel IP. Note that these
2162 * situations need the route in the per-VNI table as well as the global
2163 * table to be updated (as attributes change).
2164 */
d62a17ae 2165static int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 2166{
d62a17ae 2167 int ret;
2168 struct prefix_evpn p;
128ea8ab 2169
d62a17ae 2170 /* Update and advertise the type-3 route (only one) followed by the
2171 * locally learnt type-2 routes (MACIP) - for this VNI.
2172 */
2173 build_evpn_type3_prefix(&p, vpn->originator_ip);
2174 ret = update_evpn_route(bgp, vpn, &p, 0);
2175 if (ret)
2176 return ret;
128ea8ab 2177
d62a17ae 2178 return update_all_type2_routes(bgp, vpn);
128ea8ab 2179}
2180
50f74cf1 2181/* Delete (and withdraw) local routes for specified ES from global and ES table.
2182 * Also remove all other routes from the per ES table.
2183 * Invoked when ES is deleted.
2184 */
2185static int delete_routes_for_es(struct bgp *bgp, struct evpnes *es)
2186{
2187 int ret;
2188 char buf[ESI_STR_LEN];
2189 struct prefix_evpn p;
2190
2191 /* Delete and withdraw locally learnt ES route */
2192 build_evpn_type4_prefix(&p, &es->esi, es->originator_ip.ipaddr_v4);
2193 ret = delete_evpn_type4_route(bgp, es, &p);
2194 if (ret) {
2195 zlog_err(
2196 "%u failed to delete type-4 route for ESI %s",
2197 bgp->vrf_id,
2198 esi_to_str(&es->esi, buf, sizeof(buf)));
2199 }
2200
2201 /* Delete all routes from per ES table */
2202 return delete_all_es_routes(bgp, es);
2203}
2204
128ea8ab 2205/*
2206 * Delete (and withdraw) local routes for specified VNI from the global
2207 * table and per-VNI table. After this, remove all other routes from
2208 * the per-VNI table. Invoked upon the VNI being deleted or EVPN
2209 * (advertise-all-vni) being disabled.
2210 */
d62a17ae 2211static int delete_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 2212{
d62a17ae 2213 int ret;
2214 struct prefix_evpn p;
128ea8ab 2215
d62a17ae 2216 /* Delete and withdraw locally learnt type-2 routes (MACIP)
2217 * followed by type-3 routes (only one) - for this VNI.
2218 */
2219 ret = delete_all_type2_routes(bgp, vpn);
2220 if (ret)
2221 return ret;
128ea8ab 2222
d62a17ae 2223 build_evpn_type3_prefix(&p, vpn->originator_ip);
2224 ret = delete_evpn_route(bgp, vpn, &p);
2225 if (ret)
2226 return ret;
128ea8ab 2227
d62a17ae 2228 /* Delete all routes from the per-VNI table. */
2229 return delete_all_vni_routes(bgp, vpn);
128ea8ab 2230}
2231
2232/*
d1911c26 2233 * There is a tunnel endpoint IP address change for this VNI, delete
2234 * prior type-3 route (if needed) and update.
2235 * Note: Route re-advertisement happens elsewhere after other processing
2236 * other changes.
128ea8ab 2237 */
d62a17ae 2238static int handle_tunnel_ip_change(struct bgp *bgp, struct bgpevpn *vpn,
2239 struct in_addr originator_ip)
128ea8ab 2240{
d62a17ae 2241 struct prefix_evpn p;
128ea8ab 2242
ddd16ed5
MK
2243 /* If VNI is not live, we only need to update the originator ip */
2244 if (!is_vni_live(vpn)) {
2245 vpn->originator_ip = originator_ip;
2246 return 0;
2247 }
2248
db0e1937
MK
2249 /* Update the tunnel-ip hash */
2250 bgp_tip_del(bgp, &vpn->originator_ip);
2251 bgp_tip_add(bgp, &originator_ip);
2252
2253 /* filter routes as martian nexthop db has changed */
2254 bgp_filter_evpn_routes_upon_martian_nh_change(bgp);
2255
d62a17ae 2256 /* Need to withdraw type-3 route as the originator IP is part
2257 * of the key.
2258 */
2259 build_evpn_type3_prefix(&p, vpn->originator_ip);
2260 delete_evpn_route(bgp, vpn, &p);
128ea8ab 2261
d62a17ae 2262 /* Update the tunnel IP and re-advertise all routes for this VNI. */
2263 vpn->originator_ip = originator_ip;
d1911c26 2264 return 0;
128ea8ab 2265}
2266
50f74cf1 2267/* Install EVPN route entry in ES */
2268static int install_evpn_route_entry_in_es(struct bgp *bgp,
2269 struct evpnes *es,
2270 struct prefix_evpn *p,
2271 struct bgp_info *parent_ri)
2272{
2273 int ret = 0;
2274 struct bgp_node *rn = NULL;
2275 struct bgp_info *ri = NULL;
2276 struct attr *attr_new = NULL;
2277
2278 /* Create (or fetch) route within the VNI.
2279 * NOTE: There is no RD here.
2280 */
2281 rn = bgp_node_get(es->route_table, (struct prefix *)p);
2282
2283 /* Check if route entry is already present. */
2284 for (ri = rn->info; ri; ri = ri->next)
2285 if (ri->extra &&
2286 (struct bgp_info *)ri->extra->parent == parent_ri)
2287 break;
2288
2289 if (!ri) {
2290 /* Add (or update) attribute to hash. */
2291 attr_new = bgp_attr_intern(parent_ri->attr);
2292
2293 /* Create new route with its attribute. */
2294 ri = info_make(parent_ri->type, BGP_ROUTE_IMPORTED, 0,
2295 parent_ri->peer, attr_new, rn);
2296 SET_FLAG(ri->flags, BGP_INFO_VALID);
2297 bgp_info_extra_get(ri);
2298 ri->extra->parent = parent_ri;
2299 bgp_info_add(rn, ri);
2300 } else {
2301 if (attrhash_cmp(ri->attr, parent_ri->attr)
2302 && !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
2303 bgp_unlock_node(rn);
2304 return 0;
2305 }
2306 /* The attribute has changed. */
2307 /* Add (or update) attribute to hash. */
2308 attr_new = bgp_attr_intern(parent_ri->attr);
2309
2310 /* Restore route, if needed. */
2311 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
2312 bgp_info_restore(rn, ri);
2313
2314 /* Mark if nexthop has changed. */
2315 if (!IPV4_ADDR_SAME(&ri->attr->nexthop, &attr_new->nexthop))
2316 SET_FLAG(ri->flags, BGP_INFO_IGP_CHANGED);
2317
2318 /* Unintern existing, set to new. */
2319 bgp_attr_unintern(&ri->attr);
2320 ri->attr = attr_new;
2321 ri->uptime = bgp_clock();
2322 }
2323
2324 /* Perform route selection and update zebra, if required. */
2325 ret = evpn_es_route_select_install(bgp, es, rn);
2326 return ret;
2327}
2328
d3135ba3 2329/*
2330 * Install route entry into the VRF routing table and invoke route selection.
2331 */
2332static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
2333 struct prefix_evpn *evp,
2334 struct bgp_info *parent_ri)
2335{
2336 struct bgp_node *rn;
2337 struct bgp_info *ri;
1ec31309 2338 struct attr attr;
d3135ba3 2339 struct attr *attr_new;
c4edf708 2340 int ret = 0;
d3135ba3 2341 struct prefix p;
2342 struct prefix *pp = &p;
2343 afi_t afi = 0;
2344 safi_t safi = 0;
1eb88002
MK
2345 char buf[PREFIX_STRLEN];
2346 char buf1[PREFIX_STRLEN];
d3135ba3 2347
2348 memset(pp, 0, sizeof(struct prefix));
3714a385 2349 ip_prefix_from_evpn_prefix(evp, pp);
d3135ba3 2350
1eb88002 2351 if (bgp_debug_zebra(NULL)) {
996c9314
LB
2352 zlog_debug(
2353 "installing evpn prefix %s as ip prefix %s in vrf %s",
2354 prefix2str(evp, buf, sizeof(buf)),
2355 prefix2str(pp, buf1, sizeof(buf)),
2356 vrf_id_to_name(bgp_vrf->vrf_id));
1eb88002
MK
2357 }
2358
d3135ba3 2359 /* Create (or fetch) route within the VRF. */
2360 /* NOTE: There is no RD here. */
3714a385 2361 if (is_evpn_prefix_ipaddr_v4(evp)) {
d3135ba3 2362 afi = AFI_IP;
2363 safi = SAFI_UNICAST;
2364 rn = bgp_node_get(bgp_vrf->rib[afi][safi], pp);
3714a385 2365 } else if (is_evpn_prefix_ipaddr_v6(evp)) {
d3135ba3 2366 afi = AFI_IP6;
2367 safi = SAFI_UNICAST;
2368 rn = bgp_node_get(bgp_vrf->rib[afi][safi], pp);
2369 } else
2370 return 0;
2371
1ec31309 2372 /* EVPN routes currently only support a IPv4 next hop which corresponds
2373 * to the remote VTEP. When importing into a VRF, if it is IPv6 host
450e362d 2374 * or prefix route, we have to convert the next hop to an IPv4-mapped
2375 * address for the rest of the code to flow through. In the case of IPv4,
2376 * make sure to set the flag for next hop attribute.
1ec31309 2377 */
2378 bgp_attr_dup(&attr, parent_ri->attr);
2379 if (afi == AFI_IP6)
2380 evpn_convert_nexthop_to_ipv6(&attr);
450e362d 2381 else
2382 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
1ec31309 2383
d3135ba3 2384 /* Check if route entry is already present. */
2385 for (ri = rn->info; ri; ri = ri->next)
2386 if (ri->extra
2387 && (struct bgp_info *)ri->extra->parent == parent_ri)
2388 break;
2389
2390 if (!ri) {
2391 /* Add (or update) attribute to hash. */
1ec31309 2392 attr_new = bgp_attr_intern(&attr);
d3135ba3 2393
2394 /* Create new route with its attribute. */
90f4f482 2395 ri = info_make(parent_ri->type, BGP_ROUTE_IMPORTED, 0,
d3135ba3 2396 parent_ri->peer, attr_new, rn);
2397 SET_FLAG(ri->flags, BGP_INFO_VALID);
2398 bgp_info_extra_get(ri);
528cd74f 2399 ri->extra->parent = bgp_info_lock(parent_ri);
7c82b312 2400 bgp_lock_node((struct bgp_node *)parent_ri->net);
b57ba6d2 2401 if (parent_ri->extra) {
d3135ba3 2402 memcpy(&ri->extra->label, &parent_ri->extra->label,
b57ba6d2
MK
2403 sizeof(ri->extra->label));
2404 ri->extra->num_labels = parent_ri->extra->num_labels;
2405 }
d3135ba3 2406 bgp_info_add(rn, ri);
2407 } else {
1ec31309 2408 if (attrhash_cmp(ri->attr, &attr)
d3135ba3 2409 && !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
2410 bgp_unlock_node(rn);
2411 return 0;
2412 }
2413 /* The attribute has changed. */
2414 /* Add (or update) attribute to hash. */
1ec31309 2415 attr_new = bgp_attr_intern(&attr);
d3135ba3 2416
2417 /* Restore route, if needed. */
2418 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
2419 bgp_info_restore(rn, ri);
2420
2421 /* Mark if nexthop has changed. */
1ec31309 2422 if ((afi == AFI_IP &&
2423 !IPV4_ADDR_SAME(&ri->attr->nexthop, &attr_new->nexthop)) ||
2424 (afi == AFI_IP6 &&
2425 !IPV6_ADDR_SAME(&ri->attr->mp_nexthop_global,
2426 &attr_new->mp_nexthop_global)))
d3135ba3 2427 SET_FLAG(ri->flags, BGP_INFO_IGP_CHANGED);
2428
2429 /* Unintern existing, set to new. */
2430 bgp_attr_unintern(&ri->attr);
2431 ri->attr = attr_new;
2432 ri->uptime = bgp_clock();
2433 }
2434
2435 /* Perform route selection and update zebra, if required. */
1eb88002 2436 bgp_process(bgp_vrf, rn, afi, safi);
d3135ba3 2437
2438 return ret;
2439}
2440
128ea8ab 2441/*
2442 * Install route entry into the VNI routing table and invoke route selection.
2443 */
d62a17ae 2444static int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
2445 struct prefix_evpn *p,
2446 struct bgp_info *parent_ri)
2447{
2448 struct bgp_node *rn;
2449 struct bgp_info *ri;
2450 struct attr *attr_new;
2451 int ret;
2452
2453 /* Create (or fetch) route within the VNI. */
2454 /* NOTE: There is no RD here. */
2455 rn = bgp_node_get(vpn->route_table, (struct prefix *)p);
2456
2457 /* Check if route entry is already present. */
2458 for (ri = rn->info; ri; ri = ri->next)
2459 if (ri->extra
2460 && (struct bgp_info *)ri->extra->parent == parent_ri)
2461 break;
2462
2463 if (!ri) {
2464 /* Add (or update) attribute to hash. */
2465 attr_new = bgp_attr_intern(parent_ri->attr);
2466
2467 /* Create new route with its attribute. */
90f4f482 2468 ri = info_make(parent_ri->type, BGP_ROUTE_IMPORTED, 0,
d62a17ae 2469 parent_ri->peer, attr_new, rn);
2470 SET_FLAG(ri->flags, BGP_INFO_VALID);
2471 bgp_info_extra_get(ri);
528cd74f 2472 ri->extra->parent = bgp_info_lock(parent_ri);
7c82b312 2473 bgp_lock_node((struct bgp_node *)parent_ri->net);
b57ba6d2 2474 if (parent_ri->extra) {
d62a17ae 2475 memcpy(&ri->extra->label, &parent_ri->extra->label,
b57ba6d2
MK
2476 sizeof(ri->extra->label));
2477 ri->extra->num_labels = parent_ri->extra->num_labels;
2478 }
d62a17ae 2479 bgp_info_add(rn, ri);
2480 } else {
2481 if (attrhash_cmp(ri->attr, parent_ri->attr)
2482 && !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
2483 bgp_unlock_node(rn);
2484 return 0;
2485 }
2486 /* The attribute has changed. */
2487 /* Add (or update) attribute to hash. */
2488 attr_new = bgp_attr_intern(parent_ri->attr);
2489
50f74cf1 2490 /* Restore route, if needed. */
2491 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
2492 bgp_info_restore(rn, ri);
2493
2494 /* Mark if nexthop has changed. */
2495 if (!IPV4_ADDR_SAME(&ri->attr->nexthop, &attr_new->nexthop))
2496 SET_FLAG(ri->flags, BGP_INFO_IGP_CHANGED);
2497
2498 /* Unintern existing, set to new. */
2499 bgp_attr_unintern(&ri->attr);
2500 ri->attr = attr_new;
2501 ri->uptime = bgp_clock();
2502 }
2503
2504 /* Perform route selection and update zebra, if required. */
2505 ret = evpn_route_select_install(bgp, vpn, rn);
2506
2507 return ret;
2508}
2509
2510/* Uninstall EVPN route entry from ES route table */
2511static int uninstall_evpn_route_entry_in_es(struct bgp *bgp,
2512 struct evpnes *es,
2513 struct prefix_evpn *p,
2514 struct bgp_info *parent_ri)
2515{
2516 int ret;
2517 struct bgp_node *rn;
2518 struct bgp_info *ri;
2519
2520 if (!es->route_table)
2521 return 0;
2522
2523 /* Locate route within the ESI.
2524 * NOTE: There is no RD here.
2525 */
2526 rn = bgp_node_lookup(es->route_table, (struct prefix *)p);
2527 if (!rn)
2528 return 0;
2529
2530 /* Find matching route entry. */
2531 for (ri = rn->info; ri; ri = ri->next)
2532 if (ri->extra &&
2533 (struct bgp_info *)ri->extra->parent == parent_ri)
2534 break;
d62a17ae 2535
50f74cf1 2536 if (!ri)
2537 return 0;
d62a17ae 2538
50f74cf1 2539 /* Mark entry for deletion */
2540 bgp_info_delete(rn, ri);
d62a17ae 2541
2542 /* Perform route selection and update zebra, if required. */
50f74cf1 2543 ret = evpn_es_route_select_install(bgp, es, rn);
2544
2545 /* Unlock route node. */
2546 bgp_unlock_node(rn);
d62a17ae 2547
2548 return ret;
128ea8ab 2549}
2550
d3135ba3 2551/*
2552 * Uninstall route entry from the VRF routing table and send message
2553 * to zebra, if appropriate.
2554 */
2555static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
2556 struct prefix_evpn *evp,
2557 struct bgp_info *parent_ri)
2558{
2559 struct bgp_node *rn;
2560 struct bgp_info *ri;
c4edf708 2561 int ret = 0;
d3135ba3 2562 struct prefix p;
2563 struct prefix *pp = &p;
2564 afi_t afi = 0;
2565 safi_t safi = 0;
1eb88002
MK
2566 char buf[PREFIX_STRLEN];
2567 char buf1[PREFIX_STRLEN];
d3135ba3 2568
2569 memset(pp, 0, sizeof(struct prefix));
3714a385 2570 ip_prefix_from_evpn_prefix(evp, pp);
d3135ba3 2571
1eb88002 2572 if (bgp_debug_zebra(NULL)) {
996c9314
LB
2573 zlog_debug(
2574 "uninstalling evpn prefix %s as ip prefix %s in vrf %s",
2575 prefix2str(evp, buf, sizeof(buf)),
2576 prefix2str(pp, buf1, sizeof(buf)),
2577 vrf_id_to_name(bgp_vrf->vrf_id));
1eb88002
MK
2578 }
2579
d3135ba3 2580 /* Locate route within the VRF. */
2581 /* NOTE: There is no RD here. */
3714a385 2582 if (is_evpn_prefix_ipaddr_v4(evp)) {
d3135ba3 2583 afi = AFI_IP;
2584 safi = SAFI_UNICAST;
2585 rn = bgp_node_lookup(bgp_vrf->rib[afi][safi], pp);
2586 } else {
2587 afi = AFI_IP6;
2588 safi = SAFI_UNICAST;
2589 rn = bgp_node_lookup(bgp_vrf->rib[afi][safi], pp);
2590 }
2591
2592 if (!rn)
2593 return 0;
2594
2595 /* Find matching route entry. */
2596 for (ri = rn->info; ri; ri = ri->next)
2597 if (ri->extra
2598 && (struct bgp_info *)ri->extra->parent == parent_ri)
2599 break;
2600
2601 if (!ri)
2602 return 0;
2603
2604 /* Mark entry for deletion */
2605 bgp_info_delete(rn, ri);
2606
2607 /* Perform route selection and update zebra, if required. */
1eb88002 2608 bgp_process(bgp_vrf, rn, afi, safi);
d3135ba3 2609
2610 /* Unlock route node. */
2611 bgp_unlock_node(rn);
2612
2613 return ret;
2614}
2615
128ea8ab 2616/*
2617 * Uninstall route entry from the VNI routing table and send message
2618 * to zebra, if appropriate.
2619 */
d62a17ae 2620static int uninstall_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
2621 struct prefix_evpn *p,
2622 struct bgp_info *parent_ri)
128ea8ab 2623{
d62a17ae 2624 struct bgp_node *rn;
2625 struct bgp_info *ri;
2626 int ret;
128ea8ab 2627
d62a17ae 2628 /* Locate route within the VNI. */
2629 /* NOTE: There is no RD here. */
2630 rn = bgp_node_lookup(vpn->route_table, (struct prefix *)p);
2631 if (!rn)
2632 return 0;
128ea8ab 2633
d62a17ae 2634 /* Find matching route entry. */
2635 for (ri = rn->info; ri; ri = ri->next)
2636 if (ri->extra
2637 && (struct bgp_info *)ri->extra->parent == parent_ri)
2638 break;
128ea8ab 2639
d62a17ae 2640 if (!ri)
2641 return 0;
128ea8ab 2642
d62a17ae 2643 /* Mark entry for deletion */
2644 bgp_info_delete(rn, ri);
128ea8ab 2645
d62a17ae 2646 /* Perform route selection and update zebra, if required. */
2647 ret = evpn_route_select_install(bgp, vpn, rn);
128ea8ab 2648
d62a17ae 2649 /* Unlock route node. */
2650 bgp_unlock_node(rn);
128ea8ab 2651
d62a17ae 2652 return ret;
128ea8ab 2653}
2654
50f74cf1 2655/*
2656 * Given a prefix, see if it belongs to ES.
2657 */
2658static int is_prefix_matching_for_es(struct prefix_evpn *p,
2659 struct evpnes *es)
2660{
2661 /* if not an ES route return false */
2662 if (p->prefix.route_type != BGP_EVPN_ES_ROUTE)
2663 return 0;
2664
2665 if (memcmp(&p->prefix.es_addr.esi, &es->esi, sizeof(esi_t)) == 0)
2666 return 1;
2667
2668 return 0;
2669}
2670
5ba238b7
MK
2671/*
2672 * Given a route entry and a VRF, see if this route entry should be
2673 * imported into the VRF i.e., RTs match.
2674 */
996c9314 2675static int is_route_matching_for_vrf(struct bgp *bgp_vrf, struct bgp_info *ri)
5ba238b7
MK
2676{
2677 struct attr *attr = ri->attr;
2678 struct ecommunity *ecom;
2679 int i;
2680
2681 assert(attr);
2682 /* Route should have valid RT to be even considered. */
2683 if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
2684 return 0;
2685
2686 ecom = attr->ecommunity;
2687 if (!ecom || !ecom->size)
2688 return 0;
2689
2690 /* For each extended community RT, see if it matches this VNI. If any RT
2691 * matches, we're done.
2692 */
2693 for (i = 0; i < ecom->size; i++) {
d7c0a89a
QY
2694 uint8_t *pnt;
2695 uint8_t type, sub_type;
5ba238b7
MK
2696 struct ecommunity_val *eval;
2697 struct ecommunity_val eval_tmp;
2698 struct vrf_irt_node *irt;
2699
2700 /* Only deal with RTs */
2701 pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
2702 eval = (struct ecommunity_val *)(ecom->val
2703 + (i * ECOMMUNITY_SIZE));
2704 type = *pnt++;
2705 sub_type = *pnt++;
2706 if (sub_type != ECOMMUNITY_ROUTE_TARGET)
2707 continue;
2708
2709 /* See if this RT matches specified VNIs import RTs */
2710 irt = lookup_vrf_import_rt(eval);
5d9cbca2 2711 if (irt)
5ba238b7
MK
2712 if (is_vrf_present_in_irt_vrfs(irt->vrfs, bgp_vrf))
2713 return 1;
2714
2715 /* Also check for non-exact match. In this, we mask out the AS
2716 * and
2717 * only check on the local-admin sub-field. This is to
2718 * facilitate using
2719 * VNI as the RT for EBGP peering too.
2720 */
2721 irt = NULL;
2722 if (type == ECOMMUNITY_ENCODE_AS
2723 || type == ECOMMUNITY_ENCODE_AS4
2724 || type == ECOMMUNITY_ENCODE_IP) {
2725 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
2726 mask_ecom_global_admin(&eval_tmp, eval);
2727 irt = lookup_vrf_import_rt(&eval_tmp);
2728 }
5d9cbca2 2729 if (irt)
5ba238b7
MK
2730 if (is_vrf_present_in_irt_vrfs(irt->vrfs, bgp_vrf))
2731 return 1;
2732 }
2733
2734 return 0;
2735}
2736
128ea8ab 2737/*
2738 * Given a route entry and a VNI, see if this route entry should be
2739 * imported into the VNI i.e., RTs match.
2740 */
d62a17ae 2741static int is_route_matching_for_vni(struct bgp *bgp, struct bgpevpn *vpn,
2742 struct bgp_info *ri)
2743{
2744 struct attr *attr = ri->attr;
2745 struct ecommunity *ecom;
2746 int i;
2747
2748 assert(attr);
2749 /* Route should have valid RT to be even considered. */
2750 if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
2751 return 0;
2752
2753 ecom = attr->ecommunity;
2754 if (!ecom || !ecom->size)
2755 return 0;
2756
2757 /* For each extended community RT, see if it matches this VNI. If any RT
2758 * matches, we're done.
2759 */
2760 for (i = 0; i < ecom->size; i++) {
d7c0a89a
QY
2761 uint8_t *pnt;
2762 uint8_t type, sub_type;
d62a17ae 2763 struct ecommunity_val *eval;
2764 struct ecommunity_val eval_tmp;
2765 struct irt_node *irt;
2766
2767 /* Only deal with RTs */
2768 pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
2769 eval = (struct ecommunity_val *)(ecom->val
2770 + (i * ECOMMUNITY_SIZE));
2771 type = *pnt++;
2772 sub_type = *pnt++;
2773 if (sub_type != ECOMMUNITY_ROUTE_TARGET)
2774 continue;
2775
2776 /* See if this RT matches specified VNIs import RTs */
2777 irt = lookup_import_rt(bgp, eval);
b1ab0dfe 2778 if (irt)
d62a17ae 2779 if (is_vni_present_in_irt_vnis(irt->vnis, vpn))
2780 return 1;
2781
2782 /* Also check for non-exact match. In this, we mask out the AS
2783 * and
2784 * only check on the local-admin sub-field. This is to
2785 * facilitate using
2786 * VNI as the RT for EBGP peering too.
2787 */
2788 irt = NULL;
2789 if (type == ECOMMUNITY_ENCODE_AS
2790 || type == ECOMMUNITY_ENCODE_AS4
2791 || type == ECOMMUNITY_ENCODE_IP) {
2792 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
2793 mask_ecom_global_admin(&eval_tmp, eval);
2794 irt = lookup_import_rt(bgp, &eval_tmp);
2795 }
b1ab0dfe 2796 if (irt)
d62a17ae 2797 if (is_vni_present_in_irt_vnis(irt->vnis, vpn))
2798 return 1;
2799 }
2800
2801 return 0;
128ea8ab 2802}
2803
50f74cf1 2804static int install_uninstall_routes_for_es(struct bgp *bgp,
2805 struct evpnes *es,
2806 int install)
2807{
2808 int ret;
2809 afi_t afi;
2810 safi_t safi;
2811 char buf[PREFIX_STRLEN];
2812 char buf1[ESI_STR_LEN];
2813 struct bgp_node *rd_rn, *rn;
2814 struct bgp_table *table;
2815 struct bgp_info *ri;
2816
2817 afi = AFI_L2VPN;
2818 safi = SAFI_EVPN;
2819
2bb9eff4
DS
2820 /*
2821 * Walk entire global routing table and evaluate routes which could be
50f74cf1 2822 * imported into this VRF. Note that we need to loop through all global
2823 * routes to determine which route matches the import rt on vrf
2824 */
2825 for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
2826 rd_rn = bgp_route_next(rd_rn)) {
2827 table = (struct bgp_table *)(rd_rn->info);
2828 if (!table)
2829 continue;
2830
2831 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
2832 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
2833
2834 for (ri = rn->info; ri; ri = ri->next) {
2bb9eff4
DS
2835 /*
2836 * Consider "valid" remote routes applicable for
50f74cf1 2837 * this ES.
2838 */
2839 if (!(CHECK_FLAG(ri->flags, BGP_INFO_VALID)
2840 && ri->type == ZEBRA_ROUTE_BGP
2841 && ri->sub_type == BGP_ROUTE_NORMAL))
2842 continue;
2843
2bb9eff4
DS
2844 if (!is_prefix_matching_for_es(evp, es))
2845 continue;
50f74cf1 2846
2bb9eff4
DS
2847 if (install)
2848 ret = install_evpn_route_entry_in_es(
2849 bgp, es, evp, ri);
2850 else
2851 ret = uninstall_evpn_route_entry_in_es(
2852 bgp, es, evp, ri);
2853
2854 if (ret) {
2855 zlog_err(
2856 "Failed to %s EVPN %s route in ESI %s",
2857 install ? "install"
2858 : "uninstall",
2859 prefix2str(evp, buf,
2860 sizeof(buf)),
2861 esi_to_str(&es->esi, buf1,
2862 sizeof(buf1)));
2863 return ret;
50f74cf1 2864 }
2865 }
2866 }
2867 }
2868 return 0;
2869}
2870
5ba238b7
MK
2871/*
2872 * Install or uninstall mac-ip routes are appropriate for this
2873 * particular VRF.
2874 */
996c9314 2875static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install)
5ba238b7
MK
2876{
2877 afi_t afi;
2878 safi_t safi;
2879 struct bgp_node *rd_rn, *rn;
2880 struct bgp_table *table;
2881 struct bgp_info *ri;
2882 int ret;
2883 char buf[PREFIX_STRLEN];
2884 struct bgp *bgp_def = NULL;
2885
2886 afi = AFI_L2VPN;
2887 safi = SAFI_EVPN;
2888 bgp_def = bgp_get_default();
2889 if (!bgp_def)
2890 return -1;
2891
2892 /* Walk entire global routing table and evaluate routes which could be
2893 * imported into this VRF. Note that we need to loop through all global
2894 * routes to determine which route matches the import rt on vrf
2895 */
2896 for (rd_rn = bgp_table_top(bgp_def->rib[afi][safi]); rd_rn;
2897 rd_rn = bgp_route_next(rd_rn)) {
2898 table = (struct bgp_table *)(rd_rn->info);
2899 if (!table)
2900 continue;
2901
2902 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
2903 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
2904
1eb88002 2905 /* if not mac-ip route skip this route */
996c9314
LB
2906 if (!(evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
2907 || evp->prefix.route_type
2908 == BGP_EVPN_IP_PREFIX_ROUTE))
5ba238b7
MK
2909 continue;
2910
1eb88002 2911 /* if not a mac+ip route skip this route */
3714a385 2912 if (!(is_evpn_prefix_ipaddr_v4(evp)
2913 || is_evpn_prefix_ipaddr_v6(evp)))
1eb88002
MK
2914 continue;
2915
5ba238b7
MK
2916 for (ri = rn->info; ri; ri = ri->next) {
2917 /* Consider "valid" remote routes applicable for
523cafc4 2918 * this VRF.
2919 */
5ba238b7
MK
2920 if (!(CHECK_FLAG(ri->flags, BGP_INFO_VALID)
2921 && ri->type == ZEBRA_ROUTE_BGP
2922 && ri->sub_type == BGP_ROUTE_NORMAL))
2923 continue;
2924
2925 if (is_route_matching_for_vrf(bgp_vrf, ri)) {
2926 if (install)
996c9314 2927 ret = install_evpn_route_entry_in_vrf(
5ba238b7
MK
2928 bgp_vrf, evp, ri);
2929 else
996c9314 2930 ret = uninstall_evpn_route_entry_in_vrf(
5ba238b7
MK
2931 bgp_vrf, evp, ri);
2932
2933 if (ret) {
2934 zlog_err(
2935 "Failed to %s EVPN %s route in VRF %s",
2936 install ? "install"
2937 : "uninstall",
2938 prefix2str(evp, buf,
2939 sizeof(buf)),
996c9314
LB
2940 vrf_id_to_name(
2941 bgp_vrf->vrf_id));
5ba238b7
MK
2942 return ret;
2943 }
2944 }
2945 }
2946 }
2947 }
2948
2949 return 0;
2950}
2951
128ea8ab 2952/*
2953 * Install or uninstall routes of specified type that are appropriate for this
2954 * particular VNI.
2955 */
d62a17ae 2956static int install_uninstall_routes_for_vni(struct bgp *bgp,
2957 struct bgpevpn *vpn,
2958 bgp_evpn_route_type rtype,
2959 int install)
2960{
0291c246
MK
2961 afi_t afi;
2962 safi_t safi;
2963 struct bgp_node *rd_rn, *rn;
2964 struct bgp_table *table;
2965 struct bgp_info *ri;
2966 int ret;
d62a17ae 2967
2968 afi = AFI_L2VPN;
2969 safi = SAFI_EVPN;
2970
2971 /* Walk entire global routing table and evaluate routes which could be
2972 * imported into this VPN. Note that we cannot just look at the routes
2973 * for
2974 * the VNI's RD - remote routes applicable for this VNI could have any
2975 * RD.
2976 */
2977 /* EVPN routes are a 2-level table. */
2978 for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
2979 rd_rn = bgp_route_next(rd_rn)) {
2980 table = (struct bgp_table *)(rd_rn->info);
2981 if (!table)
2982 continue;
2983
2984 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
2985 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
2986
2987 if (evp->prefix.route_type != rtype)
2988 continue;
2989
2990 for (ri = rn->info; ri; ri = ri->next) {
2991 /* Consider "valid" remote routes applicable for
2992 * this VNI. */
2993 if (!(CHECK_FLAG(ri->flags, BGP_INFO_VALID)
2994 && ri->type == ZEBRA_ROUTE_BGP
2995 && ri->sub_type == BGP_ROUTE_NORMAL))
2996 continue;
2997
2998 if (is_route_matching_for_vni(bgp, vpn, ri)) {
2999 if (install)
3000 ret = install_evpn_route_entry(
60466a63 3001 bgp, vpn, evp, ri);
d62a17ae 3002 else
3003 ret = uninstall_evpn_route_entry(
3004 bgp, vpn, evp, ri);
3005
3006 if (ret) {
3007 zlog_err(
3008 "%u: Failed to %s EVPN %s route in VNI %u",
3009 bgp->vrf_id,
3010 install ? "install"
3011 : "uninstall",
3012 rtype == BGP_EVPN_MAC_IP_ROUTE
3013 ? "MACIP"
3014 : "IMET",
3015 vpn->vni);
3016 return ret;
3017 }
3018 }
3019 }
3020 }
3021 }
3022
3023 return 0;
128ea8ab 3024}
3025
50f74cf1 3026/* Install any existing remote ES routes applicable for this ES into its routing
3027 * table. This is invoked when ES comes up.
3028 */
3029static int install_routes_for_es(struct bgp *bgp, struct evpnes *es)
3030{
3031 return install_uninstall_routes_for_es(bgp, es, 1);
3032}
3033
3034
5ba238b7 3035/* Install any existing remote routes applicable for this VRF into VRF RIB. This
523cafc4 3036 * is invoked upon l3vni-add or l3vni import rt change
3037 */
5ba238b7
MK
3038static int install_routes_for_vrf(struct bgp *bgp_vrf)
3039{
3040 install_uninstall_routes_for_vrf(bgp_vrf, 1);
3041 return 0;
3042}
3043
128ea8ab 3044/*
3045 * Install any existing remote routes applicable for this VNI into its
3046 * routing table. This is invoked when a VNI becomes "live" or its Import
3047 * RT is changed.
3048 */
d62a17ae 3049static int install_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 3050{
d62a17ae 3051 int ret;
128ea8ab 3052
d62a17ae 3053 /* Install type-3 routes followed by type-2 routes - the ones applicable
3054 * for this VNI.
3055 */
3056 ret = install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_IMET_ROUTE,
3057 1);
3058 if (ret)
3059 return ret;
128ea8ab 3060
d62a17ae 3061 return install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_MAC_IP_ROUTE,
3062 1);
128ea8ab 3063}
3064
5ba238b7
MK
3065/* uninstall routes from l3vni vrf. */
3066static int uninstall_routes_for_vrf(struct bgp *bgp_vrf)
3067{
3068 install_uninstall_routes_for_vrf(bgp_vrf, 0);
3069 return 0;
3070}
3071
90e60aa7 3072/*
3073 * Uninstall any existing remote routes for this VNI. One scenario in which
3074 * this is invoked is upon an import RT change.
3075 */
d62a17ae 3076static int uninstall_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 3077{
d62a17ae 3078 int ret;
90e60aa7 3079
d62a17ae 3080 /* Uninstall type-2 routes followed by type-3 routes - the ones
3081 * applicable
3082 * for this VNI.
3083 */
3084 ret = install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_MAC_IP_ROUTE,
3085 0);
3086 if (ret)
3087 return ret;
90e60aa7 3088
d62a17ae 3089 return install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_IMET_ROUTE,
3090 0);
90e60aa7 3091}
3092
50f74cf1 3093/* Install or unistall route in ES */
3094static int install_uninstall_route_in_es(struct bgp *bgp, struct evpnes *es,
3095 afi_t afi, safi_t safi,
3096 struct prefix_evpn *evp,
3097 struct bgp_info *ri,
3098 int install)
3099{
3100 int ret = 0;
3101 char buf[ESI_STR_LEN];
3102
3103 if (install)
3104 ret = install_evpn_route_entry_in_es(bgp, es, evp, ri);
3105 else
3106 ret = uninstall_evpn_route_entry_in_es(bgp, es, evp, ri);
3107
3108 if (ret) {
3109 zlog_err("%u: Failed to %s EVPN %s route in ESI %s",
3110 bgp->vrf_id, install ? "install" : "uninstall",
3111 "ES",
3112 esi_to_str(&evp->prefix.es_addr.esi, buf,
3113 sizeof(buf)));
3114 return ret;
3115 }
3116 return 0;
3117}
3118
d3135ba3 3119/*
3120 * Install or uninstall route in matching VRFs (list).
3121 */
3122static int install_uninstall_route_in_vrfs(struct bgp *bgp_def, afi_t afi,
3123 safi_t safi, struct prefix_evpn *evp,
3124 struct bgp_info *ri,
3125 struct list *vrfs, int install)
3126{
3127 char buf[PREFIX2STR_BUFFER];
3128 struct bgp *bgp_vrf;
3129 struct listnode *node, *nnode;
3130
90264d64 3131 /* Only type-2/type-5 routes go into a VRF */
996c9314
LB
3132 if (!(evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
3133 || evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE))
d3135ba3 3134 return 0;
3135
90264d64 3136 /* if it is type-2 route and not a mac+ip route skip this route */
996c9314 3137 if ((evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
3714a385 3138 && !(is_evpn_prefix_ipaddr_v4(evp)
3139 || is_evpn_prefix_ipaddr_v6(evp)))
30a30f57
MK
3140 return 0;
3141
d3135ba3 3142 for (ALL_LIST_ELEMENTS(vrfs, node, nnode, bgp_vrf)) {
3143 int ret;
3144
3145 if (install)
996c9314 3146 ret = install_evpn_route_entry_in_vrf(bgp_vrf, evp, ri);
d3135ba3 3147 else
996c9314
LB
3148 ret = uninstall_evpn_route_entry_in_vrf(bgp_vrf, evp,
3149 ri);
d3135ba3 3150
3151 if (ret) {
3152 zlog_err("%u: Failed to %s prefix %s in VRF %s",
3153 bgp_def->vrf_id,
3154 install ? "install" : "uninstall",
3155 prefix2str(evp, buf, sizeof(buf)),
3156 vrf_id_to_name(bgp_vrf->vrf_id));
3157 return ret;
3158 }
3159 }
3160
3161 return 0;
3162}
3163
128ea8ab 3164/*
3165 * Install or uninstall route in matching VNIs (list).
3166 */
d62a17ae 3167static int install_uninstall_route_in_vnis(struct bgp *bgp, afi_t afi,
3168 safi_t safi, struct prefix_evpn *evp,
3169 struct bgp_info *ri,
3170 struct list *vnis, int install)
128ea8ab 3171{
d62a17ae 3172 struct bgpevpn *vpn;
3173 struct listnode *node, *nnode;
128ea8ab 3174
d62a17ae 3175 for (ALL_LIST_ELEMENTS(vnis, node, nnode, vpn)) {
3176 int ret;
128ea8ab 3177
d62a17ae 3178 if (!is_vni_live(vpn))
3179 continue;
128ea8ab 3180
d62a17ae 3181 if (install)
3182 ret = install_evpn_route_entry(bgp, vpn, evp, ri);
3183 else
3184 ret = uninstall_evpn_route_entry(bgp, vpn, evp, ri);
128ea8ab 3185
d62a17ae 3186 if (ret) {
3187 zlog_err("%u: Failed to %s EVPN %s route in VNI %u",
3188 bgp->vrf_id, install ? "install" : "uninstall",
3189 evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
3190 ? "MACIP"
3191 : "IMET",
3192 vpn->vni);
3193 return ret;
3194 }
3195 }
128ea8ab 3196
d62a17ae 3197 return 0;
128ea8ab 3198}
3199
3200/*
50f74cf1 3201 * Install or uninstall route for appropriate VNIs/ESIs.
128ea8ab 3202 */
d62a17ae 3203static int install_uninstall_evpn_route(struct bgp *bgp, afi_t afi, safi_t safi,
3204 struct prefix *p, struct bgp_info *ri,
3205 int import)
3206{
3207 struct prefix_evpn *evp = (struct prefix_evpn *)p;
3208 struct attr *attr = ri->attr;
3209 struct ecommunity *ecom;
3210 int i;
3211
3212 assert(attr);
3213
50f74cf1 3214 /* Only type-2, type-3, type-4 and type-5 are supported currently */
d62a17ae 3215 if (!(evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
90264d64 3216 || evp->prefix.route_type == BGP_EVPN_IMET_ROUTE
50f74cf1 3217 || evp->prefix.route_type == BGP_EVPN_ES_ROUTE
90264d64 3218 || evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE))
d62a17ae 3219 return 0;
3220
3221 /* If we don't have Route Target, nothing much to do. */
3222 if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
3223 return 0;
3224
3225 ecom = attr->ecommunity;
3226 if (!ecom || !ecom->size)
3227 return -1;
3228
50f74cf1 3229 /* An EVPN route belongs to a VNI or a VRF or an ESI based on the RTs
3230 * attached to the route */
d62a17ae 3231 for (i = 0; i < ecom->size; i++) {
d7c0a89a
QY
3232 uint8_t *pnt;
3233 uint8_t type, sub_type;
d62a17ae 3234 struct ecommunity_val *eval;
3235 struct ecommunity_val eval_tmp;
996c9314 3236 struct irt_node *irt; /* import rt for l2vni */
d3135ba3 3237 struct vrf_irt_node *vrf_irt; /* import rt for l3vni */
50f74cf1 3238 struct evpnes *es;
d62a17ae 3239
3240 /* Only deal with RTs */
3241 pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
3242 eval = (struct ecommunity_val *)(ecom->val
3243 + (i * ECOMMUNITY_SIZE));
3244 type = *pnt++;
3245 sub_type = *pnt++;
3246 if (sub_type != ECOMMUNITY_ROUTE_TARGET)
3247 continue;
3248
50f74cf1 3249 /*
3250 * macip routes (type-2) are imported into VNI and VRF tables.
3251 * IMET route is imported into VNI table.
3252 * prefix routes are imported into VRF table.
523cafc4 3253 */
50f74cf1 3254 if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE ||
3255 evp->prefix.route_type == BGP_EVPN_IMET_ROUTE ||
3256 evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE) {
d62a17ae 3257
50f74cf1 3258 irt = lookup_import_rt(bgp, eval);
3259 if (irt)
3260 install_uninstall_route_in_vnis(bgp, afi, safi,
3261 evp, ri,
3262 irt->vnis,
3263 import);
3264
3265 vrf_irt = lookup_vrf_import_rt(eval);
3266 if (vrf_irt)
3267 install_uninstall_route_in_vrfs(bgp, afi, safi,
3268 evp, ri,
3269 vrf_irt->vrfs,
3270 import);
3271
3272 /* Also check for non-exact match.
3273 * In this, we mask out the AS and
3274 * only check on the local-admin sub-field.
3275 * This is to facilitate using
3276 * VNI as the RT for EBGP peering too.
3277 */
3278 irt = NULL;
3279 vrf_irt = NULL;
3280 if (type == ECOMMUNITY_ENCODE_AS
3281 || type == ECOMMUNITY_ENCODE_AS4
3282 || type == ECOMMUNITY_ENCODE_IP) {
3283 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
3284 mask_ecom_global_admin(&eval_tmp, eval);
3285 irt = lookup_import_rt(bgp, &eval_tmp);
3286 vrf_irt = lookup_vrf_import_rt(&eval_tmp);
3287 }
3288
3289 if (irt)
3290 install_uninstall_route_in_vnis(bgp, afi, safi,
3291 evp, ri,
3292 irt->vnis,
3293 import);
3294 if (vrf_irt)
3295 install_uninstall_route_in_vrfs(bgp, afi, safi,
3296 evp, ri,
3297 vrf_irt->vrfs,
3298 import);
3299 }
3300
3301 /* es route is imported into the es table */
3302 if (evp->prefix.route_type == BGP_EVPN_ES_ROUTE) {
3303
3304 /* we will match based on the entire esi to avoid
3305 * imoort of an es route for esi2 into esi1
3306 */
3307 es = bgp_evpn_lookup_es(bgp, &evp->prefix.es_addr.esi);
3308 if (es && is_es_local(es))
3309 install_uninstall_route_in_es(bgp, es,
3310 afi, safi,
3311 evp, ri, import);
d62a17ae 3312 }
d62a17ae 3313 }
3314
3315 return 0;
128ea8ab 3316}
3317
2bb9eff4
DS
3318/*
3319 * delete and withdraw all ipv4 and ipv6 routes in the vrf table as type-5
3320 * routes
3321 */
80b140af
MK
3322static void delete_withdraw_vrf_routes(struct bgp *bgp_vrf)
3323{
3324 /* delete all ipv4 routes and withdraw from peers */
fdf19f06
MK
3325 if (advertise_type5_routes(bgp_vrf, AFI_IP))
3326 bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
80b140af
MK
3327
3328 /* delete all ipv6 routes and withdraw from peers */
fdf19f06
MK
3329 if (advertise_type5_routes(bgp_vrf, AFI_IP6))
3330 bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
80b140af
MK
3331}
3332
2bb9eff4
DS
3333/*
3334 * update and advertise all ipv4 and ipv6 routes in thr vrf table as type-5
3335 * routes
3336 */
80b140af
MK
3337static void update_advertise_vrf_routes(struct bgp *bgp_vrf)
3338{
3339 /* update all ipv4 routes */
fdf19f06
MK
3340 if (advertise_type5_routes(bgp_vrf, AFI_IP))
3341 bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
80b140af
MK
3342
3343 /* update all ipv6 routes */
fdf19f06
MK
3344 if (advertise_type5_routes(bgp_vrf, AFI_IP6))
3345 bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
80b140af
MK
3346}
3347
676f83b9 3348/*
3349 * update and advertise local routes for a VRF as type-5 routes.
3350 * This is invoked upon RD change for a VRF. Note taht the processing is only
3351 * done in the global route table using the routes which already exist in the
3352 * VRF routing table
3353 */
80b140af 3354static void update_router_id_vrf(struct bgp *bgp_vrf)
676f83b9 3355{
80b140af
MK
3356 /* skip if the RD is configured */
3357 if (is_vrf_rd_configured(bgp_vrf))
3358 return;
3359
3360 /* derive the RD for the VRF based on new router-id */
3361 bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf);
3362
3363 /* update advertise ipv4|ipv6 routes as type-5 routes */
3364 update_advertise_vrf_routes(bgp_vrf);
676f83b9 3365}
3366
3367/*
3368 * Delete and withdraw all type-5 routes for the RD corresponding to VRF.
3369 * This is invoked upon VRF RD change. The processing is done only from global
3370 * table.
3371 */
80b140af 3372static void withdraw_router_id_vrf(struct bgp *bgp_vrf)
676f83b9 3373{
80b140af
MK
3374 /* skip if the RD is configured */
3375 if (is_vrf_rd_configured(bgp_vrf))
3376 return;
3377
3378 /* delete/withdraw ipv4|ipv6 routes as type-5 routes */
3379 delete_withdraw_vrf_routes(bgp_vrf);
676f83b9 3380}
3381
90e60aa7 3382/*
3383 * Update and advertise local routes for a VNI. Invoked upon router-id
3384 * change. Note that the processing is done only on the global route table
3385 * using routes that already exist in the per-VNI table.
3386 */
d62a17ae 3387static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
3388{
3389 struct prefix_evpn p;
3390 struct bgp_node *rn, *global_rn;
3391 struct bgp_info *ri, *global_ri;
3392 struct attr *attr;
3393 afi_t afi = AFI_L2VPN;
3394 safi_t safi = SAFI_EVPN;
3395
3396 /* Locate type-3 route for VNI in the per-VNI table and use its
3397 * attributes to create and advertise the type-3 route for this VNI
3398 * in the global table.
3399 */
3400 build_evpn_type3_prefix(&p, vpn->originator_ip);
3401 rn = bgp_node_lookup(vpn->route_table, (struct prefix *)&p);
3402 if (!rn) /* unexpected */
3403 return 0;
3404 for (ri = rn->info; ri; ri = ri->next)
3405 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
3406 && ri->sub_type == BGP_ROUTE_STATIC)
3407 break;
3408 if (!ri) /* unexpected */
3409 return 0;
3410 attr = ri->attr;
3411
3412 global_rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
3413 (struct prefix *)&p, &vpn->prd);
1a98c087
MK
3414 update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1, 0, &ri,
3415 0);
d62a17ae 3416
3417 /* Schedule for processing and unlock node. */
3418 bgp_process(bgp, global_rn, afi, safi);
3419 bgp_unlock_node(global_rn);
3420
3421 /* Now, walk this VNI's route table and use the route and its attribute
3422 * to create and schedule route in global table.
3423 */
3424 for (rn = bgp_table_top(vpn->route_table); rn;
3425 rn = bgp_route_next(rn)) {
3426 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
3427
3428 /* Identify MAC-IP local routes. */
3429 if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
3430 continue;
3431
3432 for (ri = rn->info; ri; ri = ri->next)
3433 if (ri->peer == bgp->peer_self
3434 && ri->type == ZEBRA_ROUTE_BGP
3435 && ri->sub_type == BGP_ROUTE_STATIC)
3436 break;
3437 if (!ri)
3438 continue;
3439
3440 /* Create route in global routing table using this route entry's
3441 * attribute.
3442 */
3443 attr = ri->attr;
3444 global_rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
3445 (struct prefix *)evp, &vpn->prd);
3446 assert(global_rn);
3447 update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1,
1a98c087 3448 0, &global_ri, 0);
d62a17ae 3449
3450 /* Schedule for processing and unlock node. */
3451 bgp_process(bgp, global_rn, afi, safi);
3452 bgp_unlock_node(global_rn);
3453 }
3454
3455 return 0;
90e60aa7 3456}
3457
3458/*
3459 * Delete (and withdraw) local routes for a VNI - only from the global
3460 * table. Invoked upon router-id change.
3461 */
d62a17ae 3462static int delete_withdraw_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 3463{
d62a17ae 3464 int ret;
3465 struct prefix_evpn p;
3466 struct bgp_node *global_rn;
3467 struct bgp_info *ri;
3468 afi_t afi = AFI_L2VPN;
3469 safi_t safi = SAFI_EVPN;
90e60aa7 3470
d62a17ae 3471 /* Delete and withdraw locally learnt type-2 routes (MACIP)
3472 * for this VNI - from the global table.
3473 */
3474 ret = delete_global_type2_routes(bgp, vpn);
3475 if (ret)
3476 return ret;
90e60aa7 3477
d62a17ae 3478 /* Remove type-3 route for this VNI from global table. */
3479 build_evpn_type3_prefix(&p, vpn->originator_ip);
3480 global_rn = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi,
3481 (struct prefix *)&p, &vpn->prd);
3482 if (global_rn) {
3483 /* Delete route entry in the global EVPN table. */
50f74cf1 3484 delete_evpn_route_entry(bgp, afi, safi, global_rn, &ri);
90e60aa7 3485
d62a17ae 3486 /* Schedule for processing - withdraws to peers happen from
3487 * this table.
3488 */
3489 if (ri)
3490 bgp_process(bgp, global_rn, afi, safi);
3491 bgp_unlock_node(global_rn);
3492 }
90e60aa7 3493
d62a17ae 3494 return 0;
90e60aa7 3495}
3496
2d48ee25 3497/*
3498 * Handle router-id change. Update and advertise local routes corresponding
3499 * to this VNI from peers. Note that this is invoked after updating the
3500 * router-id. The routes in the per-VNI table are used to create routes in
3501 * the global table and schedule them.
3502 */
d62a17ae 3503static void update_router_id_vni(struct hash_backet *backet, struct bgp *bgp)
2d48ee25 3504{
d62a17ae 3505 struct bgpevpn *vpn;
2d48ee25 3506
d62a17ae 3507 vpn = (struct bgpevpn *)backet->data;
2d48ee25 3508
d62a17ae 3509 if (!vpn) {
3510 zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__);
3511 return;
3512 }
2d48ee25 3513
d62a17ae 3514 /* Skip VNIs with configured RD. */
3515 if (is_rd_configured(vpn))
3516 return;
2d48ee25 3517
d62a17ae 3518 bgp_evpn_derive_auto_rd(bgp, vpn);
3519 update_advertise_vni_routes(bgp, vpn);
2d48ee25 3520}
3521
3522/*
3523 * Handle router-id change. Delete and withdraw local routes corresponding
3524 * to this VNI from peers. Note that this is invoked prior to updating
3525 * the router-id and is done only on the global route table, the routes
3526 * are needed in the per-VNI table to re-advertise with new router id.
3527 */
d62a17ae 3528static void withdraw_router_id_vni(struct hash_backet *backet, struct bgp *bgp)
2d48ee25 3529{
d62a17ae 3530 struct bgpevpn *vpn;
2d48ee25 3531
d62a17ae 3532 vpn = (struct bgpevpn *)backet->data;
2d48ee25 3533
d62a17ae 3534 if (!vpn) {
3535 zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__);
3536 return;
3537 }
2d48ee25 3538
d62a17ae 3539 /* Skip VNIs with configured RD. */
3540 if (is_rd_configured(vpn))
3541 return;
2d48ee25 3542
d62a17ae 3543 delete_withdraw_vni_routes(bgp, vpn);
2d48ee25 3544}
3545
128ea8ab 3546/*
3547 * Process received EVPN type-2 route (advertise or withdraw).
3548 */
d62a17ae 3549static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
d7c0a89a
QY
3550 struct attr *attr, uint8_t *pfx, int psize,
3551 uint32_t addpath_id)
d62a17ae 3552{
3553 struct prefix_rd prd;
3554 struct prefix_evpn p;
554cd77a 3555 struct bgp_route_evpn evpn;
d7c0a89a
QY
3556 uint8_t ipaddr_len;
3557 uint8_t macaddr_len;
b57ba6d2 3558 mpls_label_t label[BGP_MAX_LABELS]; /* holds the VNI(s) as in packet */
d7c0a89a 3559 uint32_t num_labels = 0;
554cd77a 3560 uint32_t eth_tag;
d62a17ae 3561 int ret;
3562
3563 /* Type-2 route should be either 33, 37 or 49 bytes or an
3564 * additional 3 bytes if there is a second label (VNI):
3565 * RD (8), ESI (10), Eth Tag (4), MAC Addr Len (1),
3566 * MAC Addr (6), IP len (1), IP (0, 4 or 16),
3567 * MPLS Lbl1 (3), MPLS Lbl2 (0 or 3)
3568 */
3569 if (psize != 33 && psize != 37 && psize != 49 && psize != 36
3570 && psize != 40 && psize != 52) {
3571 zlog_err("%u:%s - Rx EVPN Type-2 NLRI with invalid length %d",
3572 peer->bgp->vrf_id, peer->host, psize);
3573 return -1;
3574 }
3575
554cd77a
VB
3576 memset(&evpn, 0, sizeof(evpn));
3577
d62a17ae 3578 /* Make prefix_rd */
3579 prd.family = AF_UNSPEC;
3580 prd.prefixlen = 64;
3581 memcpy(&prd.val, pfx, 8);
3582 pfx += 8;
3583
3584 /* Make EVPN prefix. */
3585 memset(&p, 0, sizeof(struct prefix_evpn));
b03b8898 3586 p.family = AF_EVPN;
50f74cf1 3587 p.prefixlen = EVPN_ROUTE_PREFIXLEN;
d62a17ae 3588 p.prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
3589
554cd77a
VB
3590 /* Copy Ethernet Seg Identifier */
3591 memcpy(&evpn.eth_s_id.val, pfx, ESI_LEN);
3592 pfx += ESI_LEN;
d62a17ae 3593
554cd77a
VB
3594 /* Copy Ethernet Tag */
3595 memcpy(&eth_tag, pfx, 4);
3714a385 3596 p.prefix.macip_addr.eth_tag = ntohl(eth_tag);
d62a17ae 3597 pfx += 4;
3598
3599 /* Get the MAC Addr len */
3600 macaddr_len = *pfx++;
3601
3602 /* Get the MAC Addr */
28328ea9 3603 if (macaddr_len == (ETH_ALEN * 8)) {
3714a385 3604 memcpy(&p.prefix.macip_addr.mac.octet, pfx, ETH_ALEN);
28328ea9 3605 pfx += ETH_ALEN;
d62a17ae 3606 } else {
3607 zlog_err(
3608 "%u:%s - Rx EVPN Type-2 NLRI with unsupported MAC address length %d",
3609 peer->bgp->vrf_id, peer->host, macaddr_len);
3610 return -1;
3611 }
3612
3613
3614 /* Get the IP. */
3615 ipaddr_len = *pfx++;
3616 if (ipaddr_len != 0 && ipaddr_len != IPV4_MAX_BITLEN
3617 && ipaddr_len != IPV6_MAX_BITLEN) {
3618 zlog_err(
3619 "%u:%s - Rx EVPN Type-2 NLRI with unsupported IP address length %d",
3620 peer->bgp->vrf_id, peer->host, ipaddr_len);
3621 return -1;
3622 }
3623
3624 if (ipaddr_len) {
3625 ipaddr_len /= 8; /* Convert to bytes. */
3714a385 3626 p.prefix.macip_addr.ip.ipa_type = (ipaddr_len == IPV4_MAX_BYTELEN)
d62a17ae 3627 ? IPADDR_V4
3628 : IPADDR_V6;
3714a385 3629 memcpy(&p.prefix.macip_addr.ip.ip.addr, pfx, ipaddr_len);
d62a17ae 3630 }
3631 pfx += ipaddr_len;
3632
b57ba6d2
MK
3633 /* Get the VNI(s). Stored as bytes here. */
3634 num_labels++;
3635 memset(label, 0, sizeof(label));
3636 memcpy(&label[0], pfx, BGP_LABEL_BYTES);
1b817c78 3637 pfx += BGP_LABEL_BYTES;
b57ba6d2
MK
3638 psize -= (33 + ipaddr_len);
3639 /* Do we have a second VNI? */
3640 if (psize) {
3641 num_labels++;
3642 memcpy(&label[1], pfx, BGP_LABEL_BYTES);
6b11bd8d 3643 /*
3644 * If in future, we are required to access additional fields,
996c9314
LB
3645 * we MUST increment pfx by BGP_LABEL_BYTES in before reading
3646 * the next field
6b11bd8d 3647 */
b57ba6d2 3648 }
d62a17ae 3649
3650 /* Process the route. */
3651 if (attr)
3652 ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
3653 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
554cd77a 3654 &prd, &label[0], num_labels, 0, &evpn);
d62a17ae 3655 else
3656 ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
3657 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
554cd77a 3658 &prd, &label[0], num_labels, &evpn);
d62a17ae 3659 return ret;
128ea8ab 3660}
3661
3662/*
3663 * Process received EVPN type-3 route (advertise or withdraw).
3664 */
d62a17ae 3665static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,
d7c0a89a
QY
3666 struct attr *attr, uint8_t *pfx, int psize,
3667 uint32_t addpath_id)
d62a17ae 3668{
3669 struct prefix_rd prd;
3670 struct prefix_evpn p;
d7c0a89a 3671 uint8_t ipaddr_len;
554cd77a 3672 uint32_t eth_tag;
d62a17ae 3673 int ret;
3674
3675 /* Type-3 route should be either 17 or 29 bytes: RD (8), Eth Tag (4),
3676 * IP len (1) and IP (4 or 16).
3677 */
3678 if (psize != 17 && psize != 29) {
3679 zlog_err("%u:%s - Rx EVPN Type-3 NLRI with invalid length %d",
3680 peer->bgp->vrf_id, peer->host, psize);
3681 return -1;
3682 }
3683
7fd077aa 3684 /* If PMSI is present, log if it is anything other than IR.
3685 * Note: We just simply ignore the values as it is not clear if
3686 * doing anything else is better.
3687 */
3688 if (attr &&
3689 (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) {
3690 if (attr->pmsi_tnl_type != PMSI_TNLTYPE_INGR_REPL) {
d0be47e8 3691 zlog_warn("%u:%s - Rx EVPN Type-3 NLRI with unsupported PTA %d",
7fd077aa 3692 peer->bgp->vrf_id, peer->host,
3693 attr->pmsi_tnl_type);
3694 }
3695 }
3696
d62a17ae 3697 /* Make prefix_rd */
3698 prd.family = AF_UNSPEC;
3699 prd.prefixlen = 64;
3700 memcpy(&prd.val, pfx, 8);
3701 pfx += 8;
3702
3703 /* Make EVPN prefix. */
3704 memset(&p, 0, sizeof(struct prefix_evpn));
b03b8898 3705 p.family = AF_EVPN;
50f74cf1 3706 p.prefixlen = EVPN_ROUTE_PREFIXLEN;
d62a17ae 3707 p.prefix.route_type = BGP_EVPN_IMET_ROUTE;
3708
554cd77a
VB
3709 /* Copy Ethernet Tag */
3710 memcpy(&eth_tag, pfx, 4);
3714a385 3711 p.prefix.imet_addr.eth_tag = ntohl(eth_tag);
d62a17ae 3712 pfx += 4;
3713
3714 /* Get the IP. */
3715 ipaddr_len = *pfx++;
3716 if (ipaddr_len == IPV4_MAX_BITLEN) {
3714a385 3717 p.prefix.imet_addr.ip.ipa_type = IPADDR_V4;
3718 memcpy(&p.prefix.imet_addr.ip.ip.addr, pfx, IPV4_MAX_BYTELEN);
d62a17ae 3719 } else {
3720 zlog_err(
3721 "%u:%s - Rx EVPN Type-3 NLRI with unsupported IP address length %d",
3722 peer->bgp->vrf_id, peer->host, ipaddr_len);
3723 return -1;
3724 }
3725
3726 /* Process the route. */
3727 if (attr)
3728 ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
3729 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
b57ba6d2 3730 &prd, NULL, 0, 0, NULL);
d62a17ae 3731 else
3732 ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
3733 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
b57ba6d2 3734 &prd, NULL, 0, NULL);
d62a17ae 3735 return ret;
128ea8ab 3736}
3737
50f74cf1 3738/*
3739 * Process received EVPN type-4 route (advertise or withdraw).
3740 */
3741static int process_type4_route(struct peer *peer, afi_t afi, safi_t safi,
3742 struct attr *attr, uint8_t *pfx, int psize,
3743 uint32_t addpath_id)
3744{
3745 int ret;
3746 esi_t esi;
3747 uint8_t ipaddr_len;
3748 struct in_addr vtep_ip;
3749 struct prefix_rd prd;
3750 struct prefix_evpn p;
3751
3752 /* Type-4 route should be either 23 or 35 bytes
3753 * RD (8), ESI (10), ip-len (1), ip (4 or 16)
3754 */
3755 if (psize != 23 && psize != 35) {
3756 zlog_err("%u:%s - Rx EVPN Type-4 NLRI with invalid length %d",
3757 peer->bgp->vrf_id, peer->host, psize);
3758 return -1;
3759 }
3760
3761 /* Make prefix_rd */
3762 prd.family = AF_UNSPEC;
3763 prd.prefixlen = 64;
3764 memcpy(&prd.val, pfx, 8);
3765 pfx += 8;
3766
3767 /* get the ESI */
3768 memcpy(&esi, pfx, ESI_BYTES);
3769 pfx += ESI_BYTES;
3770
3771
3772 /* Get the IP. */
3773 ipaddr_len = *pfx++;
3774 if (ipaddr_len == IPV4_MAX_BITLEN) {
3775 memcpy(&vtep_ip, pfx, IPV4_MAX_BYTELEN);
3776 } else {
3777 zlog_err(
3778 "%u:%s - Rx EVPN Type-4 NLRI with unsupported IP address length %d",
3779 peer->bgp->vrf_id, peer->host, ipaddr_len);
3780 return -1;
3781 }
3782
3783 build_evpn_type4_prefix(&p, &esi, vtep_ip);
3784 /* Process the route. */
3785 if (attr) {
3786 ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
3787 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
3788 &prd, NULL, 0, 0, NULL);
2bb9eff4 3789 } else {
50f74cf1 3790 ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
3791 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
3792 &prd, NULL, 0, NULL);
3793 }
3794 return ret;
3795}
3796
3797
128ea8ab 3798/*
3799 * Process received EVPN type-5 route (advertise or withdraw).
3800 */
d62a17ae 3801static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
d7c0a89a
QY
3802 struct attr *attr, uint8_t *pfx, int psize,
3803 uint32_t addpath_id, int withdraw)
d62a17ae 3804{
3805 struct prefix_rd prd;
3806 struct prefix_evpn p;
3807 struct bgp_route_evpn evpn;
d7c0a89a
QY
3808 uint8_t ippfx_len;
3809 uint32_t eth_tag;
b57ba6d2 3810 mpls_label_t label; /* holds the VNI as in the packet */
d62a17ae 3811 int ret;
3812
3813 /* Type-5 route should be 34 or 58 bytes:
3814 * RD (8), ESI (10), Eth Tag (4), IP len (1), IP (4 or 16),
3815 * GW (4 or 16) and VNI (3).
3816 * Note that the IP and GW should both be IPv4 or both IPv6.
3817 */
3818 if (psize != 34 && psize != 58) {
3819 zlog_err("%u:%s - Rx EVPN Type-5 NLRI with invalid length %d",
3820 peer->bgp->vrf_id, peer->host, psize);
3821 return -1;
3822 }
3823
3824 /* Make prefix_rd */
3825 prd.family = AF_UNSPEC;
3826 prd.prefixlen = 64;
3827 memcpy(&prd.val, pfx, 8);
3828 pfx += 8;
3829
3830 /* Make EVPN prefix. */
3831 memset(&p, 0, sizeof(struct prefix_evpn));
b03b8898 3832 p.family = AF_EVPN;
50f74cf1 3833 p.prefixlen = EVPN_ROUTE_PREFIXLEN;
d62a17ae 3834 p.prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE;
3835
3836 /* Additional information outside of prefix - ESI and GW IP */
3837 memset(&evpn, 0, sizeof(evpn));
3838
3839 /* Fetch ESI */
3840 memcpy(&evpn.eth_s_id.val, pfx, 10);
3841 pfx += 10;
3842
3843 /* Fetch Ethernet Tag. */
3844 memcpy(&eth_tag, pfx, 4);
3714a385 3845 p.prefix.prefix_addr.eth_tag = ntohl(eth_tag);
d62a17ae 3846 pfx += 4;
3847
3848 /* Fetch IP prefix length. */
3849 ippfx_len = *pfx++;
3850 if (ippfx_len > IPV6_MAX_BITLEN) {
3851 zlog_err(
3852 "%u:%s - Rx EVPN Type-5 NLRI with invalid IP Prefix length %d",
3853 peer->bgp->vrf_id, peer->host, ippfx_len);
3854 return -1;
3855 }
3714a385 3856 p.prefix.prefix_addr.ip_prefix_length = ippfx_len;
d62a17ae 3857
3858 /* Determine IPv4 or IPv6 prefix */
3859 /* Since the address and GW are from the same family, this just becomes
3860 * a simple check on the total size.
3861 */
3862 if (psize == 34) {
3714a385 3863 SET_IPADDR_V4(&p.prefix.prefix_addr.ip);
3864 memcpy(&p.prefix.prefix_addr.ip.ipaddr_v4, pfx, 4);
d62a17ae 3865 pfx += 4;
3866 memcpy(&evpn.gw_ip.ipv4, pfx, 4);
3867 pfx += 4;
d62a17ae 3868 } else {
3714a385 3869 SET_IPADDR_V6(&p.prefix.prefix_addr.ip);
3870 memcpy(&p.prefix.prefix_addr.ip.ipaddr_v6, pfx, 16);
d62a17ae 3871 pfx += 16;
3872 memcpy(&evpn.gw_ip.ipv6, pfx, 16);
3873 pfx += 16;
d62a17ae 3874 }
3875
b57ba6d2
MK
3876 /* Get the VNI (in MPLS label field). Stored as bytes here. */
3877 memset(&label, 0, sizeof(label));
3878 memcpy(&label, pfx, BGP_LABEL_BYTES);
6b11bd8d 3879
3880 /*
3881 * If in future, we are required to access additional fields,
996c9314
LB
3882 * we MUST increment pfx by BGP_LABEL_BYTES in before reading the next
3883 * field
6b11bd8d 3884 */
d62a17ae 3885
3886 /* Process the route. */
3887 if (!withdraw)
3888 ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
3889 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
b57ba6d2 3890 &prd, &label, 1, 0, &evpn);
d62a17ae 3891 else
3892 ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
3893 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
b57ba6d2 3894 &prd, &label, 1, &evpn);
d62a17ae 3895
3896 return ret;
3897}
3898
3899static void evpn_mpattr_encode_type5(struct stream *s, struct prefix *p,
996c9314 3900 struct prefix_rd *prd, mpls_label_t *label,
d7c0a89a 3901 uint32_t num_labels, struct attr *attr)
d62a17ae 3902{
3903 int len;
3904 char temp[16];
3905 struct evpn_addr *p_evpn_p;
3906
3907 memset(&temp, 0, 16);
b03b8898 3908 if (p->family != AF_EVPN)
d62a17ae 3909 return;
3910 p_evpn_p = &(p->u.prefix_evpn);
3911
e9fc2840 3912 /* len denites the total len of IP and GW-IP in the route
523cafc4 3913 IP and GW-IP have to be both ipv4 or ipv6
3914 */
3714a385 3915 if (IS_IPADDR_V4(&p_evpn_p->prefix_addr.ip))
e9fc2840 3916 len = 8; /* IP and GWIP are both ipv4 */
d62a17ae 3917 else
e9fc2840 3918 len = 32; /* IP and GWIP are both ipv6 */
d62a17ae 3919 /* Prefix contains RD, ESI, EthTag, IP length, IP, GWIP and VNI */
3920 stream_putc(s, 8 + 10 + 4 + 1 + len + 3);
3921 stream_put(s, prd->val, 8);
0af35d90 3922 if (attr)
d62a17ae 3923 stream_put(s, &(attr->evpn_overlay.eth_s_id), 10);
3924 else
3925 stream_put(s, &temp, 10);
3714a385 3926 stream_putl(s, p_evpn_p->prefix_addr.eth_tag);
3927 stream_putc(s, p_evpn_p->prefix_addr.ip_prefix_length);
3928 if (IS_IPADDR_V4(&p_evpn_p->prefix_addr.ip))
3929 stream_put_ipv4(s, p_evpn_p->prefix_addr.ip.ipaddr_v4.s_addr);
d62a17ae 3930 else
3714a385 3931 stream_put(s, &p_evpn_p->prefix_addr.ip.ipaddr_v6, 16);
0af35d90 3932 if (attr) {
3714a385 3933 if (IS_IPADDR_V4(&p_evpn_p->prefix_addr.ip))
d62a17ae 3934 stream_put_ipv4(s,
3935 attr->evpn_overlay.gw_ip.ipv4.s_addr);
3936 else
3937 stream_put(s, &(attr->evpn_overlay.gw_ip.ipv6), 16);
3938 } else {
3714a385 3939 if (IS_IPADDR_V4(&p_evpn_p->prefix_addr.ip))
d62a17ae 3940 stream_put_ipv4(s, 0);
3941 else
3942 stream_put(s, &temp, 16);
3943 }
3944
b57ba6d2 3945 if (num_labels)
d62a17ae 3946 stream_put(s, label, 3);
3947 else
3948 stream_put3(s, 0);
128ea8ab 3949}
3950
3951/*
3952 * Cleanup specific VNI upon EVPN (advertise-all-vni) being disabled.
3953 */
d62a17ae 3954static void cleanup_vni_on_disable(struct hash_backet *backet, struct bgp *bgp)
128ea8ab 3955{
d62a17ae 3956 struct bgpevpn *vpn = (struct bgpevpn *)backet->data;
128ea8ab 3957
d62a17ae 3958 /* Remove EVPN routes and schedule for processing. */
3959 delete_routes_for_vni(bgp, vpn);
128ea8ab 3960
d62a17ae 3961 /* Clear "live" flag and see if hash needs to be freed. */
3962 UNSET_FLAG(vpn->flags, VNI_FLAG_LIVE);
3963 if (!is_vni_configured(vpn))
3964 bgp_evpn_free(bgp, vpn);
128ea8ab 3965}
3966
3967/*
3968 * Free a VNI entry; iterator function called during cleanup.
3969 */
d62a17ae 3970static void free_vni_entry(struct hash_backet *backet, struct bgp *bgp)
128ea8ab 3971{
d62a17ae 3972 struct bgpevpn *vpn;
128ea8ab 3973
d62a17ae 3974 vpn = (struct bgpevpn *)backet->data;
3975 delete_all_vni_routes(bgp, vpn);
3976 bgp_evpn_free(bgp, vpn);
128ea8ab 3977}
3978
c581d8b0
MK
3979/*
3980 * Derive AUTO import RT for BGP VRF - L3VNI
3981 */
3982static void evpn_auto_rt_import_add_for_vrf(struct bgp *bgp_vrf)
3983{
10ebe1ab
MK
3984 struct bgp *bgp_def = NULL;
3985
c581d8b0 3986 form_auto_rt(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_import_rtl);
10ebe1ab
MK
3987 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD);
3988
3989 /* Map RT to VRF */
3990 bgp_def = bgp_get_default();
3991 if (!bgp_def)
3992 return;
3993 bgp_evpn_map_vrf_to_its_rts(bgp_vrf);
c581d8b0
MK
3994}
3995
3996/*
3997 * Delete AUTO import RT from BGP VRF - L3VNI
3998 */
3999static void evpn_auto_rt_import_delete_for_vrf(struct bgp *bgp_vrf)
4000{
4001 evpn_rt_delete_auto(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_import_rtl);
4002}
4003
4004/*
4005 * Derive AUTO export RT for BGP VRF - L3VNI
4006 */
4007static void evpn_auto_rt_export_add_for_vrf(struct bgp *bgp_vrf)
4008{
4009 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD);
4010 form_auto_rt(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_export_rtl);
4011}
4012
4013/*
4014 * Delete AUTO export RT from BGP VRF - L3VNI
4015 */
4016static void evpn_auto_rt_export_delete_for_vrf(struct bgp *bgp_vrf)
4017{
4018 evpn_rt_delete_auto(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_export_rtl);
4019}
128ea8ab 4020
f1f8b53c
MK
4021static void bgp_evpn_handle_export_rt_change_for_vrf(struct bgp *bgp_vrf)
4022{
4023 struct bgp *bgp_def = NULL;
4024 struct listnode *node = NULL;
4025 struct bgpevpn *vpn = NULL;
4026
4027 bgp_def = bgp_get_default();
4028 if (!bgp_def)
4029 return;
4030
4992b4ae
MK
4031 /* update all type-5 routes */
4032 update_advertise_vrf_routes(bgp_vrf);
4033
4034 /* update all type-2 routes */
f1f8b53c
MK
4035 for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn))
4036 update_routes_for_vni(bgp_def, vpn);
4037}
4038
bf1061d8
VB
4039/*
4040 * Handle autort change for a given VNI.
4041 */
4042static void update_autort_vni(struct hash_backet *backet, struct bgp *bgp)
4043{
4044 struct bgpevpn *vpn = backet->data;
bf1061d8
VB
4045
4046 if (!vpn) {
4047 zlog_warn("%s: VNI hash entry for VNI not found", __PRETTY_FUNCTION__);
4048 return;
4049 }
4050
4051 if (!is_import_rt_configured(vpn)) {
4052 if (is_vni_live(vpn))
4053 bgp_evpn_uninstall_routes(bgp, vpn);
4054 bgp_evpn_unmap_vni_from_its_rts(bgp, vpn);
bf1061d8
VB
4055 list_delete_all_node(vpn->import_rtl);
4056 bgp_evpn_derive_auto_rt_import(bgp, vpn);
4057 if (is_vni_live(vpn))
4058 bgp_evpn_install_routes(bgp, vpn);
4059 }
4060 if (!is_export_rt_configured(vpn)) {
bf1061d8
VB
4061 list_delete_all_node(vpn->export_rtl);
4062 bgp_evpn_derive_auto_rt_export(bgp, vpn);
4063 if (is_vni_live(vpn))
4064 bgp_evpn_handle_export_rt_change(bgp, vpn);
4065 }
4066}
4067
128ea8ab 4068/*
4069 * Public functions.
4070 */
4071
5424b7ba 4072/* withdraw type-5 route corresponding to ip prefix */
31310b25 4073void bgp_evpn_withdraw_type5_route(struct bgp *bgp_vrf, struct prefix *p,
5424b7ba
MK
4074 afi_t afi, safi_t safi)
4075{
4076 int ret = 0;
4077 struct prefix_evpn evp;
4078 char buf[PREFIX_STRLEN];
4079
31310b25 4080 build_type5_prefix_from_ip_prefix(&evp, p);
5424b7ba
MK
4081 ret = delete_evpn_type5_route(bgp_vrf, &evp);
4082 if (ret) {
4083 zlog_err(
996c9314
LB
4084 "%u failed to delete type-5 route for prefix %s in vrf %s",
4085 bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf)),
4086 vrf_id_to_name(bgp_vrf->vrf_id));
5424b7ba
MK
4087 }
4088}
4089
342dd0c6 4090/* withdraw all type-5 routes for an address family */
996c9314 4091void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, afi_t afi, safi_t safi)
342dd0c6 4092{
4093 struct bgp_table *table = NULL;
4094 struct bgp_node *rn = NULL;
25f2ca53 4095 struct bgp_info *ri;
342dd0c6 4096
053905d2 4097 table = bgp_vrf->rib[afi][safi];
25f2ca53 4098 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
4099 /* Only care about "selected" routes - non-imported. */
4100 /* TODO: Support for AddPath for EVPN. */
4101 for (ri = rn->info; ri; ri = ri->next) {
996c9314
LB
4102 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)
4103 && (!ri->extra || !ri->extra->parent)) {
25f2ca53 4104 bgp_evpn_withdraw_type5_route(bgp_vrf, &rn->p,
4105 afi, safi);
4106 break;
4107 }
4108 }
4109 }
5424b7ba 4110}
342dd0c6 4111
2f69f6d3 4112/*
4113 * Advertise IP prefix as type-5 route. The afi/safi and src_attr passed
4114 * to this function correspond to those of the source IP prefix (best
4115 * path in the case of the attr. In the case of a local prefix (when we
4116 * are advertising local subnets), the src_attr will be NULL.
4117 */
31310b25 4118void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p,
996c9314
LB
4119 struct attr *src_attr, afi_t afi,
4120 safi_t safi)
5424b7ba
MK
4121{
4122 int ret = 0;
4123 struct prefix_evpn evp;
4124 char buf[PREFIX_STRLEN];
7c82b312 4125
31310b25 4126 build_type5_prefix_from_ip_prefix(&evp, p);
2f69f6d3 4127 ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr);
4128 if (ret)
996c9314
LB
4129 zlog_err("%u: Failed to create type-5 route for prefix %s",
4130 bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf)));
342dd0c6 4131}
4132
2f69f6d3 4133/* Inject all prefixes of a particular address-family (currently, IPv4 or
4134 * IPv6 unicast) into EVPN as type-5 routes. This is invoked when the
4135 * advertisement is enabled.
4136 */
996c9314
LB
4137void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi,
4138 safi_t safi)
342dd0c6 4139{
4140 struct bgp_table *table = NULL;
4141 struct bgp_node *rn = NULL;
2f69f6d3 4142 struct bgp_info *ri;
342dd0c6 4143
053905d2 4144 table = bgp_vrf->rib[afi][safi];
31310b25 4145 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
2f69f6d3 4146 /* Need to identify the "selected" route entry to use its
25f2ca53 4147 * attribute. Also, we only consider "non-imported" routes.
2f69f6d3 4148 * TODO: Support for AddPath for EVPN.
4149 */
4150 for (ri = rn->info; ri; ri = ri->next) {
996c9314
LB
4151 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)
4152 && (!ri->extra || !ri->extra->parent)) {
53c84f78
MK
4153
4154 /* apply the route-map */
4155 if (bgp_vrf->adv_cmd_rmap[afi][safi].map) {
4156 int ret = 0;
4157
996c9314
LB
4158 ret = route_map_apply(
4159 bgp_vrf->adv_cmd_rmap[afi][safi]
4160 .map,
4161 &rn->p, RMAP_BGP, ri);
53c84f78
MK
4162 if (ret == RMAP_DENYMATCH)
4163 continue;
4164 }
996c9314
LB
4165 bgp_evpn_advertise_type5_route(
4166 bgp_vrf, &rn->p, ri->attr, afi, safi);
2f69f6d3 4167 break;
4168 }
4169 }
31310b25 4170 }
342dd0c6 4171}
4172
996c9314 4173void evpn_rt_delete_auto(struct bgp *bgp, vni_t vni, struct list *rtl)
c581d8b0
MK
4174{
4175 struct listnode *node, *nnode, *node_to_del;
4176 struct ecommunity *ecom, *ecom_auto;
4177 struct ecommunity_val eval;
4178
bf1061d8
VB
4179 if (bgp->advertise_autort_rfc8365)
4180 vni |= EVPN_AUTORT_VXLAN;
c581d8b0
MK
4181 encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
4182
4183 ecom_auto = ecommunity_new();
4184 ecommunity_add_val(ecom_auto, &eval);
4185 node_to_del = NULL;
4186
4187 for (ALL_LIST_ELEMENTS(rtl, node, nnode, ecom)) {
4188 if (ecommunity_match(ecom, ecom_auto)) {
4189 ecommunity_free(&ecom);
4190 node_to_del = node;
4191 }
4192 }
4193
4194 if (node_to_del)
4195 list_delete_node(rtl, node_to_del);
4196
4197 ecommunity_free(&ecom_auto);
4198}
4199
4200void bgp_evpn_configure_import_rt_for_vrf(struct bgp *bgp_vrf,
10ebe1ab 4201 struct ecommunity *ecomadd)
c581d8b0 4202{
5ba238b7
MK
4203 /* uninstall routes from vrf */
4204 uninstall_routes_for_vrf(bgp_vrf);
10ebe1ab
MK
4205
4206 /* Cleanup the RT to VRF mapping */
4207 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf);
4208
c581d8b0
MK
4209 /* Remove auto generated RT */
4210 evpn_auto_rt_import_delete_for_vrf(bgp_vrf);
4211
4212 /* Add the newly configured RT to RT list */
4213 listnode_add_sort(bgp_vrf->vrf_import_rtl, ecomadd);
4214 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD);
4215
10ebe1ab
MK
4216 /* map VRF to its RTs */
4217 bgp_evpn_map_vrf_to_its_rts(bgp_vrf);
4218
5ba238b7
MK
4219 /* install routes matching the new VRF */
4220 install_routes_for_vrf(bgp_vrf);
c581d8b0
MK
4221}
4222
4223void bgp_evpn_unconfigure_import_rt_for_vrf(struct bgp *bgp_vrf,
4224 struct ecommunity *ecomdel)
4225{
4226 struct listnode *node = NULL, *nnode = NULL, *node_to_del = NULL;
4227 struct ecommunity *ecom = NULL;
4228
5ba238b7
MK
4229 /* uninstall routes from vrf */
4230 uninstall_routes_for_vrf(bgp_vrf);
10ebe1ab
MK
4231
4232 /* Cleanup the RT to VRF mapping */
4233 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf);
4234
c581d8b0
MK
4235 /* remove the RT from the RT list */
4236 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_import_rtl, node, nnode, ecom)) {
4237 if (ecommunity_match(ecom, ecomdel)) {
4238 ecommunity_free(&ecom);
4239 node_to_del = node;
4240 break;
4241 }
4242 }
4243
4244 if (node_to_del)
4245 list_delete_node(bgp_vrf->vrf_import_rtl, node_to_del);
4246
4247 /* fallback to auto import rt, if this was the last RT */
4248 if (list_isempty(bgp_vrf->vrf_import_rtl)) {
4249 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD);
4250 evpn_auto_rt_import_add_for_vrf(bgp_vrf);
4251 }
4252
10ebe1ab
MK
4253 /* map VRFs to its RTs */
4254 bgp_evpn_map_vrf_to_its_rts(bgp_vrf);
4255
5ba238b7
MK
4256 /* install routes matching this new RT */
4257 install_routes_for_vrf(bgp_vrf);
c581d8b0
MK
4258}
4259
4260void bgp_evpn_configure_export_rt_for_vrf(struct bgp *bgp_vrf,
4261 struct ecommunity *ecomadd)
4262{
4263 /* remove auto-generated RT */
4264 evpn_auto_rt_export_delete_for_vrf(bgp_vrf);
4265
4266 /* Add the new RT to the RT list */
4267 listnode_add_sort(bgp_vrf->vrf_export_rtl, ecomadd);
4268 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD);
4269
f1f8b53c 4270 bgp_evpn_handle_export_rt_change_for_vrf(bgp_vrf);
c581d8b0
MK
4271}
4272
4273void bgp_evpn_unconfigure_export_rt_for_vrf(struct bgp *bgp_vrf,
4274 struct ecommunity *ecomdel)
4275{
4276 struct listnode *node = NULL, *nnode = NULL, *node_to_del = NULL;
4277 struct ecommunity *ecom = NULL;
4278
4279 /* Remove the RT from the RT list */
4280 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_export_rtl, node, nnode, ecom)) {
4281 if (ecommunity_match(ecom, ecomdel)) {
4282 ecommunity_free(&ecom);
4283 node_to_del = node;
4284 break;
4285 }
4286 }
4287
4288 if (node_to_del)
4289 list_delete_node(bgp_vrf->vrf_export_rtl, node_to_del);
4290
4291 /* fall back to auto-generated RT if this was the last RT */
877702e7 4292 if (bgp_vrf->vrf_export_rtl && list_isempty(bgp_vrf->vrf_export_rtl)) {
c581d8b0
MK
4293 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD);
4294 evpn_auto_rt_export_add_for_vrf(bgp_vrf);
4295 }
4296
f1f8b53c 4297 bgp_evpn_handle_export_rt_change_for_vrf(bgp_vrf);
c581d8b0
MK
4298}
4299
2d48ee25 4300/*
4301 * Handle change to BGP router id. This is invoked twice by the change
4302 * handler, first before the router id has been changed and then after
4303 * the router id has been changed. The first invocation will result in
676f83b9 4304 * local routes for all VNIs/VRF being deleted and withdrawn and the next
2d48ee25 4305 * will result in the routes being re-advertised.
4306 */
d62a17ae 4307void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw)
2d48ee25 4308{
676f83b9 4309 if (withdraw) {
4310
4311 /* delete and withdraw all the type-5 routes
523cafc4 4312 stored in the global table for this vrf
4313 */
80b140af 4314 withdraw_router_id_vrf(bgp);
676f83b9 4315
4316 /* delete all the VNI routes (type-2/type-3) routes for all the
523cafc4 4317 * L2-VNIs
4318 */
d62a17ae 4319 hash_iterate(bgp->vnihash,
4320 (void (*)(struct hash_backet *,
4321 void *))withdraw_router_id_vni,
4322 bgp);
676f83b9 4323 } else {
4324
4325 /* advertise all routes in the vrf as type-5 routes with the new
523cafc4 4326 * RD
4327 */
80b140af 4328 update_router_id_vrf(bgp);
676f83b9 4329
4330 /* advertise all the VNI routes (type-2/type-3) routes with the
523cafc4 4331 * new RD
4332 */
d62a17ae 4333 hash_iterate(bgp->vnihash,
4334 (void (*)(struct hash_backet *,
4335 void *))update_router_id_vni,
4336 bgp);
676f83b9 4337 }
2d48ee25 4338}
4339
bf1061d8
VB
4340/*
4341 * Handle change to auto-RT algorithm - update and advertise local routes.
4342 */
4343void bgp_evpn_handle_autort_change(struct bgp *bgp)
4344{
4345 hash_iterate(bgp->vnihash,
4346 (void (*)(struct hash_backet *,
4347 void*))update_autort_vni,
4348 bgp);
4349}
4350
90e60aa7 4351/*
4352 * Handle change to export RT - update and advertise local routes.
4353 */
d62a17ae 4354int bgp_evpn_handle_export_rt_change(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 4355{
d62a17ae 4356 return update_routes_for_vni(bgp, vpn);
90e60aa7 4357}
4358
996c9314 4359void bgp_evpn_handle_vrf_rd_change(struct bgp *bgp_vrf, int withdraw)
676f83b9 4360{
4361 if (withdraw)
4362 delete_withdraw_vrf_routes(bgp_vrf);
4363 else
4364 update_advertise_vrf_routes(bgp_vrf);
4365}
4366
90e60aa7 4367/*
4368 * Handle change to RD. This is invoked twice by the change handler,
4369 * first before the RD has been changed and then after the RD has
4370 * been changed. The first invocation will result in local routes
4371 * of this VNI being deleted and withdrawn and the next will result
4372 * in the routes being re-advertised.
4373 */
d62a17ae 4374void bgp_evpn_handle_rd_change(struct bgp *bgp, struct bgpevpn *vpn,
4375 int withdraw)
90e60aa7 4376{
d62a17ae 4377 if (withdraw)
4378 delete_withdraw_vni_routes(bgp, vpn);
4379 else
4380 update_advertise_vni_routes(bgp, vpn);
90e60aa7 4381}
4382
4383/*
4384 * Install routes for this VNI. Invoked upon change to Import RT.
4385 */
d62a17ae 4386int bgp_evpn_install_routes(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 4387{
d62a17ae 4388 return install_routes_for_vni(bgp, vpn);
90e60aa7 4389}
4390
4391/*
4392 * Uninstall all routes installed for this VNI. Invoked upon change
4393 * to Import RT.
4394 */
d62a17ae 4395int bgp_evpn_uninstall_routes(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 4396{
d62a17ae 4397 return uninstall_routes_for_vni(bgp, vpn);
90e60aa7 4398}
4399
b16031a2 4400/*
b57ba6d2 4401 * TODO: Hardcoded for a maximum of 2 VNIs right now
b16031a2 4402 */
d7c0a89a 4403char *bgp_evpn_label2str(mpls_label_t *label, uint32_t num_labels, char *buf,
996c9314 4404 int len)
b16031a2 4405{
b57ba6d2 4406 vni_t vni1, vni2;
b16031a2 4407
b57ba6d2
MK
4408 vni1 = label2vni(label);
4409 if (num_labels == 2) {
996c9314 4410 vni2 = label2vni(label + 1);
b57ba6d2
MK
4411 snprintf(buf, len, "%u/%u", vni1, vni2);
4412 } else
4413 snprintf(buf, len, "%u", vni1);
d62a17ae 4414 return buf;
b16031a2 4415}
4416
9c92b5f7
MK
4417/*
4418 * Function to convert evpn route to json format.
4419 * NOTE: We don't use prefix2str as the output here is a bit different.
4420 */
57f7feb6 4421void bgp_evpn_route2json(struct prefix_evpn *p, json_object *json)
9c92b5f7 4422{
b682f6de 4423 char buf1[ETHER_ADDR_STRLEN];
4424 char buf2[PREFIX2STR_BUFFER];
9c92b5f7 4425
b682f6de 4426 if (!json)
4427 return;
9c92b5f7 4428
dff8f48d 4429 if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) {
b682f6de 4430 json_object_int_add(json, "routeType", p->prefix.route_type);
3714a385 4431 json_object_int_add(json, "ethTag",
4432 p->prefix.imet_addr.eth_tag);
57f7feb6 4433 json_object_int_add(json, "ipLen",
3714a385 4434 is_evpn_prefix_ipaddr_v4(p)
57f7feb6
MK
4435 ? IPV4_MAX_BITLEN
4436 : IPV6_MAX_BITLEN);
b682f6de 4437 json_object_string_add(json, "ip",
3714a385 4438 inet_ntoa(p->prefix.imet_addr.ip.ipaddr_v4));
57f7feb6 4439 } else if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
3714a385 4440 if (is_evpn_prefix_ipaddr_none(p)) {
57f7feb6
MK
4441 json_object_int_add(json, "routeType",
4442 p->prefix.route_type);
3714a385 4443 json_object_int_add(json, "ethTag",
4444 p->prefix.macip_addr.eth_tag);
57f7feb6
MK
4445 json_object_int_add(json, "macLen", 8 * ETH_ALEN);
4446 json_object_string_add(json, "mac",
3714a385 4447 prefix_mac2str(&p->prefix.macip_addr.mac,
57f7feb6
MK
4448 buf1,
4449 sizeof(buf1)));
dff8f48d 4450 } else {
d7c0a89a 4451 uint8_t family;
dff8f48d 4452
3714a385 4453 family = is_evpn_prefix_ipaddr_v4(p) ? AF_INET
57f7feb6 4454 : AF_INET6;
dff8f48d 4455
b682f6de 4456 json_object_int_add(json, "routeType",
57f7feb6 4457 p->prefix.route_type);
3714a385 4458 json_object_int_add(json, "ethTag",
4459 p->prefix.macip_addr.eth_tag);
57f7feb6 4460 json_object_int_add(json, "macLen", 8 * ETH_ALEN);
b682f6de 4461 json_object_string_add(json, "mac",
3714a385 4462 prefix_mac2str(&p->prefix.macip_addr.mac,
57f7feb6
MK
4463 buf1,
4464 sizeof(buf1)));
b682f6de 4465 json_object_int_add(json, "ipLen",
3714a385 4466 is_evpn_prefix_ipaddr_v4(p)
57f7feb6
MK
4467 ? IPV4_MAX_BITLEN
4468 : IPV6_MAX_BITLEN);
4469 json_object_string_add(
4470 json, "ip",
3714a385 4471 inet_ntop(family,
4472 &p->prefix.macip_addr.ip.ip.addr,
4473 buf2,
57f7feb6 4474 PREFIX2STR_BUFFER));
dff8f48d
MK
4475 }
4476 } else {
4477 /* Currently, this is to cater to other AF_ETHERNET code. */
4478 }
9c92b5f7
MK
4479}
4480
520d5d76 4481/*
4482 * Function to convert evpn route to string.
4483 * NOTE: We don't use prefix2str as the output here is a bit different.
4484 */
d62a17ae 4485char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len)
4486{
4487 char buf1[ETHER_ADDR_STRLEN];
4488 char buf2[PREFIX2STR_BUFFER];
50f74cf1 4489 char buf3[ESI_STR_LEN];
d62a17ae 4490
4491 if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) {
554cd77a 4492 snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]", p->prefix.route_type,
3714a385 4493 p->prefix.imet_addr.eth_tag,
4494 is_evpn_prefix_ipaddr_v4(p) ? IPV4_MAX_BITLEN
d62a17ae 4495 : IPV6_MAX_BITLEN,
3714a385 4496 inet_ntoa(p->prefix.imet_addr.ip.ipaddr_v4));
d62a17ae 4497 } else if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
3714a385 4498 if (is_evpn_prefix_ipaddr_none(p))
554cd77a
VB
4499 snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]",
4500 p->prefix.route_type,
3714a385 4501 p->prefix.macip_addr.eth_tag,
554cd77a 4502 8 * ETH_ALEN,
3714a385 4503 prefix_mac2str(&p->prefix.macip_addr.mac, buf1,
d62a17ae 4504 sizeof(buf1)));
4505 else {
d7c0a89a 4506 uint8_t family;
d62a17ae 4507
3714a385 4508 family = is_evpn_prefix_ipaddr_v4(p) ? AF_INET
d62a17ae 4509 : AF_INET6;
554cd77a
VB
4510 snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]:[%d]:[%s]",
4511 p->prefix.route_type,
3714a385 4512 p->prefix.macip_addr.eth_tag,
554cd77a 4513 8 * ETH_ALEN,
3714a385 4514 prefix_mac2str(&p->prefix.macip_addr.mac, buf1,
d62a17ae 4515 sizeof(buf1)),
4516 family == AF_INET ? IPV4_MAX_BITLEN
4517 : IPV6_MAX_BITLEN,
3714a385 4518 inet_ntop(family,
4519 &p->prefix.macip_addr.ip.ip.addr,
4520 buf2,
d62a17ae 4521 PREFIX2STR_BUFFER));
4522 }
342dd0c6 4523 } else if (p->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE) {
554cd77a
VB
4524 snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]",
4525 p->prefix.route_type,
3714a385 4526 p->prefix.prefix_addr.eth_tag,
4527 p->prefix.prefix_addr.ip_prefix_length,
4528 is_evpn_prefix_ipaddr_v4(p)
4529 ? inet_ntoa(p->prefix.prefix_addr.ip.ipaddr_v4)
4530 : inet6_ntoa(p->prefix.prefix_addr.ip.ipaddr_v6));
50f74cf1 4531 } else if (p->prefix.route_type == BGP_EVPN_ES_ROUTE) {
4532 snprintf(buf, len, "[%d]:[%s]:[%d]:[%s]",
4533 p->prefix.route_type,
4534 esi_to_str(&p->prefix.es_addr.esi, buf3, sizeof(buf3)),
4535 is_evpn_prefix_ipaddr_v4(p) ? IPV4_MAX_BITLEN
4536 : IPV6_MAX_BITLEN,
4537 inet_ntoa(p->prefix.es_addr.ip.ipaddr_v4));
d62a17ae 4538 } else {
b03b8898 4539 /* For EVPN route types not supported yet. */
f9aa3e55
QY
4540 snprintf(buf, len, "(unsupported route type %d)",
4541 p->prefix.route_type);
d62a17ae 4542 }
4543
4544 return (buf);
520d5d76 4545}
4546
128ea8ab 4547/*
4548 * Encode EVPN prefix in Update (MP_REACH)
4549 */
d62a17ae 4550void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
996c9314 4551 struct prefix_rd *prd, mpls_label_t *label,
d7c0a89a
QY
4552 uint32_t num_labels, struct attr *attr,
4553 int addpath_encode, uint32_t addpath_tx_id)
d62a17ae 4554{
4555 struct prefix_evpn *evp = (struct prefix_evpn *)p;
b57ba6d2 4556 int len, ipa_len = 0;
d62a17ae 4557
4558 if (addpath_encode)
4559 stream_putl(s, addpath_tx_id);
4560
4561 /* Route type */
4562 stream_putc(s, evp->prefix.route_type);
4563
4564 switch (evp->prefix.route_type) {
4565 case BGP_EVPN_MAC_IP_ROUTE:
3714a385 4566 if (is_evpn_prefix_ipaddr_v4(evp))
d62a17ae 4567 ipa_len = IPV4_MAX_BYTELEN;
3714a385 4568 else if (is_evpn_prefix_ipaddr_v6(evp))
d62a17ae 4569 ipa_len = IPV6_MAX_BYTELEN;
b57ba6d2
MK
4570 /* RD, ESI, EthTag, MAC+len, IP len, [IP], 1 VNI */
4571 len = 8 + 10 + 4 + 1 + 6 + 1 + ipa_len + 3;
4572 if (ipa_len && num_labels > 1) /* There are 2 VNIs */
4573 len += 3;
4574 stream_putc(s, len);
996c9314 4575 stream_put(s, prd->val, 8); /* RD */
554cd77a
VB
4576 if (attr)
4577 stream_put(s, &attr->evpn_overlay.eth_s_id, ESI_LEN);
4578 else
4579 stream_put(s, 0, 10);
3714a385 4580 stream_putl(s, evp->prefix.macip_addr.eth_tag); /* Ethernet Tag ID */
28328ea9 4581 stream_putc(s, 8 * ETH_ALEN); /* Mac Addr Len - bits */
3714a385 4582 stream_put(s, evp->prefix.macip_addr.mac.octet, 6); /* Mac Addr */
4583 stream_putc(s, 8 * ipa_len); /* IP address Length */
4584 if (ipa_len) /* IP */
4585 stream_put(s, &evp->prefix.macip_addr.ip.ip.addr,
4586 ipa_len);
b57ba6d2
MK
4587 /* 1st label is the L2 VNI */
4588 stream_put(s, label, BGP_LABEL_BYTES);
4589 /* Include 2nd label (L3 VNI) if advertising MAC+IP */
4590 if (ipa_len && num_labels > 1)
996c9314 4591 stream_put(s, label + 1, BGP_LABEL_BYTES);
d62a17ae 4592 break;
4593
4594 case BGP_EVPN_IMET_ROUTE:
4595 stream_putc(s, 17); // TODO: length - assumes IPv4 address
4596 stream_put(s, prd->val, 8); /* RD */
3714a385 4597 stream_putl(s, evp->prefix.imet_addr.eth_tag); /* Ethernet Tag ID */
d62a17ae 4598 stream_putc(s, IPV4_MAX_BITLEN); /* IP address Length - bits */
4599 /* Originating Router's IP Addr */
3714a385 4600 stream_put_in_addr(s, &evp->prefix.imet_addr.ip.ipaddr_v4);
d62a17ae 4601 break;
4602
50f74cf1 4603 case BGP_EVPN_ES_ROUTE:
4604 stream_putc(s, 23); /* TODO: length: assumes ipv4 VTEP */
4605 stream_put(s, prd->val, 8); /* RD */
4606 stream_put(s, evp->prefix.es_addr.esi.val, 10); /* ESI */
4607 stream_putc(s, IPV4_MAX_BITLEN); /* IP address Length - bits */
2bb9eff4
DS
4608 /* VTEP IP */
4609 stream_put_in_addr(s, &evp->prefix.es_addr.ip.ipaddr_v4);
50f74cf1 4610 break;
4611
d62a17ae 4612 case BGP_EVPN_IP_PREFIX_ROUTE:
4613 /* TODO: AddPath support. */
b57ba6d2 4614 evpn_mpattr_encode_type5(s, p, prd, label, num_labels, attr);
d62a17ae 4615 break;
4616
4617 default:
4618 break;
4619 }
4620}
4621
4622int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
4623 struct bgp_nlri *packet, int withdraw)
4624{
d7c0a89a
QY
4625 uint8_t *pnt;
4626 uint8_t *lim;
d62a17ae 4627 afi_t afi;
4628 safi_t safi;
d7c0a89a 4629 uint32_t addpath_id;
d62a17ae 4630 int addpath_encoded;
4631 int psize = 0;
d7c0a89a
QY
4632 uint8_t rtype;
4633 uint8_t rlen;
d62a17ae 4634 struct prefix p;
4635
d62a17ae 4636 /* Start processing the NLRI - there may be multiple in the MP_REACH */
4637 pnt = packet->nlri;
4638 lim = pnt + packet->length;
4639 afi = packet->afi;
4640 safi = packet->safi;
4641 addpath_id = 0;
4642
4643 addpath_encoded =
4644 (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
4645 && CHECK_FLAG(peer->af_cap[afi][safi],
4646 PEER_CAP_ADDPATH_AF_TX_RCV));
4647
4648 for (; pnt < lim; pnt += psize) {
4649 /* Clear prefix structure. */
4650 memset(&p, 0, sizeof(struct prefix));
4651
4652 /* Deal with path-id if AddPath is supported. */
4653 if (addpath_encoded) {
4654 /* When packet overflow occurs return immediately. */
4655 if (pnt + BGP_ADDPATH_ID_LEN > lim)
4656 return -1;
4657
4658 addpath_id = ntohl(*((uint32_t *)pnt));
4659 pnt += BGP_ADDPATH_ID_LEN;
4660 }
4661
4662 /* All EVPN NLRI types start with type and length. */
4663 if (pnt + 2 > lim)
4664 return -1;
4665
4666 rtype = *pnt++;
4667 psize = rlen = *pnt++;
4668
4669 /* When packet overflow occur return immediately. */
4670 if (pnt + psize > lim)
4671 return -1;
4672
4673 switch (rtype) {
4674 case BGP_EVPN_MAC_IP_ROUTE:
4675 if (process_type2_route(peer, afi, safi,
4676 withdraw ? NULL : attr, pnt,
4677 psize, addpath_id)) {
4678 zlog_err(
4679 "%u:%s - Error in processing EVPN type-2 NLRI size %d",
4680 peer->bgp->vrf_id, peer->host, psize);
4681 return -1;
4682 }
4683 break;
4684
4685 case BGP_EVPN_IMET_ROUTE:
4686 if (process_type3_route(peer, afi, safi,
4687 withdraw ? NULL : attr, pnt,
4688 psize, addpath_id)) {
4689 zlog_err(
4690 "%u:%s - Error in processing EVPN type-3 NLRI size %d",
4691 peer->bgp->vrf_id, peer->host, psize);
4692 return -1;
4693 }
4694 break;
4695
50f74cf1 4696 case BGP_EVPN_ES_ROUTE:
4697 if (process_type4_route(peer, afi, safi,
4698 withdraw ? NULL : attr, pnt,
4699 psize, addpath_id)) {
4700 zlog_err(
4701 "%u:%s - Error in processing EVPN type-4 NLRI size %d",
4702 peer->bgp->vrf_id, peer->host, psize);
4703 return -1;
4704 }
4705 break;
4706
d62a17ae 4707 case BGP_EVPN_IP_PREFIX_ROUTE:
4708 if (process_type5_route(peer, afi, safi, attr, pnt,
4709 psize, addpath_id, withdraw)) {
4710 zlog_err(
4711 "%u:%s - Error in processing EVPN type-5 NLRI size %d",
4712 peer->bgp->vrf_id, peer->host, psize);
4713 return -1;
4714 }
4715 break;
4716
4717 default:
4718 break;
4719 }
4720 }
4721
4722 /* Packet length consistency check. */
4723 if (pnt != lim)
4724 return -1;
4725
4726 return 0;
128ea8ab 4727}
4728
10ebe1ab
MK
4729/*
4730 * Map the RTs (configured or automatically derived) of a VRF to the VRF.
4731 * The mapping will be used during route processing.
4732 * bgp_def: default bgp instance
4733 * bgp_vrf: specific bgp vrf instance on which RT is configured
4734 */
4735void bgp_evpn_map_vrf_to_its_rts(struct bgp *bgp_vrf)
4736{
4737 int i = 0;
4738 struct ecommunity_val *eval = NULL;
4739 struct listnode *node = NULL, *nnode = NULL;
4740 struct ecommunity *ecom = NULL;
4741
4742 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_import_rtl, node, nnode, ecom)) {
4743 for (i = 0; i < ecom->size; i++) {
4744 eval = (struct ecommunity_val *)(ecom->val
4745 + (i
4746 * ECOMMUNITY_SIZE));
4747 map_vrf_to_rt(bgp_vrf, eval);
4748 }
4749 }
4750}
4751
4752/*
4753 * Unmap the RTs (configured or automatically derived) of a VRF from the VRF.
4754 */
4755void bgp_evpn_unmap_vrf_from_its_rts(struct bgp *bgp_vrf)
4756{
4757 int i;
4758 struct ecommunity_val *eval;
4759 struct listnode *node, *nnode;
4760 struct ecommunity *ecom;
4761
4762 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_import_rtl, node, nnode, ecom)) {
4763 for (i = 0; i < ecom->size; i++) {
4764 struct vrf_irt_node *irt;
4765 struct ecommunity_val eval_tmp;
4766
4767 eval = (struct ecommunity_val *)(ecom->val
4768 + (i
4769 * ECOMMUNITY_SIZE));
4770 /* If using "automatic" RT, we only care about the
4771 * local-admin sub-field.
4772 * This is to facilitate using VNI as the RT for EBGP
4773 * peering too.
4774 */
4775 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
4776 if (!CHECK_FLAG(bgp_vrf->vrf_flags,
4777 BGP_VRF_IMPORT_RT_CFGD))
4778 mask_ecom_global_admin(&eval_tmp, eval);
4779
4780 irt = lookup_vrf_import_rt(&eval_tmp);
4781 if (irt)
4782 unmap_vrf_from_rt(bgp_vrf, irt);
4783 }
4784 }
4785}
4786
4787
128ea8ab 4788/*
4789 * Map the RTs (configured or automatically derived) of a VNI to the VNI.
4790 * The mapping will be used during route processing.
4791 */
d62a17ae 4792void bgp_evpn_map_vni_to_its_rts(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 4793{
d62a17ae 4794 int i;
4795 struct ecommunity_val *eval;
4796 struct listnode *node, *nnode;
4797 struct ecommunity *ecom;
128ea8ab 4798
d62a17ae 4799 for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
4800 for (i = 0; i < ecom->size; i++) {
4801 eval = (struct ecommunity_val *)(ecom->val
4802 + (i
4803 * ECOMMUNITY_SIZE));
4804 map_vni_to_rt(bgp, vpn, eval);
4805 }
4806 }
128ea8ab 4807}
4808
4809/*
4810 * Unmap the RTs (configured or automatically derived) of a VNI from the VNI.
4811 */
d62a17ae 4812void bgp_evpn_unmap_vni_from_its_rts(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 4813{
d62a17ae 4814 int i;
4815 struct ecommunity_val *eval;
4816 struct listnode *node, *nnode;
4817 struct ecommunity *ecom;
128ea8ab 4818
d62a17ae 4819 for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
4820 for (i = 0; i < ecom->size; i++) {
4821 struct irt_node *irt;
4822 struct ecommunity_val eval_tmp;
128ea8ab 4823
d62a17ae 4824 eval = (struct ecommunity_val *)(ecom->val
4825 + (i
4826 * ECOMMUNITY_SIZE));
4827 /* If using "automatic" RT, we only care about the
4828 * local-admin sub-field.
4829 * This is to facilitate using VNI as the RT for EBGP
4830 * peering too.
4831 */
4832 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
4833 if (!is_import_rt_configured(vpn))
4834 mask_ecom_global_admin(&eval_tmp, eval);
128ea8ab 4835
d62a17ae 4836 irt = lookup_import_rt(bgp, &eval_tmp);
4837 if (irt)
4838 unmap_vni_from_rt(bgp, vpn, irt);
4839 }
4840 }
128ea8ab 4841}
4842
4843/*
4844 * Derive Import RT automatically for VNI and map VNI to RT.
4845 * The mapping will be used during route processing.
4846 */
d62a17ae 4847void bgp_evpn_derive_auto_rt_import(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 4848{
c581d8b0 4849 form_auto_rt(bgp, vpn->vni, vpn->import_rtl);
d62a17ae 4850 UNSET_FLAG(vpn->flags, VNI_FLAG_IMPRT_CFGD);
128ea8ab 4851
d62a17ae 4852 /* Map RT to VNI */
4853 bgp_evpn_map_vni_to_its_rts(bgp, vpn);
128ea8ab 4854}
4855
4856/*
4857 * Derive Export RT automatically for VNI.
4858 */
d62a17ae 4859void bgp_evpn_derive_auto_rt_export(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 4860{
c581d8b0 4861 form_auto_rt(bgp, vpn->vni, vpn->export_rtl);
d62a17ae 4862 UNSET_FLAG(vpn->flags, VNI_FLAG_EXPRT_CFGD);
128ea8ab 4863}
4864
676f83b9 4865/*
4866 * Derive RD automatically for VNI using passed information - it
4867 * is of the form RouterId:unique-id-for-vni.
4868 */
4869void bgp_evpn_derive_auto_rd_for_vrf(struct bgp *bgp)
4870{
92708db6 4871 form_auto_rd(bgp->router_id, bgp->vrf_rd_id, &bgp->vrf_prd);
676f83b9 4872}
4873
128ea8ab 4874/*
4875 * Derive RD automatically for VNI using passed information - it
4876 * is of the form RouterId:unique-id-for-vni.
4877 */
d62a17ae 4878void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 4879{
d62a17ae 4880 char buf[100];
128ea8ab 4881
d62a17ae 4882 vpn->prd.family = AF_UNSPEC;
4883 vpn->prd.prefixlen = 64;
4884 sprintf(buf, "%s:%hu", inet_ntoa(bgp->router_id), vpn->rd_id);
cbb65f5e 4885 (void)str2prefix_rd(buf, &vpn->prd);
d62a17ae 4886 UNSET_FLAG(vpn->flags, VNI_FLAG_RD_CFGD);
128ea8ab 4887}
4888
4889/*
4890 * Lookup VNI.
4891 */
d62a17ae 4892struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni)
128ea8ab 4893{
d62a17ae 4894 struct bgpevpn *vpn;
4895 struct bgpevpn tmp;
128ea8ab 4896
d62a17ae 4897 memset(&tmp, 0, sizeof(struct bgpevpn));
4898 tmp.vni = vni;
4899 vpn = hash_lookup(bgp->vnihash, &tmp);
4900 return vpn;
128ea8ab 4901}
4902
4903/*
4904 * Create a new vpn - invoked upon configuration or zebra notification.
4905 */
d62a17ae 4906struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
29c53922
MK
4907 struct in_addr originator_ip,
4908 vrf_id_t tenant_vrf_id)
128ea8ab 4909{
d62a17ae 4910 struct bgpevpn *vpn;
128ea8ab 4911
d62a17ae 4912 if (!bgp)
4913 return NULL;
128ea8ab 4914
d62a17ae 4915 vpn = XCALLOC(MTYPE_BGP_EVPN, sizeof(struct bgpevpn));
4916 if (!vpn)
4917 return NULL;
128ea8ab 4918
d62a17ae 4919 /* Set values - RD and RT set to defaults. */
4920 vpn->vni = vni;
4921 vpn->originator_ip = originator_ip;
29c53922 4922 vpn->tenant_vrf_id = tenant_vrf_id;
128ea8ab 4923
d62a17ae 4924 /* Initialize route-target import and export lists */
4925 vpn->import_rtl = list_new();
4926 vpn->import_rtl->cmp = (int (*)(void *, void *))evpn_route_target_cmp;
987d8198 4927 vpn->import_rtl->del = evpn_xxport_delete_ecomm;
d62a17ae 4928 vpn->export_rtl = list_new();
4929 vpn->export_rtl->cmp = (int (*)(void *, void *))evpn_route_target_cmp;
987d8198 4930 vpn->export_rtl->del = evpn_xxport_delete_ecomm;
e9eb5f63 4931 bf_assign_index(bm->rd_idspace, vpn->rd_id);
d62a17ae 4932 derive_rd_rt_for_vni(bgp, vpn);
128ea8ab 4933
d62a17ae 4934 /* Initialize EVPN route table. */
960035b2 4935 vpn->route_table = bgp_table_init(bgp, AFI_L2VPN, SAFI_EVPN);
128ea8ab 4936
d62a17ae 4937 /* Add to hash */
4938 if (!hash_get(bgp->vnihash, vpn, hash_alloc_intern)) {
4939 XFREE(MTYPE_BGP_EVPN, vpn);
4940 return NULL;
4941 }
6a8657d0
MK
4942
4943 /* add to l2vni list on corresponding vrf */
4944 bgpevpn_link_to_l3vni(vpn);
4945
d62a17ae 4946 QOBJ_REG(vpn, bgpevpn);
4947 return vpn;
128ea8ab 4948}
4949
4950/*
4951 * Free a given VPN - called in multiple scenarios such as zebra
4952 * notification, configuration being deleted, advertise-all-vni disabled etc.
4953 * This just frees appropriate memory, caller should have taken other
4954 * needed actions.
4955 */
d62a17ae 4956void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 4957{
6a8657d0 4958 bgpevpn_unlink_from_l3vni(vpn);
d62a17ae 4959 bgp_table_unlock(vpn->route_table);
4960 bgp_evpn_unmap_vni_from_its_rts(bgp, vpn);
affe9e99
DS
4961 list_delete_and_null(&vpn->import_rtl);
4962 list_delete_and_null(&vpn->export_rtl);
e9eb5f63 4963 bf_release_index(bm->rd_idspace, vpn->rd_id);
d62a17ae 4964 hash_release(bgp->vnihash, vpn);
4965 QOBJ_UNREG(vpn);
4966 XFREE(MTYPE_BGP_EVPN, vpn);
128ea8ab 4967}
4968
4969/*
50f74cf1 4970 * Lookup local ES.
4971 */
4972struct evpnes *bgp_evpn_lookup_es(struct bgp *bgp, esi_t *esi)
4973{
4974 struct evpnes *es;
4975 struct evpnes tmp;
4976
4977 memset(&tmp, 0, sizeof(struct evpnes));
4978 memcpy(&tmp.esi, esi, sizeof(esi_t));
4979 es = hash_lookup(bgp->esihash, &tmp);
4980 return es;
4981}
4982
4983/*
4984 * Create a new local es - invoked upon zebra notification.
4985 */
4986struct evpnes *bgp_evpn_es_new(struct bgp *bgp,
4987 esi_t *esi,
4988 struct ipaddr *originator_ip)
4989{
4990 char buf[100];
4991 struct evpnes *es;
4992
4993 if (!bgp)
4994 return NULL;
4995
4996 es = XCALLOC(MTYPE_BGP_EVPN_ES, sizeof(struct evpnes));
4997 if (!es)
4998 return NULL;
4999
5000 /* set the ESI and originator_ip */
5001 memcpy(&es->esi, esi, sizeof(esi_t));
5002 memcpy(&es->originator_ip, originator_ip, sizeof(struct ipaddr));
5003
5004 /* Initialise the VTEP list */
5005 es->vtep_list = list_new();
5006 es->vtep_list->cmp = (int (*)(void *, void *))evpn_vtep_ip_cmp;
5007
5008 /* auto derive RD for this es */
5009 bf_assign_index(bm->rd_idspace, es->rd_id);
5010 es->prd.family = AF_UNSPEC;
5011 es->prd.prefixlen = 64;
5012 sprintf(buf, "%s:%hu", inet_ntoa(bgp->router_id), es->rd_id);
5013 (void)str2prefix_rd(buf, &es->prd);
5014
5015 /* Initialize the ES route table */
5016 es->route_table = bgp_table_init(bgp, AFI_L2VPN, SAFI_EVPN);
5017
5018 /* Add to hash */
5019 if (!hash_get(bgp->esihash, es, hash_alloc_intern)) {
5020 XFREE(MTYPE_BGP_EVPN_ES, es);
5021 return NULL;
5022 }
5023
5024 QOBJ_REG(es, evpnes);
5025 return es;
5026}
5027
5028/*
5029 * Free a given ES -
5030 * This just frees appropriate memory, caller should have taken other
5031 * needed actions.
5032 */
5033void bgp_evpn_es_free(struct bgp *bgp, struct evpnes *es)
5034{
5035 list_delete_and_null(&es->vtep_list);
5036 bgp_table_unlock(es->route_table);
5037 bf_release_index(bm->rd_idspace, es->rd_id);
5038 hash_release(bgp->esihash, es);
5039 QOBJ_UNREG(es);
5040 XFREE(MTYPE_BGP_EVPN_ES, es);
5041}
5042
5043/*
5044 * Import evpn route from global table to VNI/VRF/ESI.
128ea8ab 5045 */
d62a17ae 5046int bgp_evpn_import_route(struct bgp *bgp, afi_t afi, safi_t safi,
5047 struct prefix *p, struct bgp_info *ri)
128ea8ab 5048{
d62a17ae 5049 return install_uninstall_evpn_route(bgp, afi, safi, p, ri, 1);
128ea8ab 5050}
5051
5052/*
50f74cf1 5053 * Unimport evpn route from VNI/VRF/ESI.
128ea8ab 5054 */
d62a17ae 5055int bgp_evpn_unimport_route(struct bgp *bgp, afi_t afi, safi_t safi,
5056 struct prefix *p, struct bgp_info *ri)
128ea8ab 5057{
d62a17ae 5058 return install_uninstall_evpn_route(bgp, afi, safi, p, ri, 0);
128ea8ab 5059}
5060
db0e1937
MK
5061/* filter routes which have martian next hops */
5062int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp)
5063{
0291c246
MK
5064 afi_t afi;
5065 safi_t safi;
5066 struct bgp_node *rd_rn, *rn;
5067 struct bgp_table *table;
5068 struct bgp_info *ri;
db0e1937
MK
5069
5070 afi = AFI_L2VPN;
5071 safi = SAFI_EVPN;
5072
5073 /* Walk entire global routing table and evaluate routes which could be
5074 * imported into this VPN. Note that we cannot just look at the routes
5075 * for the VNI's RD -
5076 * remote routes applicable for this VNI could have any RD.
5077 */
5078 /* EVPN routes are a 2-level table. */
5079 for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
5080 rd_rn = bgp_route_next(rd_rn)) {
5081 table = (struct bgp_table *)(rd_rn->info);
5082 if (!table)
5083 continue;
5084
5085 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
5086
5087 for (ri = rn->info; ri; ri = ri->next) {
5088
5089 /* Consider "valid" remote routes applicable for
5090 * this VNI. */
5091 if (!(ri->type == ZEBRA_ROUTE_BGP
5092 && ri->sub_type == BGP_ROUTE_NORMAL))
5093 continue;
5094
60466a63 5095 if (bgp_nexthop_self(bgp, ri->attr->nexthop)) {
db0e1937
MK
5096
5097 char attr_str[BUFSIZ];
5098 char pbuf[PREFIX_STRLEN];
5099
5100 bgp_dump_attr(ri->attr, attr_str,
5101 BUFSIZ);
5102
5103 if (bgp_debug_update(ri->peer, &rn->p,
5104 NULL, 1))
5105 zlog_debug(
b682f6de 5106 "%u: prefix %s with attr %s - DENIED due to martian or self nexthop",
db0e1937
MK
5107 bgp->vrf_id,
5108 prefix2str(
60466a63 5109 &rn->p, pbuf,
db0e1937
MK
5110 sizeof(pbuf)),
5111 attr_str);
5112
5113 bgp_evpn_unimport_route(bgp, afi, safi,
5114 &rn->p, ri);
5115
60466a63
QY
5116 bgp_rib_remove(rn, ri, ri->peer, afi,
5117 safi);
db0e1937 5118 }
db0e1937
MK
5119 }
5120 }
5121 }
5122
5123 return 0;
5124}
5125
128ea8ab 5126/*
5127 * Handle del of a local MACIP.
5128 */
d62a17ae 5129int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
5130 struct ipaddr *ip)
128ea8ab 5131{
d62a17ae 5132 struct bgpevpn *vpn;
5133 struct prefix_evpn p;
128ea8ab 5134
d62a17ae 5135 if (!bgp->vnihash) {
5136 zlog_err("%u: VNI hash not created", bgp->vrf_id);
5137 return -1;
5138 }
128ea8ab 5139
d62a17ae 5140 /* Lookup VNI hash - should exist. */
5141 vpn = bgp_evpn_lookup_vni(bgp, vni);
5142 if (!vpn || !is_vni_live(vpn)) {
5143 zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP DEL",
5144 bgp->vrf_id, vni, vpn ? "not live" : "not found");
5145 return -1;
5146 }
128ea8ab 5147
d62a17ae 5148 /* Remove EVPN type-2 route and schedule for processing. */
5149 build_evpn_type2_prefix(&p, mac, ip);
5150 delete_evpn_route(bgp, vpn, &p);
128ea8ab 5151
d62a17ae 5152 return 0;
128ea8ab 5153}
5154
5155/*
5156 * Handle add of a local MACIP.
5157 */
d62a17ae 5158int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
d7c0a89a 5159 struct ipaddr *ip, uint8_t flags)
128ea8ab 5160{
d62a17ae 5161 struct bgpevpn *vpn;
5162 struct prefix_evpn p;
128ea8ab 5163
d62a17ae 5164 if (!bgp->vnihash) {
5165 zlog_err("%u: VNI hash not created", bgp->vrf_id);
5166 return -1;
5167 }
128ea8ab 5168
d62a17ae 5169 /* Lookup VNI hash - should exist. */
5170 vpn = bgp_evpn_lookup_vni(bgp, vni);
5171 if (!vpn || !is_vni_live(vpn)) {
5172 zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP ADD",
5173 bgp->vrf_id, vni, vpn ? "not live" : "not found");
5174 return -1;
5175 }
128ea8ab 5176
d62a17ae 5177 /* Create EVPN type-2 route and schedule for processing. */
5178 build_evpn_type2_prefix(&p, mac, ip);
1a98c087 5179 if (update_evpn_route(bgp, vpn, &p, flags)) {
d62a17ae 5180 char buf[ETHER_ADDR_STRLEN];
5181 char buf2[INET6_ADDRSTRLEN];
128ea8ab 5182
d62a17ae 5183 zlog_err(
ead40654 5184 "%u:Failed to create Type-2 route, VNI %u %s MAC %s IP %s (flags: 0x%x)",
1a98c087 5185 bgp->vrf_id, vpn->vni,
996c9314
LB
5186 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY)
5187 ? "sticky gateway"
5188 : "",
d62a17ae 5189 prefix_mac2str(mac, buf, sizeof(buf)),
996c9314 5190 ipaddr2str(ip, buf2, sizeof(buf2)), flags);
d62a17ae 5191 return -1;
5192 }
128ea8ab 5193
d62a17ae 5194 return 0;
128ea8ab 5195}
5196
6a8657d0
MK
5197static void link_l2vni_hash_to_l3vni(struct hash_backet *backet,
5198 struct bgp *bgp_vrf)
5199{
5200 struct bgpevpn *vpn = NULL;
5201 struct bgp *bgp_def = NULL;
5202
5203 bgp_def = bgp_get_default();
5204 assert(bgp_def);
5205
5206 vpn = (struct bgpevpn *)backet->data;
5207 if (vpn->tenant_vrf_id == bgp_vrf->vrf_id)
5208 bgpevpn_link_to_l3vni(vpn);
5209}
5210
996c9314
LB
5211int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac,
5212 struct in_addr originator_ip, int filter)
fe1dc5a3
MK
5213{
5214 struct bgp *bgp_vrf = NULL; /* bgp VRF instance */
5215 struct bgp *bgp_def = NULL; /* default bgp instance */
f1f8b53c
MK
5216 struct listnode *node = NULL;
5217 struct bgpevpn *vpn = NULL;
fe1dc5a3
MK
5218 as_t as = 0;
5219
5220 /* get the default instamce - required to get the AS number for VRF
523cafc4 5221 * auto-creatio
5222 */
fe1dc5a3
MK
5223 bgp_def = bgp_get_default();
5224 if (!bgp_def) {
996c9314
LB
5225 zlog_err(
5226 "Cannot process L3VNI %u ADD - default BGP instance not yet created",
5227 l3vni);
fe1dc5a3
MK
5228 return -1;
5229 }
5230 as = bgp_def->as;
5231
5232 /* if the BGP vrf instance doesnt exist - create one */
0b5131c9 5233 bgp_vrf = bgp_lookup_by_name(vrf_id_to_name(vrf_id));
fe1dc5a3
MK
5234 if (!bgp_vrf) {
5235
5236 int ret = 0;
5237
5238 ret = bgp_get(&bgp_vrf, &as, vrf_id_to_name(vrf_id),
5239 BGP_INSTANCE_TYPE_VRF);
5240 switch (ret) {
5241 case BGP_ERR_MULTIPLE_INSTANCE_NOT_SET:
5242 zlog_err("'bgp multiple-instance' not present\n");
5243 return -1;
5244 case BGP_ERR_AS_MISMATCH:
5245 zlog_err("BGP is already running; AS is %u\n", as);
5246 return -1;
5247 case BGP_ERR_INSTANCE_MISMATCH:
5248 zlog_err("BGP instance name and AS number mismatch\n");
5249 return -1;
5250 }
5251
5252 /* mark as auto created */
5253 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_AUTO);
5254 }
5255
5256 /* associate with l3vni */
5257 bgp_vrf->l3vni = l3vni;
5258
5259 /* set the router mac - to be used in mac-ip routes for this vrf */
5260 memcpy(&bgp_vrf->rmac, rmac, sizeof(struct ethaddr));
5261
b67a60d2 5262 /* set the originator ip */
5263 bgp_vrf->originator_ip = originator_ip;
5264
c48d9f5f
MK
5265 /* set the right filter - are we using l3vni only for prefix routes? */
5266 if (filter)
5267 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY);
5268
c581d8b0
MK
5269 /* auto derive RD/RT */
5270 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD))
5271 evpn_auto_rt_import_add_for_vrf(bgp_vrf);
5272 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD))
5273 evpn_auto_rt_export_add_for_vrf(bgp_vrf);
676f83b9 5274 bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf);
fe1dc5a3 5275
6a8657d0
MK
5276 /* link all corresponding l2vnis */
5277 hash_iterate(bgp_def->vnihash,
996c9314
LB
5278 (void (*)(struct hash_backet *,
5279 void *))link_l2vni_hash_to_l3vni,
6a8657d0
MK
5280 bgp_vrf);
5281
c48d9f5f
MK
5282 /* Only update all corresponding type-2 routes if we are advertising two
5283 * labels along with type-2 routes
5284 */
5285 if (!filter)
5286 for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn))
5287 update_routes_for_vni(bgp_def, vpn);
fe1dc5a3 5288
06d2e8f3
MK
5289 /* advertise type-5 routes if needed */
5290 update_advertise_vrf_routes(bgp_vrf);
5291
5ba238b7
MK
5292 /* install all remote routes belonging to this l3vni into correspondng
5293 * vrf */
5294 install_routes_for_vrf(bgp_vrf);
fe1dc5a3
MK
5295
5296 return 0;
5297}
5298
996c9314 5299int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id)
fe1dc5a3
MK
5300{
5301 struct bgp *bgp_vrf = NULL; /* bgp vrf instance */
f1f8b53c
MK
5302 struct bgp *bgp_def = NULL; /* default bgp instance */
5303 struct listnode *node = NULL;
18abc1eb 5304 struct listnode *next = NULL;
f1f8b53c 5305 struct bgpevpn *vpn = NULL;
fe1dc5a3
MK
5306
5307 bgp_vrf = bgp_lookup_by_vrf_id(vrf_id);
5308 if (!bgp_vrf) {
996c9314
LB
5309 zlog_err(
5310 "Cannot process L3VNI %u Del - Could not find BGP instance",
5311 l3vni);
fe1dc5a3
MK
5312 return -1;
5313 }
5314
f1f8b53c
MK
5315 bgp_def = bgp_get_default();
5316 if (!bgp_def) {
996c9314
LB
5317 zlog_err(
5318 "Cannot process L3VNI %u Del - Could not find default BGP instance",
5319 l3vni);
f1f8b53c
MK
5320 return -1;
5321 }
5322
1eb88002 5323 /* unimport remote routes from VRF, if it is AUTO vrf bgp_delete will
523cafc4 5324 * take care of uninstalling the routes from zebra
5325 */
1eb88002
MK
5326 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_AUTO))
5327 uninstall_routes_for_vrf(bgp_vrf);
5ba238b7 5328
06d2e8f3
MK
5329 /* delete/withdraw all type-5 routes */
5330 delete_withdraw_vrf_routes(bgp_vrf);
5331
fe1dc5a3
MK
5332 /* remove the l3vni from vrf instance */
5333 bgp_vrf->l3vni = 0;
5334
5335 /* remove the Rmac from the BGP vrf */
5336 memset(&bgp_vrf->rmac, 0, sizeof(struct ethaddr));
5337
c581d8b0 5338 /* delete RD/RT */
23a06e11 5339 if (bgp_vrf->vrf_import_rtl && !list_isempty(bgp_vrf->vrf_import_rtl)) {
10ebe1ab 5340 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf);
5ba238b7 5341 list_delete_all_node(bgp_vrf->vrf_import_rtl);
23a06e11
MK
5342 }
5343 if (bgp_vrf->vrf_export_rtl && !list_isempty(bgp_vrf->vrf_export_rtl)) {
5ba238b7 5344 list_delete_all_node(bgp_vrf->vrf_export_rtl);
23a06e11 5345 }
fe1dc5a3 5346
f1f8b53c 5347 /* update all corresponding local mac-ip routes */
c48d9f5f
MK
5348 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY)) {
5349 for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn)) {
5350 UNSET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS);
5351 update_routes_for_vni(bgp_def, vpn);
5352 }
5353 }
fe1dc5a3 5354
18abc1eb 5355 /* If any L2VNIs point to this instance, unlink them. */
5356 for (ALL_LIST_ELEMENTS(bgp_vrf->l2vnis, node, next, vpn))
5357 bgpevpn_unlink_from_l3vni(vpn);
5358
fe1dc5a3
MK
5359 /* Delete the instance if it was autocreated */
5360 if (CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_AUTO))
5361 bgp_delete(bgp_vrf);
5362
5363 return 0;
5364}
5365
128ea8ab 5366/*
5367 * Handle del of a local VNI.
5368 */
d62a17ae 5369int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni)
128ea8ab 5370{
d62a17ae 5371 struct bgpevpn *vpn;
128ea8ab 5372
d62a17ae 5373 if (!bgp->vnihash) {
5374 zlog_err("%u: VNI hash not created", bgp->vrf_id);
5375 return -1;
5376 }
128ea8ab 5377
d62a17ae 5378 /* Locate VNI hash */
5379 vpn = bgp_evpn_lookup_vni(bgp, vni);
5380 if (!vpn) {
1e00627b 5381 if (bgp_debug_zebra(NULL))
3518f352
DS
5382 zlog_warn(
5383 "%u: VNI hash entry for VNI %u not found at DEL",
5384 bgp->vrf_id, vni);
d62a17ae 5385 return 0;
5386 }
128ea8ab 5387
d62a17ae 5388 /* Remove all local EVPN routes and schedule for processing (to
5389 * withdraw from peers).
5390 */
5391 delete_routes_for_vni(bgp, vpn);
128ea8ab 5392
db0e1937
MK
5393 /*
5394 * tunnel is no longer active, del tunnel ip address from tip_hash
5395 */
5396 bgp_tip_del(bgp, &vpn->originator_ip);
5397
d62a17ae 5398 /* Clear "live" flag and see if hash needs to be freed. */
5399 UNSET_FLAG(vpn->flags, VNI_FLAG_LIVE);
5400 if (!is_vni_configured(vpn))
5401 bgp_evpn_free(bgp, vpn);
128ea8ab 5402
d62a17ae 5403 return 0;
128ea8ab 5404}
5405
5406/*
d1911c26 5407 * Handle add (or update) of a local VNI. The VNI changes we care
5408 * about are for the local-tunnel-ip and the (tenant) VRF.
128ea8ab 5409 */
d62a17ae 5410int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
996c9314 5411 struct in_addr originator_ip, vrf_id_t tenant_vrf_id)
d62a17ae 5412{
5413 struct bgpevpn *vpn;
5414 struct prefix_evpn p;
5415
5416 if (!bgp->vnihash) {
5417 zlog_err("%u: VNI hash not created", bgp->vrf_id);
5418 return -1;
5419 }
5420
5421 /* Lookup VNI. If present and no change, exit. */
5422 vpn = bgp_evpn_lookup_vni(bgp, vni);
ddd16ed5 5423 if (vpn) {
29c53922 5424
d1911c26 5425 if (is_vni_live(vpn)
5426 && IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip)
5427 && vpn->tenant_vrf_id == tenant_vrf_id)
5428 /* Probably some other param has changed that we don't
5429 * care about. */
5430 return 0;
5431
5432 /* Update tenant_vrf_id if it has changed. */
6a8657d0
MK
5433 if (vpn->tenant_vrf_id != tenant_vrf_id) {
5434 bgpevpn_unlink_from_l3vni(vpn);
29c53922 5435 vpn->tenant_vrf_id = tenant_vrf_id;
6a8657d0
MK
5436 bgpevpn_link_to_l3vni(vpn);
5437 }
29c53922 5438
d1911c26 5439 /* If tunnel endpoint IP has changed, update (and delete prior
5440 * type-3 route, if needed.)
5441 */
5442 if (!IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip))
5443 handle_tunnel_ip_change(bgp, vpn, originator_ip);
d62a17ae 5444
d1911c26 5445 /* Update all routes with new endpoint IP and/or export RT
5446 * for VRFs
5447 */
5448 if (is_vni_live(vpn))
5449 update_routes_for_vni(bgp, vpn);
d62a17ae 5450 }
5451
5452 /* Create or update as appropriate. */
5453 if (!vpn) {
29c53922 5454 vpn = bgp_evpn_new(bgp, vni, originator_ip, tenant_vrf_id);
d62a17ae 5455 if (!vpn) {
5456 zlog_err(
5457 "%u: Failed to allocate VNI entry for VNI %u - at Add",
5458 bgp->vrf_id, vni);
5459 return -1;
5460 }
5461 }
5462
db0e1937 5463 /* if the VNI is live already, there is nothing more to do */
ddd16ed5
MK
5464 if (is_vni_live(vpn))
5465 return 0;
5466
d62a17ae 5467 /* Mark as "live" */
5468 SET_FLAG(vpn->flags, VNI_FLAG_LIVE);
5469
db0e1937
MK
5470 /* tunnel is now active, add tunnel-ip to db */
5471 bgp_tip_add(bgp, &originator_ip);
5472
5473 /* filter routes as nexthop database has changed */
5474 bgp_filter_evpn_routes_upon_martian_nh_change(bgp);
5475
d62a17ae 5476 /* Create EVPN type-3 route and schedule for processing. */
5477 build_evpn_type3_prefix(&p, vpn->originator_ip);
5478 if (update_evpn_route(bgp, vpn, &p, 0)) {
5479 zlog_err("%u: Type3 route creation failure for VNI %u",
5480 bgp->vrf_id, vni);
5481 return -1;
5482 }
5483
5484 /* If we have learnt and retained remote routes (VTEPs, MACs) for this
5485 * VNI,
5486 * install them.
5487 */
5488 install_routes_for_vni(bgp, vpn);
5489
d7d97010
MK
5490 /* If we are advertising gateway mac-ip
5491 It needs to be conveyed again to zebra */
5492 bgp_zebra_advertise_gw_macip(bgp, vpn->advertise_gw_macip, vpn->vni);
5493
d62a17ae 5494 return 0;
b18825eb 5495}
14c1a7bf 5496
50f74cf1 5497/*
5498 * bgp_evpn_local_es_del
5499 */
5500int bgp_evpn_local_es_del(struct bgp *bgp,
5501 esi_t *esi,
5502 struct ipaddr *originator_ip)
5503{
5504 char buf[ESI_STR_LEN];
5505 struct evpnes *es = NULL;
5506
5507 if (!bgp->esihash) {
5508 zlog_err("%u: ESI hash not yet created", bgp->vrf_id);
5509 return -1;
5510 }
5511
5512 /* Lookup ESI hash - should exist. */
5513 es = bgp_evpn_lookup_es(bgp, esi);
5514 if (!es) {
5515 zlog_warn("%u: ESI hash entry for ESI %s at Local ES DEL",
5516 bgp->vrf_id,
5517 esi_to_str(esi, buf, sizeof(buf)));
5518 return -1;
5519 }
5520
5521 /* Delete all local EVPN ES routes from ESI table
2bb9eff4 5522 * and schedule for processing (to withdraw from peers))
50f74cf1 5523 */
5524 delete_routes_for_es(bgp, es);
5525
5526 /* free the hash entry */
5527 bgp_evpn_es_free(bgp, es);
5528
5529 return 0;
5530}
5531
5532/*
5533 * bgp_evpn_local_es_add
5534 */
5535int bgp_evpn_local_es_add(struct bgp *bgp,
5536 esi_t *esi,
5537 struct ipaddr *originator_ip)
5538{
5539 char buf[ESI_STR_LEN];
5540 struct evpnes *es = NULL;
5541 struct prefix_evpn p;
5542
5543 if (!bgp->esihash) {
5544 zlog_err("%u: ESI hash not yet created", bgp->vrf_id);
5545 return -1;
5546 }
5547
5548 /* create the new es */
2bb9eff4 5549 es = bgp_evpn_lookup_es(bgp, esi);
50f74cf1 5550 if (!es) {
5551 es = bgp_evpn_es_new(bgp, esi, originator_ip);
5552 if (!es) {
5553 zlog_err(
5554 "%u: Failed to allocate ES entry for ESI %s - at Local ES Add",
5555 bgp->vrf_id, esi_to_str(esi, buf, sizeof(buf)));
5556 return -1;
5557 }
5558 }
5559 UNSET_FLAG(es->flags, EVPNES_REMOTE);
5560 SET_FLAG(es->flags, EVPNES_LOCAL);
5561
5562 build_evpn_type4_prefix(&p, esi, originator_ip->ipaddr_v4);
5563 if (update_evpn_type4_route(bgp, es, &p)) {
5564 zlog_err("%u: Type4 route creation failure for ESI %s",
5565 bgp->vrf_id, esi_to_str(esi, buf, sizeof(buf)));
5566 return -1;
5567 }
5568
5569 /* import all remote ES routes in th ES table */
5570 install_routes_for_es(bgp, es);
5571
5572 return 0;
5573}
5574
7724c0a1 5575/*
5576 * Cleanup EVPN information on disable - Need to delete and withdraw
5577 * EVPN routes from peers.
5578 */
d62a17ae 5579void bgp_evpn_cleanup_on_disable(struct bgp *bgp)
7724c0a1 5580{
9d303b37
DL
5581 hash_iterate(bgp->vnihash, (void (*)(struct hash_backet *,
5582 void *))cleanup_vni_on_disable,
5583 bgp);
7724c0a1 5584}
5585
14c1a7bf 5586/*
5587 * Cleanup EVPN information - invoked at the time of bgpd exit or when the
5588 * BGP instance (default) is being freed.
5589 */
d62a17ae 5590void bgp_evpn_cleanup(struct bgp *bgp)
14c1a7bf 5591{
d62a17ae 5592 if (bgp->vnihash)
9d303b37
DL
5593 hash_iterate(bgp->vnihash, (void (*)(struct hash_backet *,
5594 void *))free_vni_entry,
5595 bgp);
d62a17ae 5596 if (bgp->import_rt_hash)
5597 hash_free(bgp->import_rt_hash);
5598 bgp->import_rt_hash = NULL;
10ebe1ab
MK
5599 if (bgp->vrf_import_rt_hash)
5600 hash_free(bgp->vrf_import_rt_hash);
5601 bgp->vrf_import_rt_hash = NULL;
d62a17ae 5602 if (bgp->vnihash)
5603 hash_free(bgp->vnihash);
5604 bgp->vnihash = NULL;
50f74cf1 5605 if (bgp->esihash)
5606 hash_free(bgp->esihash);
5607 bgp->esihash = NULL;
c581d8b0 5608 if (bgp->vrf_import_rtl)
bb7a24ab 5609 list_delete_and_null(&bgp->vrf_import_rtl);
c581d8b0 5610 if (bgp->vrf_export_rtl)
bb7a24ab 5611 list_delete_and_null(&bgp->vrf_export_rtl);
6a8657d0 5612 if (bgp->l2vnis)
bb7a24ab 5613 list_delete_and_null(&bgp->l2vnis);
14c1a7bf 5614}
5615
5616/*
5617 * Initialization for EVPN
5618 * Create
5619 * VNI hash table
5620 * hash for RT to VNI
14c1a7bf 5621 */
d62a17ae 5622void bgp_evpn_init(struct bgp *bgp)
5623{
5624 bgp->vnihash =
5625 hash_create(vni_hash_key_make, vni_hash_cmp, "BGP VNI Hash");
50f74cf1 5626 bgp->esihash =
5627 hash_create(esi_hash_keymake, esi_cmp,
5628 "BGP EVPN Local ESI Hash");
d62a17ae 5629 bgp->import_rt_hash =
5630 hash_create(import_rt_hash_key_make, import_rt_hash_cmp,
5631 "BGP Import RT Hash");
10ebe1ab
MK
5632 bgp->vrf_import_rt_hash =
5633 hash_create(vrf_import_rt_hash_key_make, vrf_import_rt_hash_cmp,
5634 "BGP VRF Import RT Hash");
c581d8b0
MK
5635 bgp->vrf_import_rtl = list_new();
5636 bgp->vrf_import_rtl->cmp =
5637 (int (*)(void *, void *))evpn_route_target_cmp;
987d8198 5638 bgp->vrf_import_rtl->del = evpn_xxport_delete_ecomm;
c581d8b0
MK
5639 bgp->vrf_export_rtl = list_new();
5640 bgp->vrf_export_rtl->cmp =
5641 (int (*)(void *, void *))evpn_route_target_cmp;
987d8198 5642 bgp->vrf_export_rtl->del = evpn_xxport_delete_ecomm;
6a8657d0 5643 bgp->l2vnis = list_new();
996c9314 5644 bgp->l2vnis->cmp = (int (*)(void *, void *))vni_hash_cmp;
14c1a7bf 5645}
10ebe1ab
MK
5646
5647void bgp_evpn_vrf_delete(struct bgp *bgp_vrf)
5648{
5649 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf);
5650}