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