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