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