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