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