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