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