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