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