]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_evpn.c
bgpd: set NEXTHOP_UNCHANGED for l2vpn evpn by default for all BGP peers
[mirror_frr.git] / bgpd / bgp_evpn.c
CommitLineData
7ef5a232 1/* Ethernet-VPN Packet and vty Processing File
896014f4 2 * Copyright (C) 2016 6WIND
128ea8ab 3 * Copyright (C) 2017 Cumulus Networks, Inc.
896014f4 4 *
128ea8ab 5 * This file is part of FRR.
896014f4
DL
6 *
7 * FRRouting is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * FRRouting is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
7ef5a232 21
7ef5a232
PG
22#include <zebra.h>
23
24#include "command.h"
25#include "filter.h"
26#include "prefix.h"
27#include "log.h"
28#include "memory.h"
29#include "stream.h"
14c1a7bf 30#include "hash.h"
31#include "jhash.h"
128ea8ab 32#include "zclient.h"
7ef5a232
PG
33
34#include "bgpd/bgp_attr_evpn.h"
35#include "bgpd/bgpd.h"
36#include "bgpd/bgp_table.h"
37#include "bgpd/bgp_route.h"
38#include "bgpd/bgp_attr.h"
39#include "bgpd/bgp_mplsvpn.h"
9bedbb1e 40#include "bgpd/bgp_label.h"
7ef5a232 41#include "bgpd/bgp_evpn.h"
14c1a7bf 42#include "bgpd/bgp_evpn_private.h"
43#include "bgpd/bgp_ecommunity.h"
128ea8ab 44#include "bgpd/bgp_encap_types.h"
45#include "bgpd/bgp_debug.h"
46#include "bgpd/bgp_aspath.h"
d7d97010 47#include "bgpd/bgp_zebra.h"
db0e1937 48#include "bgpd/bgp_nexthop.h"
128ea8ab 49
50/*
51 * Definitions and external declarations.
52 */
53extern struct zclient *zclient;
54
55DEFINE_QOBJ_TYPE(bgpevpn)
56
57
58/*
59 * Static function declarations
60 */
d62a17ae 61static void delete_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
62 afi_t afi, safi_t safi, struct bgp_node *rn,
63 struct bgp_info **ri);
64static int delete_all_vni_routes(struct bgp *bgp, struct bgpevpn *vpn);
14c1a7bf 65
66/*
67 * Private functions.
68 */
69
70/*
71 * Make vni hash key.
72 */
d62a17ae 73static unsigned int vni_hash_key_make(void *p)
14c1a7bf 74{
d62a17ae 75 struct bgpevpn *vpn = p;
76 return (jhash_1word(vpn->vni, 0));
14c1a7bf 77}
78
79/*
80 * Comparison function for vni hash
81 */
d62a17ae 82static int vni_hash_cmp(const void *p1, const void *p2)
14c1a7bf 83{
d62a17ae 84 const struct bgpevpn *vpn1 = p1;
85 const struct bgpevpn *vpn2 = p2;
14c1a7bf 86
d62a17ae 87 if (!vpn1 && !vpn2)
88 return 1;
89 if (!vpn1 || !vpn2)
90 return 0;
91 return (vpn1->vni == vpn2->vni);
14c1a7bf 92}
93
10ebe1ab
MK
94/*
95 * Make vrf import route target hash key.
96 */
97static unsigned int vrf_import_rt_hash_key_make(void *p)
98{
99 struct vrf_irt_node *irt = p;
100 char *pnt = irt->rt.val;
5a1b3fb5
DS
101
102 return jhash(pnt, 8, 0x5abc1234);
10ebe1ab
MK
103}
104
105/*
106 * Comparison function for vrf import rt hash
107 */
108static int vrf_import_rt_hash_cmp(const void *p1, const void *p2)
109{
110 const struct vrf_irt_node *irt1 = p1;
111 const struct vrf_irt_node *irt2 = p2;
112
113 if (irt1 == NULL && irt2 == NULL)
114 return 1;
115
116 if (irt1 == NULL || irt2 == NULL)
117 return 0;
118
119 return (memcmp(irt1->rt.val, irt2->rt.val, ECOMMUNITY_SIZE) == 0);
120}
121
122/*
123 * Create a new vrf import_rt in default instance
124 */
125static struct vrf_irt_node *vrf_import_rt_new(struct ecommunity_val *rt)
126{
127 struct bgp *bgp_def = NULL;
128 struct vrf_irt_node *irt;
129
130 bgp_def = bgp_get_default();
131 if (!bgp_def) {
132 zlog_err("vrf import rt new - def instance not created yet");
133 return NULL;
134 }
135
136 irt = XCALLOC(MTYPE_BGP_EVPN_VRF_IMPORT_RT,
137 sizeof(struct vrf_irt_node));
138 if (!irt)
139 return NULL;
140
141 irt->rt = *rt;
142 irt->vrfs = list_new();
143
144 /* Add to hash */
145 if (!hash_get(bgp_def->vrf_import_rt_hash, irt, hash_alloc_intern)) {
146 XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT, irt);
147 return NULL;
148 }
149
150 return irt;
151}
152
153/*
154 * Free the vrf import rt node
155 */
156static void vrf_import_rt_free(struct vrf_irt_node *irt)
157{
158 struct bgp *bgp_def = NULL;
159
160 bgp_def = bgp_get_default();
161 if (!bgp_def) {
162 zlog_err("vrf import rt free - def instance not created yet");
163 return;
164 }
165
166 hash_release(bgp_def->vrf_import_rt_hash, irt);
167 XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT, irt);
168}
169
170/*
171 * Function to lookup Import RT node - used to map a RT to set of
172 * VNIs importing routes with that RT.
173 */
174static struct vrf_irt_node *lookup_vrf_import_rt(struct ecommunity_val *rt)
175{
176 struct bgp *bgp_def = NULL;
177 struct vrf_irt_node *irt;
178 struct vrf_irt_node tmp;
179
180 bgp_def = bgp_get_default();
181 if (!bgp_def) {
182 zlog_err("vrf import rt lookup - def instance not created yet");
183 return NULL;
184 }
185
186 memset(&tmp, 0, sizeof(struct vrf_irt_node));
187 memcpy(&tmp.rt, rt, ECOMMUNITY_SIZE);
188 irt = hash_lookup(bgp_def->vrf_import_rt_hash, &tmp);
189 return irt;
190}
191
192/*
193 * Is specified VRF present on the RT's list of "importing" VRFs?
194 */
996c9314 195static int is_vrf_present_in_irt_vrfs(struct list *vrfs, struct bgp *bgp_vrf)
10ebe1ab
MK
196{
197 struct listnode *node = NULL, *nnode = NULL;
198 struct bgp *tmp_bgp_vrf = NULL;
199
200 for (ALL_LIST_ELEMENTS(vrfs, node, nnode, tmp_bgp_vrf)) {
201 if (tmp_bgp_vrf == bgp_vrf)
202 return 1;
203 }
204 return 0;
205}
206
14c1a7bf 207/*
208 * Make import route target hash key.
209 */
d62a17ae 210static unsigned int import_rt_hash_key_make(void *p)
14c1a7bf 211{
d62a17ae 212 struct irt_node *irt = p;
213 char *pnt = irt->rt.val;
5a1b3fb5
DS
214
215 return jhash(pnt, 8, 0xdeadbeef);
14c1a7bf 216}
217
218/*
219 * Comparison function for import rt hash
220 */
d62a17ae 221static int import_rt_hash_cmp(const void *p1, const void *p2)
14c1a7bf 222{
d62a17ae 223 const struct irt_node *irt1 = p1;
224 const struct irt_node *irt2 = p2;
14c1a7bf 225
d62a17ae 226 if (irt1 == NULL && irt2 == NULL)
227 return 1;
14c1a7bf 228
d62a17ae 229 if (irt1 == NULL || irt2 == NULL)
230 return 0;
14c1a7bf 231
d62a17ae 232 return (memcmp(irt1->rt.val, irt2->rt.val, ECOMMUNITY_SIZE) == 0);
14c1a7bf 233}
234
7724c0a1 235/*
128ea8ab 236 * Create a new import_rt
237 */
d62a17ae 238static struct irt_node *import_rt_new(struct bgp *bgp,
239 struct ecommunity_val *rt)
128ea8ab 240{
d62a17ae 241 struct irt_node *irt;
128ea8ab 242
d62a17ae 243 if (!bgp)
244 return NULL;
128ea8ab 245
d62a17ae 246 irt = XCALLOC(MTYPE_BGP_EVPN_IMPORT_RT, sizeof(struct irt_node));
247 if (!irt)
248 return NULL;
128ea8ab 249
d62a17ae 250 irt->rt = *rt;
251 irt->vnis = list_new();
128ea8ab 252
d62a17ae 253 /* Add to hash */
254 if (!hash_get(bgp->import_rt_hash, irt, hash_alloc_intern)) {
255 XFREE(MTYPE_BGP_EVPN_IMPORT_RT, irt);
256 return NULL;
257 }
128ea8ab 258
d62a17ae 259 return irt;
128ea8ab 260}
261
262/*
263 * Free the import rt node
7724c0a1 264 */
d62a17ae 265static void import_rt_free(struct bgp *bgp, struct irt_node *irt)
7724c0a1 266{
d62a17ae 267 hash_release(bgp->import_rt_hash, irt);
268 XFREE(MTYPE_BGP_EVPN_IMPORT_RT, irt);
7724c0a1 269}
270
14c1a7bf 271/*
128ea8ab 272 * Function to lookup Import RT node - used to map a RT to set of
273 * VNIs importing routes with that RT.
274 */
d62a17ae 275static struct irt_node *lookup_import_rt(struct bgp *bgp,
276 struct ecommunity_val *rt)
128ea8ab 277{
d62a17ae 278 struct irt_node *irt;
279 struct irt_node tmp;
128ea8ab 280
d62a17ae 281 memset(&tmp, 0, sizeof(struct irt_node));
282 memcpy(&tmp.rt, rt, ECOMMUNITY_SIZE);
283 irt = hash_lookup(bgp->import_rt_hash, &tmp);
284 return irt;
128ea8ab 285}
286
287/*
288 * Is specified VNI present on the RT's list of "importing" VNIs?
289 */
d62a17ae 290static int is_vni_present_in_irt_vnis(struct list *vnis, struct bgpevpn *vpn)
128ea8ab 291{
d62a17ae 292 struct listnode *node, *nnode;
293 struct bgpevpn *tmp_vpn;
128ea8ab 294
d62a17ae 295 for (ALL_LIST_ELEMENTS(vnis, node, nnode, tmp_vpn)) {
296 if (tmp_vpn == vpn)
297 return 1;
298 }
128ea8ab 299
d62a17ae 300 return 0;
128ea8ab 301}
302
303/*
304 * Compare Route Targets.
305 */
d62a17ae 306static int evpn_route_target_cmp(struct ecommunity *ecom1,
307 struct ecommunity *ecom2)
128ea8ab 308{
d62a17ae 309 if (ecom1 && !ecom2)
310 return -1;
128ea8ab 311
d62a17ae 312 if (!ecom1 && ecom2)
313 return 1;
128ea8ab 314
d62a17ae 315 if (!ecom1 && !ecom2)
316 return 0;
128ea8ab 317
d62a17ae 318 if (ecom1->str && !ecom2->str)
319 return -1;
128ea8ab 320
d62a17ae 321 if (!ecom1->str && ecom2->str)
322 return 1;
128ea8ab 323
d62a17ae 324 if (!ecom1->str && !ecom2->str)
325 return 0;
128ea8ab 326
d62a17ae 327 return strcmp(ecom1->str, ecom2->str);
128ea8ab 328}
329
330/*
331 * Mask off global-admin field of specified extended community (RT),
332 * just retain the local-admin field.
333 */
d62a17ae 334static inline void mask_ecom_global_admin(struct ecommunity_val *dst,
335 struct ecommunity_val *src)
128ea8ab 336{
d7c0a89a 337 uint8_t type;
128ea8ab 338
d62a17ae 339 type = src->val[0];
340 dst->val[0] = 0;
341 if (type == ECOMMUNITY_ENCODE_AS) {
342 dst->val[2] = dst->val[3] = 0;
343 } else if (type == ECOMMUNITY_ENCODE_AS4
344 || type == ECOMMUNITY_ENCODE_IP) {
345 dst->val[2] = dst->val[3] = 0;
346 dst->val[4] = dst->val[5] = 0;
347 }
128ea8ab 348}
349
10ebe1ab
MK
350/*
351 * Map one RT to specified VRF.
352 * bgp_vrf = BGP vrf instance
353 */
996c9314 354static void map_vrf_to_rt(struct bgp *bgp_vrf, struct ecommunity_val *eval)
10ebe1ab
MK
355{
356 struct vrf_irt_node *irt = NULL;
357 struct ecommunity_val eval_tmp;
358
359 /* If using "automatic" RT,
360 * we only care about the local-admin sub-field.
361 * This is to facilitate using L3VNI(VRF-VNI)
362 * as the RT for EBGP peering too.
363 */
364 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
996c9314 365 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD))
10ebe1ab
MK
366 mask_ecom_global_admin(&eval_tmp, eval);
367
368 irt = lookup_vrf_import_rt(&eval_tmp);
e066d6d0
DS
369 if (irt && is_vrf_present_in_irt_vrfs(irt->vrfs, bgp_vrf))
370 /* Already mapped. */
371 return;
10ebe1ab 372
e066d6d0 373 if (!irt)
10ebe1ab 374 irt = vrf_import_rt_new(&eval_tmp);
10ebe1ab
MK
375
376 /* Add VRF to the list for this RT. */
377 listnode_add(irt->vrfs, bgp_vrf);
378}
379
380/*
381 * Unmap specified VRF from specified RT. If there are no other
382 * VRFs for this RT, then the RT hash is deleted.
383 * bgp_vrf: BGP VRF specific instance
384 */
996c9314 385static void unmap_vrf_from_rt(struct bgp *bgp_vrf, struct vrf_irt_node *irt)
10ebe1ab
MK
386{
387 /* Delete VRF from list for this RT. */
388 listnode_delete(irt->vrfs, bgp_vrf);
389 if (!listnode_head(irt->vrfs)) {
bb7a24ab 390 list_delete_and_null(&irt->vrfs);
10ebe1ab
MK
391 vrf_import_rt_free(irt);
392 }
393}
394
128ea8ab 395/*
396 * Map one RT to specified VNI.
14c1a7bf 397 */
d62a17ae 398static void map_vni_to_rt(struct bgp *bgp, struct bgpevpn *vpn,
399 struct ecommunity_val *eval)
128ea8ab 400{
d62a17ae 401 struct irt_node *irt;
402 struct ecommunity_val eval_tmp;
128ea8ab 403
d62a17ae 404 /* If using "automatic" RT, we only care about the local-admin
405 * sub-field.
406 * This is to facilitate using VNI as the RT for EBGP peering too.
407 */
408 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
409 if (!is_import_rt_configured(vpn))
410 mask_ecom_global_admin(&eval_tmp, eval);
128ea8ab 411
d62a17ae 412 irt = lookup_import_rt(bgp, &eval_tmp);
413 if (irt && irt->vnis)
414 if (is_vni_present_in_irt_vnis(irt->vnis, vpn))
415 /* Already mapped. */
416 return;
128ea8ab 417
d62a17ae 418 if (!irt) {
419 irt = import_rt_new(bgp, &eval_tmp);
420 assert(irt);
421 }
128ea8ab 422
d62a17ae 423 /* Add VNI to the hash list for this RT. */
424 listnode_add(irt->vnis, vpn);
128ea8ab 425}
426
427/*
428 * Unmap specified VNI from specified RT. If there are no other
429 * VNIs for this RT, then the RT hash is deleted.
430 */
d62a17ae 431static void unmap_vni_from_rt(struct bgp *bgp, struct bgpevpn *vpn,
432 struct irt_node *irt)
14c1a7bf 433{
d62a17ae 434 /* Delete VNI from hash list for this RT. */
435 listnode_delete(irt->vnis, vpn);
436 if (!listnode_head(irt->vnis)) {
acdf5e25 437 list_delete_and_null(&irt->vnis);
d62a17ae 438 import_rt_free(bgp, irt);
439 }
14c1a7bf 440}
441
128ea8ab 442/*
443 * Create RT extended community automatically from passed information:
444 * of the form AS:VNI.
445 * NOTE: We use only the lower 16 bits of the AS. This is sufficient as
446 * the need is to get a RT value that will be unique across different
447 * VNIs but the same across routers (in the same AS) for a particular
448 * VNI.
449 */
c581d8b0 450static void form_auto_rt(struct bgp *bgp, vni_t vni, struct list *rtl)
128ea8ab 451{
d62a17ae 452 struct ecommunity_val eval;
453 struct ecommunity *ecomadd;
128ea8ab 454
c581d8b0 455 encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
128ea8ab 456
d62a17ae 457 ecomadd = ecommunity_new();
458 ecommunity_add_val(ecomadd, &eval);
459 listnode_add_sort(rtl, ecomadd);
128ea8ab 460}
14c1a7bf 461
462/*
128ea8ab 463 * Derive RD and RT for a VNI automatically. Invoked at the time of
464 * creation of a VNI.
465 */
d62a17ae 466static void derive_rd_rt_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 467{
d62a17ae 468 bgp_evpn_derive_auto_rd(bgp, vpn);
469 bgp_evpn_derive_auto_rt_import(bgp, vpn);
470 bgp_evpn_derive_auto_rt_export(bgp, vpn);
128ea8ab 471}
472
1ec31309 473/*
474 * Convert nexthop (remote VTEP IP) into an IPv6 address.
475 */
476static void evpn_convert_nexthop_to_ipv6(struct attr *attr)
477{
478 if (BGP_ATTR_NEXTHOP_AFI_IP6(attr))
479 return;
480 ipv4_to_ipv4_mapped_ipv6(&attr->mp_nexthop_global, attr->nexthop);
481 attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
482}
483
128ea8ab 484/*
485 * Add (update) or delete MACIP from zebra.
14c1a7bf 486 */
d62a17ae 487static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
488 struct prefix_evpn *p,
489 struct in_addr remote_vtep_ip, int add,
d7c0a89a 490 uint8_t flags)
d62a17ae 491{
492 struct stream *s;
493 int ipa_len;
494 char buf1[ETHER_ADDR_STRLEN];
495 char buf2[INET6_ADDRSTRLEN];
496 char buf3[INET6_ADDRSTRLEN];
497
498 /* Check socket. */
499 if (!zclient || zclient->sock < 0)
500 return 0;
501
502 /* Don't try to register if Zebra doesn't know of this instance. */
503 if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
504 return 0;
505
506 s = zclient->obuf;
507 stream_reset(s);
508
996c9314
LB
509 zclient_create_header(
510 s, add ? ZEBRA_REMOTE_MACIP_ADD : ZEBRA_REMOTE_MACIP_DEL,
511 bgp->vrf_id);
d62a17ae 512 stream_putl(s, vpn->vni);
28328ea9 513 stream_put(s, &p->prefix.mac.octet, ETH_ALEN); /* Mac Addr */
d62a17ae 514 /* IP address length and IP address, if any. */
515 if (IS_EVPN_PREFIX_IPADDR_NONE(p))
516 stream_putl(s, 0);
517 else {
518 ipa_len = IS_EVPN_PREFIX_IPADDR_V4(p) ? IPV4_MAX_BYTELEN
519 : IPV6_MAX_BYTELEN;
520 stream_putl(s, ipa_len);
521 stream_put(s, &p->prefix.ip.ip.addr, ipa_len);
522 }
523 stream_put_in_addr(s, &remote_vtep_ip);
524
ead40654 525 /* TX flags - MAC sticky status and/or gateway mac */
d62a17ae 526 if (add)
ead40654 527 stream_putc(s, flags);
d62a17ae 528
529 stream_putw_at(s, 0, stream_get_endp(s));
530
531 if (bgp_debug_zebra(NULL))
996c9314
LB
532 zlog_debug(
533 "Tx %s MACIP, VNI %u MAC %s IP %s (flags: 0x%x) remote VTEP %s",
534 add ? "ADD" : "DEL", vpn->vni,
535 prefix_mac2str(&p->prefix.mac, buf1, sizeof(buf1)),
536 ipaddr2str(&p->prefix.ip, buf3, sizeof(buf3)), flags,
537 inet_ntop(AF_INET, &remote_vtep_ip, buf2,
538 sizeof(buf2)));
d62a17ae 539
540 return zclient_send_message(zclient);
7ef5a232 541}
b18825eb 542
128ea8ab 543/*
544 * Add (update) or delete remote VTEP from zebra.
545 */
d62a17ae 546static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
547 struct prefix_evpn *p, int add)
128ea8ab 548{
d62a17ae 549 struct stream *s;
128ea8ab 550
d62a17ae 551 /* Check socket. */
552 if (!zclient || zclient->sock < 0)
553 return 0;
128ea8ab 554
d62a17ae 555 /* Don't try to register if Zebra doesn't know of this instance. */
556 if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
557 return 0;
128ea8ab 558
d62a17ae 559 s = zclient->obuf;
560 stream_reset(s);
128ea8ab 561
996c9314
LB
562 zclient_create_header(
563 s, add ? ZEBRA_REMOTE_VTEP_ADD : ZEBRA_REMOTE_VTEP_DEL,
564 bgp->vrf_id);
d62a17ae 565 stream_putl(s, vpn->vni);
566 if (IS_EVPN_PREFIX_IPADDR_V4(p))
567 stream_put_in_addr(s, &p->prefix.ip.ipaddr_v4);
568 else if (IS_EVPN_PREFIX_IPADDR_V6(p)) {
569 zlog_err(
570 "Bad remote IP when trying to %s remote VTEP for VNI %u",
571 add ? "ADD" : "DEL", vpn->vni);
572 return -1;
573 }
128ea8ab 574
d62a17ae 575 stream_putw_at(s, 0, stream_get_endp(s));
128ea8ab 576
d62a17ae 577 if (bgp_debug_zebra(NULL))
578 zlog_debug("Tx %s Remote VTEP, VNI %u remote VTEP %s",
579 add ? "ADD" : "DEL", vpn->vni,
580 inet_ntoa(p->prefix.ip.ipaddr_v4));
128ea8ab 581
d62a17ae 582 return zclient_send_message(zclient);
128ea8ab 583}
584
342dd0c6 585/*
586 * Build extended communities for EVPN prefix route.
587 */
588static void build_evpn_type5_route_extcomm(struct bgp *bgp_vrf,
589 struct attr *attr)
590{
591 struct ecommunity ecom_encap;
592 struct ecommunity ecom_rmac;
593 struct ecommunity_val eval;
594 struct ecommunity_val eval_rmac;
595 bgp_encap_types tnl_type;
596 struct listnode *node, *nnode;
597 struct ecommunity *ecom;
598 struct list *vrf_export_rtl = NULL;
599
600 /* Encap */
601 tnl_type = BGP_ENCAP_TYPE_VXLAN;
602 memset(&ecom_encap, 0, sizeof(ecom_encap));
603 encode_encap_extcomm(tnl_type, &eval);
604 ecom_encap.size = 1;
d7c0a89a 605 ecom_encap.val = (uint8_t *)eval.val;
342dd0c6 606
607 /* Add Encap */
608 attr->ecommunity = ecommunity_dup(&ecom_encap);
609
610 /* Add the export RTs for L3VNI/VRF */
611 vrf_export_rtl = bgp_vrf->vrf_export_rtl;
612 if (vrf_export_rtl && !list_isempty(vrf_export_rtl)) {
613 for (ALL_LIST_ELEMENTS(vrf_export_rtl, node, nnode, ecom))
996c9314
LB
614 attr->ecommunity =
615 ecommunity_merge(attr->ecommunity, ecom);
342dd0c6 616 }
617
618 /* add the router mac extended community */
619 if (!is_zero_mac(&attr->rmac)) {
620 memset(&ecom_rmac, 0, sizeof(ecom_rmac));
621 encode_rmac_extcomm(&eval_rmac, &attr->rmac);
622 ecom_rmac.size = 1;
623 ecom_rmac.val = (uint8_t *)eval_rmac.val;
996c9314
LB
624 attr->ecommunity =
625 ecommunity_merge(attr->ecommunity, &ecom_rmac);
342dd0c6 626 }
627
628 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
629}
630
128ea8ab 631/*
1ec31309 632 * Build extended communities for EVPN route.
633 * This function is applicable for type-2 and type-3 routes. The layer-2 RT
634 * and ENCAP extended communities are applicable for all routes.
635 * The default gateway extended community and MAC mobility (sticky) extended
636 * community are added as needed based on passed settings - only for type-2
637 * routes. Likewise, the layer-3 RT and Router MAC extended communities are
638 * added, if present, based on passed settings - only for non-link-local
639 * type-2 routes.
128ea8ab 640 */
7ec156a9 641static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
1ec31309 642 int add_l3_ecomm)
128ea8ab 643{
d62a17ae 644 struct ecommunity ecom_encap;
645 struct ecommunity ecom_sticky;
ead40654 646 struct ecommunity ecom_default_gw;
bc59a672 647 struct ecommunity ecom_rmac;
d62a17ae 648 struct ecommunity_val eval;
649 struct ecommunity_val eval_sticky;
ead40654 650 struct ecommunity_val eval_default_gw;
bc59a672 651 struct ecommunity_val eval_rmac;
d62a17ae 652 bgp_encap_types tnl_type;
653 struct listnode *node, *nnode;
654 struct ecommunity *ecom;
d7c0a89a 655 uint32_t seqnum;
7a3e76f1 656 struct list *vrf_export_rtl = NULL;
128ea8ab 657
d62a17ae 658 /* Encap */
659 tnl_type = BGP_ENCAP_TYPE_VXLAN;
660 memset(&ecom_encap, 0, sizeof(ecom_encap));
661 encode_encap_extcomm(tnl_type, &eval);
662 ecom_encap.size = 1;
d7c0a89a 663 ecom_encap.val = (uint8_t *)eval.val;
128ea8ab 664
d62a17ae 665 /* Add Encap */
666 attr->ecommunity = ecommunity_dup(&ecom_encap);
128ea8ab 667
7a3e76f1 668 /* Add the export RTs for L2VNI */
d62a17ae 669 for (ALL_LIST_ELEMENTS(vpn->export_rtl, node, nnode, ecom))
670 attr->ecommunity = ecommunity_merge(attr->ecommunity, ecom);
128ea8ab 671
1ec31309 672 /* Add the export RTs for L3VNI if told to - caller determines
673 * when this should be done.
523cafc4 674 */
1ec31309 675 if (add_l3_ecomm) {
7ec156a9
MK
676 vrf_export_rtl = bgpevpn_get_vrf_export_rtl(vpn);
677 if (vrf_export_rtl && !list_isempty(vrf_export_rtl)) {
678 for (ALL_LIST_ELEMENTS(vrf_export_rtl, node, nnode,
679 ecom))
996c9314
LB
680 attr->ecommunity = ecommunity_merge(
681 attr->ecommunity, ecom);
7ec156a9 682 }
f1f8b53c 683 }
7a3e76f1 684
1ec31309 685 /* Add MAC mobility (sticky) if needed. */
d62a17ae 686 if (attr->sticky) {
687 seqnum = 0;
688 memset(&ecom_sticky, 0, sizeof(ecom_sticky));
689 encode_mac_mobility_extcomm(1, seqnum, &eval_sticky);
690 ecom_sticky.size = 1;
d7c0a89a 691 ecom_sticky.val = (uint8_t *)eval_sticky.val;
d62a17ae 692 attr->ecommunity =
693 ecommunity_merge(attr->ecommunity, &ecom_sticky);
694 }
c85c03c7 695
1ec31309 696 /* Add RMAC, if told to. */
697 if (add_l3_ecomm) {
bc59a672
MK
698 memset(&ecom_rmac, 0, sizeof(ecom_rmac));
699 encode_rmac_extcomm(&eval_rmac, &attr->rmac);
700 ecom_rmac.size = 1;
701 ecom_rmac.val = (uint8_t *)eval_rmac.val;
996c9314
LB
702 attr->ecommunity =
703 ecommunity_merge(attr->ecommunity, &ecom_rmac);
bc59a672
MK
704 }
705
1ec31309 706 /* Add default gateway, if needed. */
ead40654
MK
707 if (attr->default_gw) {
708 memset(&ecom_default_gw, 0, sizeof(ecom_default_gw));
709 encode_default_gw_extcomm(&eval_default_gw);
710 ecom_default_gw.size = 1;
711 ecom_default_gw.val = (uint8_t *)eval_default_gw.val;
996c9314
LB
712 attr->ecommunity =
713 ecommunity_merge(attr->ecommunity, &ecom_default_gw);
ead40654
MK
714 }
715
d62a17ae 716 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
128ea8ab 717}
718
719/*
720 * Add MAC mobility extended community to attribute.
721 */
d7c0a89a 722static void add_mac_mobility_to_attr(uint32_t seq_num, struct attr *attr)
d62a17ae 723{
724 struct ecommunity ecom_tmp;
725 struct ecommunity_val eval;
d7c0a89a 726 uint8_t *ecom_val_ptr;
d62a17ae 727 int i;
d7c0a89a 728 uint8_t *pnt;
d62a17ae 729 int type = 0;
730 int sub_type = 0;
731
732 /* Build MM */
733 encode_mac_mobility_extcomm(0, seq_num, &eval);
734
735 /* Find current MM ecommunity */
421bb26a 736 ecom_val_ptr = NULL;
d62a17ae 737
738 if (attr->ecommunity) {
739 for (i = 0; i < attr->ecommunity->size; i++) {
740 pnt = attr->ecommunity->val + (i * 8);
741 type = *pnt++;
742 sub_type = *pnt++;
743
744 if (type == ECOMMUNITY_ENCODE_EVPN
745 && sub_type
746 == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY) {
d7c0a89a
QY
747 ecom_val_ptr = (uint8_t *)(attr->ecommunity->val
748 + (i * 8));
d62a17ae 749 break;
750 }
751 }
752 }
753
754 /* Update the existing MM ecommunity */
421bb26a
MK
755 if (ecom_val_ptr) {
756 memcpy(ecom_val_ptr, eval.val, sizeof(char) * ECOMMUNITY_SIZE);
d62a17ae 757 }
758 /* Add MM to existing */
759 else {
760 memset(&ecom_tmp, 0, sizeof(ecom_tmp));
761 ecom_tmp.size = 1;
d7c0a89a 762 ecom_tmp.val = (uint8_t *)eval.val;
d62a17ae 763
764 attr->ecommunity =
765 ecommunity_merge(attr->ecommunity, &ecom_tmp);
766 }
128ea8ab 767}
768
769/* Install EVPN route into zebra. */
d62a17ae 770static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn,
771 struct prefix_evpn *p,
d7c0a89a 772 struct in_addr remote_vtep_ip, uint8_t flags)
128ea8ab 773{
d62a17ae 774 int ret;
128ea8ab 775
d62a17ae 776 if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
777 ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip,
ead40654 778 1, flags);
d62a17ae 779 else
780 ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 1);
128ea8ab 781
d62a17ae 782 return ret;
128ea8ab 783}
784
785/* Uninstall EVPN route from zebra. */
d62a17ae 786static int evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn,
787 struct prefix_evpn *p,
788 struct in_addr remote_vtep_ip)
128ea8ab 789{
d62a17ae 790 int ret;
128ea8ab 791
d62a17ae 792 if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
793 ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip,
794 0, 0);
795 else
796 ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 0);
128ea8ab 797
d62a17ae 798 return ret;
128ea8ab 799}
800
801/*
802 * Due to MAC mobility, the prior "local" best route has been supplanted
803 * by a "remote" best route. The prior route has to be deleted and withdrawn
804 * from peers.
805 */
d62a17ae 806static void evpn_delete_old_local_route(struct bgp *bgp, struct bgpevpn *vpn,
807 struct bgp_node *rn,
808 struct bgp_info *old_local)
128ea8ab 809{
d62a17ae 810 struct bgp_node *global_rn;
811 struct bgp_info *ri;
812 afi_t afi = AFI_L2VPN;
813 safi_t safi = SAFI_EVPN;
128ea8ab 814
d62a17ae 815 /* Locate route node in the global EVPN routing table. Note that
816 * this table is a 2-level tree (RD-level + Prefix-level) similar to
817 * L3VPN routes.
818 */
819 global_rn = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi,
820 (struct prefix *)&rn->p, &vpn->prd);
821 if (global_rn) {
822 /* Delete route entry in the global EVPN table. */
823 delete_evpn_route_entry(bgp, vpn, afi, safi, global_rn, &ri);
128ea8ab 824
d62a17ae 825 /* Schedule for processing - withdraws to peers happen from
826 * this table.
827 */
828 if (ri)
829 bgp_process(bgp, global_rn, afi, safi);
830 bgp_unlock_node(global_rn);
831 }
128ea8ab 832
d62a17ae 833 /* Delete route entry in the VNI route table, caller to remove. */
834 bgp_info_delete(rn, old_local);
128ea8ab 835}
836
837/*
838 * Calculate the best path for an EVPN route. Install/update best path in zebra,
839 * if appropriate.
840 */
d62a17ae 841static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
842 struct bgp_node *rn)
843{
844 struct bgp_info *old_select, *new_select;
845 struct bgp_info_pair old_and_new;
846 afi_t afi = AFI_L2VPN;
847 safi_t safi = SAFI_EVPN;
848 int ret = 0;
d7c0a89a 849 uint8_t flags = 0;
d62a17ae 850
851 /* Compute the best path. */
852 bgp_best_selection(bgp, rn, &bgp->maxpaths[afi][safi], &old_and_new,
853 afi, safi);
854 old_select = old_and_new.old;
855 new_select = old_and_new.new;
856
857 /* If the best path hasn't changed - see if there is still something to
858 * update
859 * to zebra RIB.
860 */
861 if (old_select && old_select == new_select
862 && old_select->type == ZEBRA_ROUTE_BGP
90f4f482 863 && old_select->sub_type == BGP_ROUTE_IMPORTED
d62a17ae 864 && !CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR)
865 && !CHECK_FLAG(old_select->flags, BGP_INFO_ATTR_CHANGED)
866 && !bgp->addpath_tx_used[afi][safi]) {
ead40654
MK
867 if (bgp_zebra_has_route_changed(rn, old_select)) {
868 if (old_select->attr->sticky)
869 SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
870 if (old_select->attr->default_gw)
871 SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
996c9314
LB
872 ret = evpn_zebra_install(
873 bgp, vpn, (struct prefix_evpn *)&rn->p,
874 old_select->attr->nexthop, flags);
ead40654 875 }
d62a17ae 876 UNSET_FLAG(old_select->flags, BGP_INFO_MULTIPATH_CHG);
877 bgp_zebra_clear_route_change_flags(rn);
878 return ret;
879 }
880
881 /* If the user did a "clear" this flag will be set */
882 UNSET_FLAG(rn->flags, BGP_NODE_USER_CLEAR);
883
884 /* bestpath has changed; update relevant fields and install or uninstall
885 * into the zebra RIB.
886 */
887 if (old_select || new_select)
888 bgp_bump_version(rn);
889
890 if (old_select)
891 bgp_info_unset_flag(rn, old_select, BGP_INFO_SELECTED);
892 if (new_select) {
893 bgp_info_set_flag(rn, new_select, BGP_INFO_SELECTED);
894 bgp_info_unset_flag(rn, new_select, BGP_INFO_ATTR_CHANGED);
895 UNSET_FLAG(new_select->flags, BGP_INFO_MULTIPATH_CHG);
896 }
897
898 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
90f4f482 899 && new_select->sub_type == BGP_ROUTE_IMPORTED) {
ead40654
MK
900 flags = 0;
901 if (new_select->attr->sticky)
902 SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
903 if (new_select->attr->default_gw)
904 SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
d62a17ae 905 ret = evpn_zebra_install(bgp, vpn, (struct prefix_evpn *)&rn->p,
996c9314 906 new_select->attr->nexthop, flags);
d62a17ae 907 /* If an old best existed and it was a "local" route, the only
908 * reason
909 * it would be supplanted is due to MAC mobility procedures. So,
910 * we
911 * need to do an implicit delete and withdraw that route from
912 * peers.
913 */
914 if (old_select && old_select->peer == bgp->peer_self
915 && old_select->type == ZEBRA_ROUTE_BGP
916 && old_select->sub_type == BGP_ROUTE_STATIC)
917 evpn_delete_old_local_route(bgp, vpn, rn, old_select);
918 } else {
919 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
90f4f482 920 && old_select->sub_type == BGP_ROUTE_IMPORTED)
d62a17ae 921 ret = evpn_zebra_uninstall(bgp, vpn,
922 (struct prefix_evpn *)&rn->p,
923 old_select->attr->nexthop);
924 }
925
926 /* Clear any route change flags. */
927 bgp_zebra_clear_route_change_flags(rn);
928
929 /* Reap old select bgp_info, if it has been removed */
930 if (old_select && CHECK_FLAG(old_select->flags, BGP_INFO_REMOVED))
931 bgp_info_reap(rn, old_select);
932
933 return ret;
128ea8ab 934}
935
ead40654
MK
936/*
937 * Return true if the local ri for this rn is of type gateway mac
938 */
939static int evpn_route_is_def_gw(struct bgp *bgp, struct bgp_node *rn)
940{
996c9314
LB
941 struct bgp_info *tmp_ri = NULL;
942 struct bgp_info *local_ri = NULL;
ead40654
MK
943
944 local_ri = NULL;
945 for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) {
946 if (tmp_ri->peer == bgp->peer_self
947 && tmp_ri->type == ZEBRA_ROUTE_BGP
948 && tmp_ri->sub_type == BGP_ROUTE_STATIC)
949 local_ri = tmp_ri;
950 }
951
952 if (!local_ri)
953 return 0;
954
955 return local_ri->attr->default_gw;
956}
957
c85c03c7 958
959/*
960 * Return true if the local ri for this rn has sticky set
961 */
d62a17ae 962static int evpn_route_is_sticky(struct bgp *bgp, struct bgp_node *rn)
c85c03c7 963{
d62a17ae 964 struct bgp_info *tmp_ri;
965 struct bgp_info *local_ri;
c85c03c7 966
d62a17ae 967 local_ri = NULL;
968 for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) {
969 if (tmp_ri->peer == bgp->peer_self
970 && tmp_ri->type == ZEBRA_ROUTE_BGP
971 && tmp_ri->sub_type == BGP_ROUTE_STATIC)
972 local_ri = tmp_ri;
973 }
c85c03c7 974
d62a17ae 975 if (!local_ri)
976 return 0;
c85c03c7 977
d62a17ae 978 return local_ri->attr->sticky;
c85c03c7 979}
980
342dd0c6 981static int update_evpn_type5_route_entry(struct bgp *bgp_def,
982 struct bgp *bgp_vrf, afi_t afi,
983 safi_t safi, struct bgp_node *rn,
5424b7ba 984 struct attr *attr, int *route_changed)
342dd0c6 985{
986 struct attr *attr_new = NULL;
987 struct bgp_info *ri = NULL;
988 mpls_label_t label = MPLS_INVALID_LABEL;
989 struct bgp_info *local_ri = NULL;
990 struct bgp_info *tmp_ri = NULL;
991
5424b7ba 992 *route_changed = 0;
342dd0c6 993 /* locate the local route entry if any */
994 for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) {
995 if (tmp_ri->peer == bgp_def->peer_self
996 && tmp_ri->type == ZEBRA_ROUTE_BGP
997 && tmp_ri->sub_type == BGP_ROUTE_STATIC)
998 local_ri = tmp_ri;
999 }
1000
1001 /* create a new route entry if one doesnt exist.
523cafc4 1002 Otherwise see if route attr has changed
1003 */
342dd0c6 1004 if (!local_ri) {
1005
5424b7ba
MK
1006 /* route has changed as this is the first entry */
1007 *route_changed = 1;
1008
342dd0c6 1009 /* Add (or update) attribute to hash. */
1010 attr_new = bgp_attr_intern(attr);
1011
1012 /* create the route info from attribute */
1013 ri = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0,
1014 bgp_def->peer_self, attr_new, rn);
1015 SET_FLAG(ri->flags, BGP_INFO_VALID);
1016
b57ba6d2 1017 /* Type-5 routes advertise the L3-VNI */
342dd0c6 1018 bgp_info_extra_get(ri);
1019 vni2label(bgp_vrf->l3vni, &label);
b57ba6d2
MK
1020 memcpy(&ri->extra->label, &label, sizeof(label));
1021 ri->extra->num_labels = 1;
342dd0c6 1022
1023 /* add the route entry to route node*/
1024 bgp_info_add(rn, ri);
1025 } else {
1026
1027 tmp_ri = local_ri;
1028 if (!attrhash_cmp(tmp_ri->attr, attr)) {
5424b7ba
MK
1029
1030 /* attribute changed */
1031 *route_changed = 1;
1032
342dd0c6 1033 /* The attribute has changed. */
1034 /* Add (or update) attribute to hash. */
1035 attr_new = bgp_attr_intern(attr);
1036 bgp_info_set_flag(rn, tmp_ri, BGP_INFO_ATTR_CHANGED);
1037
1038 /* Restore route, if needed. */
1039 if (CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED))
1040 bgp_info_restore(rn, tmp_ri);
1041
1042 /* Unintern existing, set to new. */
1043 bgp_attr_unintern(&tmp_ri->attr);
1044 tmp_ri->attr = attr_new;
1045 tmp_ri->uptime = bgp_clock();
1046 }
1047 }
1048 return 0;
1049}
1050
1051/* update evpn type-5 route entry */
996c9314
LB
1052static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp,
1053 struct attr *src_attr)
342dd0c6 1054{
1055 afi_t afi = AFI_L2VPN;
1056 safi_t safi = SAFI_EVPN;
1057 struct attr attr;
1058 struct bgp_node *rn = NULL;
1059 struct bgp *bgp_def = NULL;
5424b7ba 1060 int route_changed = 0;
342dd0c6 1061
1062 bgp_def = bgp_get_default();
1063 if (!bgp_def)
faafdfa8 1064 return 0;
342dd0c6 1065
2f69f6d3 1066 /* Build path attribute for this route - use the source attr, if
1067 * present, else treat as locally originated.
1068 */
1069 if (src_attr)
1070 bgp_attr_dup(&attr, src_attr);
1071 else {
1072 memset(&attr, 0, sizeof(struct attr));
1073 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
1074 }
1075 /* Set nexthop to ourselves and fill in the Router MAC. */
342dd0c6 1076 attr.nexthop = bgp_vrf->originator_ip;
1077 attr.mp_nexthop_global_in = bgp_vrf->originator_ip;
1078 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
1079 memcpy(&attr.rmac, &bgp_vrf->rmac, sizeof(struct ethaddr));
1080
1081 /* Setup RT and encap extended community */
1082 build_evpn_type5_route_extcomm(bgp_vrf, &attr);
1083
1084 /* get the route node in global table */
1085 rn = bgp_afi_node_get(bgp_def->rib[afi][safi], afi, safi,
996c9314 1086 (struct prefix *)evp, &bgp_vrf->vrf_prd);
342dd0c6 1087 assert(rn);
1088
1089 /* create or update the route entry within the route node */
996c9314
LB
1090 update_evpn_type5_route_entry(bgp_def, bgp_vrf, afi, safi, rn, &attr,
1091 &route_changed);
342dd0c6 1092
1093 /* schedule for processing and unlock node */
5424b7ba
MK
1094 if (route_changed) {
1095 bgp_process(bgp_def, rn, afi, safi);
1096 bgp_unlock_node(rn);
1097 }
342dd0c6 1098
1099 /* uninten temporary */
5ee65f6f 1100 if (!src_attr)
1101 aspath_unintern(&attr.aspath);
342dd0c6 1102 return 0;
1103}
1104
128ea8ab 1105/*
1106 * Create or update EVPN route entry. This could be in the VNI route table
1107 * or the global route table.
1108 */
d62a17ae 1109static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
1110 afi_t afi, safi_t safi, struct bgp_node *rn,
1111 struct attr *attr, int add, int vni_table,
d7c0a89a 1112 struct bgp_info **ri, uint8_t flags)
d62a17ae 1113{
1114 struct bgp_info *tmp_ri;
1115 struct bgp_info *local_ri, *remote_ri;
1116 struct attr *attr_new;
b57ba6d2 1117 mpls_label_t label[BGP_MAX_LABELS];
d7c0a89a 1118 uint32_t num_labels = 1;
d62a17ae 1119 int route_change = 1;
d7c0a89a 1120 uint8_t sticky = 0;
b57ba6d2 1121 struct prefix_evpn *evp;
d62a17ae 1122
1123 *ri = NULL;
b57ba6d2
MK
1124 evp = (struct prefix_evpn *)&rn->p;
1125 memset(&label, 0, sizeof(label));
d62a17ae 1126
1127 /* See if this is an update of an existing route, or a new add. Also,
1128 * identify if already known from remote, and if so, the one with the
1129 * highest sequence number; this is only when adding to the VNI routing
1130 * table.
1131 */
1132 local_ri = remote_ri = NULL;
1133 for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) {
1134 if (tmp_ri->peer == bgp->peer_self
1135 && tmp_ri->type == ZEBRA_ROUTE_BGP
1136 && tmp_ri->sub_type == BGP_ROUTE_STATIC)
1137 local_ri = tmp_ri;
1138 if (vni_table) {
1139 if (tmp_ri->type == ZEBRA_ROUTE_BGP
90f4f482 1140 && tmp_ri->sub_type == BGP_ROUTE_IMPORTED
d62a17ae 1141 && CHECK_FLAG(tmp_ri->flags, BGP_INFO_VALID)) {
1142 if (!remote_ri)
1143 remote_ri = tmp_ri;
1144 else if (mac_mobility_seqnum(tmp_ri->attr)
1145 > mac_mobility_seqnum(remote_ri->attr))
1146 remote_ri = tmp_ri;
1147 }
1148 }
1149 }
1150
1151 /* If route doesn't exist already, create a new one, if told to.
1152 * Otherwise act based on whether the attributes of the route have
1153 * changed or not.
1154 */
1155 if (!local_ri && !add)
1156 return 0;
1157
1158 if (!local_ri) {
1159 /* When learnt locally for the first time but already known from
1160 * remote, we have to initiate appropriate MAC mobility steps.
1161 * This
1162 * is applicable when updating the VNI routing table.
1a98c087
MK
1163 * We need to skip mobility steps for g/w macs (local mac on g/w
1164 * SVI) advertised in EVPN.
1165 * This will ensure that local routes are preferred for g/w macs
d62a17ae 1166 */
ead40654 1167 if (remote_ri && !CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) {
d7c0a89a 1168 uint32_t cur_seqnum;
d62a17ae 1169
1170 /* Add MM extended community to route. */
1171 cur_seqnum = mac_mobility_seqnum(remote_ri->attr);
1172 add_mac_mobility_to_attr(cur_seqnum + 1, attr);
1173 }
1174
1175 /* Add (or update) attribute to hash. */
1176 attr_new = bgp_attr_intern(attr);
1177
1178 /* Extract MAC mobility sequence number, if any. */
1179 attr_new->mm_seqnum =
1180 bgp_attr_mac_mobility_seqnum(attr_new, &sticky);
1181 attr_new->sticky = sticky;
1182
1183 /* Create new route with its attribute. */
1184 tmp_ri = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0,
1185 bgp->peer_self, attr_new, rn);
1186 SET_FLAG(tmp_ri->flags, BGP_INFO_VALID);
1187 bgp_info_extra_get(tmp_ri);
1188
1189 /* The VNI goes into the 'label' field of the route */
b57ba6d2 1190 vni2label(vpn->vni, &label[0]);
c48d9f5f
MK
1191
1192 /* Type-2 routes may carry a second VNI - the L3-VNI.
1193 * Only attach second label if we are advertising two labels for
1194 * type-2 routes.
1195 */
996c9314
LB
1196 if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
1197 && CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) {
b57ba6d2
MK
1198 vni_t l3vni;
1199
1200 l3vni = bgpevpn_get_l3vni(vpn);
1201 if (l3vni) {
1202 vni2label(l3vni, &label[1]);
1203 num_labels++;
1204 }
1205 }
d62a17ae 1206
b57ba6d2
MK
1207 memcpy(&tmp_ri->extra->label, label, sizeof(label));
1208 tmp_ri->extra->num_labels = num_labels;
d62a17ae 1209 bgp_info_add(rn, tmp_ri);
1210 } else {
1211 tmp_ri = local_ri;
1212 if (attrhash_cmp(tmp_ri->attr, attr)
1213 && !CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED))
1214 route_change = 0;
1215 else {
c48d9f5f
MK
1216 /*
1217 * The attributes have changed, type-2 routes needs to
1218 * be advertised with right labels.
1219 */
1220 vni2label(vpn->vni, &label[0]);
996c9314
LB
1221 if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
1222 && CHECK_FLAG(vpn->flags,
1223 VNI_FLAG_USE_TWO_LABELS)) {
c48d9f5f
MK
1224 vni_t l3vni;
1225
1226 l3vni = bgpevpn_get_l3vni(vpn);
1227 if (l3vni) {
1228 vni2label(l3vni, &label[1]);
1229 num_labels++;
1230 }
1231 }
1232 memcpy(&tmp_ri->extra->label, label, sizeof(label));
1233 tmp_ri->extra->num_labels = num_labels;
1234
d62a17ae 1235 /* The attribute has changed. */
1236 /* Add (or update) attribute to hash. */
1237 attr_new = bgp_attr_intern(attr);
1238 bgp_info_set_flag(rn, tmp_ri, BGP_INFO_ATTR_CHANGED);
1239
1240 /* Restore route, if needed. */
1241 if (CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED))
1242 bgp_info_restore(rn, tmp_ri);
1243
1244 /* Unintern existing, set to new. */
1245 bgp_attr_unintern(&tmp_ri->attr);
1246 tmp_ri->attr = attr_new;
1247 tmp_ri->uptime = bgp_clock();
1248 }
1249 }
1250
1251 /* Return back the route entry. */
1252 *ri = tmp_ri;
1253 return route_change;
128ea8ab 1254}
1255
1256/*
1257 * Create or update EVPN route (of type based on prefix) for specified VNI
1258 * and schedule for processing.
1259 */
d62a17ae 1260static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
d7c0a89a 1261 struct prefix_evpn *p, uint8_t flags)
128ea8ab 1262{
d62a17ae 1263 struct bgp_node *rn;
1264 struct attr attr;
1265 struct attr *attr_new;
1ec31309 1266 int add_l3_ecomm = 0;
d62a17ae 1267 struct bgp_info *ri;
1268 afi_t afi = AFI_L2VPN;
1269 safi_t safi = SAFI_EVPN;
1270 int route_change;
128ea8ab 1271
d62a17ae 1272 memset(&attr, 0, sizeof(struct attr));
128ea8ab 1273
d62a17ae 1274 /* Build path-attribute for this route. */
1275 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
1276 attr.nexthop = vpn->originator_ip;
1277 attr.mp_nexthop_global_in = vpn->originator_ip;
1278 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
317f1fe0 1279 attr.sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY) ? 1 : 0;
ead40654 1280 attr.default_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW) ? 1 : 0;
be41eb68
MK
1281
1282 /* PMSI is only needed for type-3 routes */
1283 if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE)
1284 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL);
1285
1ec31309 1286 /* router mac is only needed for type-2 routes here. */
be41eb68
MK
1287 if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
1288 bgpevpn_get_rmac(vpn, &attr.rmac);
a21bd7a3 1289 vni2label(vpn->vni, &(attr.label));
128ea8ab 1290
1ec31309 1291 /* Include L3 VNI related RTs and RMAC for type-2 routes, if they're
1292 * IPv4 or IPv6 global addresses and we're advertising L3VNI with
1293 * these routes.
1294 */
1295 if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE &&
1296 (IS_EVPN_PREFIX_IPADDR_V4(p) ||
1297 !IN6_IS_ADDR_LINKLOCAL(&p->prefix.ip.ipaddr_v6)) &&
1298 CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS))
1299 add_l3_ecomm = 1;
1300
1301 /* Set up extended community. */
1302 build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm);
128ea8ab 1303
d62a17ae 1304 /* First, create (or fetch) route node within the VNI. */
1305 /* NOTE: There is no RD here. */
1306 rn = bgp_node_get(vpn->route_table, (struct prefix *)p);
128ea8ab 1307
d62a17ae 1308 /* Create or update route entry. */
1309 route_change = update_evpn_route_entry(bgp, vpn, afi, safi, rn, &attr,
1a98c087 1310 1, 1, &ri, flags);
d62a17ae 1311 assert(ri);
1312 attr_new = ri->attr;
128ea8ab 1313
d62a17ae 1314 /* Perform route selection; this is just to set the flags correctly
1315 * as local route in the VNI always wins.
1316 */
1317 evpn_route_select_install(bgp, vpn, rn);
1318 bgp_unlock_node(rn);
128ea8ab 1319
d62a17ae 1320 /* If this is a new route or some attribute has changed, export the
1321 * route to the global table. The route will be advertised to peers
1322 * from there. Note that this table is a 2-level tree (RD-level +
1323 * Prefix-level) similar to L3VPN routes.
1324 */
1325 if (route_change) {
1326 struct bgp_info *global_ri;
128ea8ab 1327
d62a17ae 1328 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
1329 (struct prefix *)p, &vpn->prd);
1330 update_evpn_route_entry(bgp, vpn, afi, safi, rn, attr_new, 1, 0,
1a98c087 1331 &global_ri, flags);
128ea8ab 1332
d62a17ae 1333 /* Schedule for processing and unlock node. */
1334 bgp_process(bgp, rn, afi, safi);
1335 bgp_unlock_node(rn);
1336 }
128ea8ab 1337
d62a17ae 1338 /* Unintern temporary. */
1339 aspath_unintern(&attr.aspath);
128ea8ab 1340
d62a17ae 1341 return 0;
128ea8ab 1342}
1343
342dd0c6 1344/* Delete EVPN type5 route entry from global table */
1345static void delete_evpn_type5_route_entry(struct bgp *bgp_def,
996c9314
LB
1346 struct bgp *bgp_vrf, afi_t afi,
1347 safi_t safi, struct bgp_node *rn,
342dd0c6 1348 struct bgp_info **ri)
1349{
1350 struct bgp_info *tmp_ri = NULL;
1351
1352 *ri = NULL;
1353
1354 /* find the matching route entry */
1355 for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next)
1356 if (tmp_ri->peer == bgp_def->peer_self
1357 && tmp_ri->type == ZEBRA_ROUTE_BGP
1358 && tmp_ri->sub_type == BGP_ROUTE_STATIC)
1359 break;
1360
1361 *ri = tmp_ri;
1362
1363 /* Mark route for delete. */
1364 if (tmp_ri)
1365 bgp_info_delete(rn, tmp_ri);
1366}
1367
1368/* Delete EVPN type5 route */
996c9314 1369static int delete_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp)
342dd0c6 1370{
1371 afi_t afi = AFI_L2VPN;
1372 safi_t safi = SAFI_EVPN;
1373 struct bgp_node *rn = NULL;
1374 struct bgp_info *ri = NULL;
1375 struct bgp *bgp_def = NULL; /* default bgp instance */
1376
1377 bgp_def = bgp_get_default();
1378 if (!bgp_def)
faafdfa8 1379 return 0;
342dd0c6 1380
1381 /* locate the global route entry for this type-5 prefix */
1382 rn = bgp_afi_node_lookup(bgp_def->rib[afi][safi], afi, safi,
1383 (struct prefix *)evp, &bgp_vrf->vrf_prd);
1384 if (!rn)
1385 return 0;
1386
1387 delete_evpn_type5_route_entry(bgp_def, bgp_vrf, afi, safi, rn, &ri);
1388 if (ri)
1389 bgp_process(bgp_def, rn, afi, safi);
1390 bgp_unlock_node(rn);
1391 return 0;
1392}
1393
128ea8ab 1394/*
1395 * Delete EVPN route entry. This could be in the VNI route table
1396 * or the global route table.
1397 */
d62a17ae 1398static void delete_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
1399 afi_t afi, safi_t safi, struct bgp_node *rn,
1400 struct bgp_info **ri)
128ea8ab 1401{
d62a17ae 1402 struct bgp_info *tmp_ri;
128ea8ab 1403
d62a17ae 1404 *ri = NULL;
128ea8ab 1405
d62a17ae 1406 /* Now, find matching route. */
1407 for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next)
1408 if (tmp_ri->peer == bgp->peer_self
1409 && tmp_ri->type == ZEBRA_ROUTE_BGP
1410 && tmp_ri->sub_type == BGP_ROUTE_STATIC)
1411 break;
128ea8ab 1412
d62a17ae 1413 *ri = tmp_ri;
128ea8ab 1414
d62a17ae 1415 /* Mark route for delete. */
1416 if (tmp_ri)
1417 bgp_info_delete(rn, tmp_ri);
128ea8ab 1418}
1419
1420/*
1421 * Delete EVPN route (of type based on prefix) for specified VNI and
1422 * schedule for processing.
1423 */
d62a17ae 1424static int delete_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
1425 struct prefix_evpn *p)
1426{
1427 struct bgp_node *rn, *global_rn;
1428 struct bgp_info *ri;
1429 afi_t afi = AFI_L2VPN;
1430 safi_t safi = SAFI_EVPN;
1431
1432 /* First, locate the route node within the VNI. If it doesn't exist,
1433 * there
1434 * is nothing further to do.
1435 */
1436 /* NOTE: There is no RD here. */
1437 rn = bgp_node_lookup(vpn->route_table, (struct prefix *)p);
1438 if (!rn)
1439 return 0;
1440
1441 /* Next, locate route node in the global EVPN routing table. Note that
1442 * this table is a 2-level tree (RD-level + Prefix-level) similar to
1443 * L3VPN routes.
1444 */
1445 global_rn = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi,
1446 (struct prefix *)p, &vpn->prd);
1447 if (global_rn) {
1448 /* Delete route entry in the global EVPN table. */
1449 delete_evpn_route_entry(bgp, vpn, afi, safi, global_rn, &ri);
1450
1451 /* Schedule for processing - withdraws to peers happen from
1452 * this table.
1453 */
1454 if (ri)
1455 bgp_process(bgp, global_rn, afi, safi);
1456 bgp_unlock_node(global_rn);
1457 }
1458
1459 /* Delete route entry in the VNI route table. This can just be removed.
1460 */
1461 delete_evpn_route_entry(bgp, vpn, afi, safi, rn, &ri);
1462 if (ri)
1463 bgp_info_reap(rn, ri);
1464 bgp_unlock_node(rn);
1465
1466 return 0;
128ea8ab 1467}
1468
1469/*
1470 * Update all type-2 (MACIP) local routes for this VNI - these should also
1471 * be scheduled for advertise to peers.
1472 */
d62a17ae 1473static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
1474{
1475 afi_t afi;
1476 safi_t safi;
1477 struct bgp_node *rn;
1478 struct bgp_info *ri;
1479 struct attr attr;
1480 struct attr attr_sticky;
ead40654 1481 struct attr attr_def_gw;
1ec31309 1482 struct attr attr_ip6_ll;
d62a17ae 1483 struct attr *attr_new;
1ec31309 1484 int add_l3_ecomm = 0;
d62a17ae 1485
1486 afi = AFI_L2VPN;
1487 safi = SAFI_EVPN;
1488 memset(&attr, 0, sizeof(struct attr));
1489 memset(&attr_sticky, 0, sizeof(struct attr));
ead40654 1490 memset(&attr_def_gw, 0, sizeof(struct attr));
1ec31309 1491 memset(&attr_ip6_ll, 0, sizeof(struct attr));
d62a17ae 1492
1ec31309 1493 /* Build path-attribute - multiple type-2 routes for this VNI will share
1494 * the same path attribute, but we need separate structures for sticky
1495 * MACs, default gateway and IPv6 link-local addresses (no L3 RT/RMAC).
d62a17ae 1496 */
1497 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
1498 bgp_attr_default_set(&attr_sticky, BGP_ORIGIN_IGP);
ead40654 1499 bgp_attr_default_set(&attr_def_gw, BGP_ORIGIN_IGP);
d62a17ae 1500 attr.nexthop = vpn->originator_ip;
1501 attr.mp_nexthop_global_in = vpn->originator_ip;
1502 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
bc59a672 1503 bgpevpn_get_rmac(vpn, &attr.rmac);
d62a17ae 1504 attr_sticky.nexthop = vpn->originator_ip;
1505 attr_sticky.mp_nexthop_global_in = vpn->originator_ip;
1506 attr_sticky.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
1507 attr_sticky.sticky = 1;
bc59a672 1508 bgpevpn_get_rmac(vpn, &attr_sticky.rmac);
ead40654
MK
1509 attr_def_gw.nexthop = vpn->originator_ip;
1510 attr_def_gw.mp_nexthop_global_in = vpn->originator_ip;
1511 attr_def_gw.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
1512 attr_def_gw.default_gw = 1;
1513 bgpevpn_get_rmac(vpn, &attr_def_gw.rmac);
1ec31309 1514 bgp_attr_default_set(&attr_ip6_ll, BGP_ORIGIN_IGP);
1515 attr_ip6_ll.nexthop = vpn->originator_ip;
1516 attr_ip6_ll.mp_nexthop_global_in = vpn->originator_ip;
1517 attr_ip6_ll.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
1518
1519 /* Add L3 VNI RTs and RMAC for non IPv6 link-local attributes if
1520 * using L3 VNI for type-2 routes also.
1521 */
1522 if (CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS))
1523 add_l3_ecomm = 1;
1524
1525 build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm);
1526 build_evpn_route_extcomm(vpn, &attr_sticky, add_l3_ecomm);
1527 build_evpn_route_extcomm(vpn, &attr_def_gw, add_l3_ecomm);
1528 build_evpn_route_extcomm(vpn, &attr_ip6_ll, 0);
d62a17ae 1529
1530 /* Walk this VNI's route table and update local type-2 routes. For any
1531 * routes updated, update corresponding entry in the global table too.
1532 */
1533 for (rn = bgp_table_top(vpn->route_table); rn;
1534 rn = bgp_route_next(rn)) {
1535 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
1536 struct bgp_node *rd_rn;
1537 struct bgp_info *global_ri;
1538
1539 if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
1540 continue;
1541
1ec31309 1542 if (IS_EVPN_PREFIX_IPADDR_V6(evp) &&
1543 IN6_IS_ADDR_LINKLOCAL(&evp->prefix.ip.ipaddr_v6))
1544 update_evpn_route_entry(bgp, vpn, afi, safi, rn,
1545 &attr_ip6_ll, 0, 1, &ri, 0);
1546 else {
7ec156a9
MK
1547 if (evpn_route_is_sticky(bgp, rn))
1548 update_evpn_route_entry(bgp, vpn, afi, safi, rn,
996c9314
LB
1549 &attr_sticky, 0, 1, &ri,
1550 0);
ead40654
MK
1551 else if (evpn_route_is_def_gw(bgp, rn))
1552 update_evpn_route_entry(bgp, vpn, afi, safi, rn,
996c9314
LB
1553 &attr_def_gw, 0, 1, &ri,
1554 0);
7ec156a9
MK
1555 else
1556 update_evpn_route_entry(bgp, vpn, afi, safi, rn,
1557 &attr, 0, 1, &ri, 0);
7ec156a9 1558 }
d62a17ae 1559
1560 /* If a local route exists for this prefix, we need to update
1561 * the global routing table too.
1562 */
1563 if (!ri)
1564 continue;
1565
1566 /* Perform route selection; this is just to set the flags
1567 * correctly
1568 * as local route in the VNI always wins.
1569 */
1570 evpn_route_select_install(bgp, vpn, rn);
1571
1572 attr_new = ri->attr;
1573
1574 /* Update route in global routing table. */
1575 rd_rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
1576 (struct prefix *)evp, &vpn->prd);
1577 assert(rd_rn);
1578 update_evpn_route_entry(bgp, vpn, afi, safi, rd_rn, attr_new, 0,
1a98c087 1579 0, &global_ri, 0);
d62a17ae 1580
1581 /* Schedule for processing and unlock node. */
1582 bgp_process(bgp, rd_rn, afi, safi);
1583 bgp_unlock_node(rd_rn);
1584 }
1585
1586 /* Unintern temporary. */
1587 aspath_unintern(&attr.aspath);
1588 aspath_unintern(&attr_sticky.aspath);
ead40654 1589 aspath_unintern(&attr_def_gw.aspath);
1ec31309 1590 aspath_unintern(&attr_ip6_ll.aspath);
d62a17ae 1591
1592 return 0;
128ea8ab 1593}
1594
1595/*
1596 * Delete all type-2 (MACIP) local routes for this VNI - only from the
1597 * global routing table. These are also scheduled for withdraw from peers.
1598 */
d62a17ae 1599static int delete_global_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 1600{
d62a17ae 1601 afi_t afi;
1602 safi_t safi;
1603 struct bgp_node *rdrn, *rn;
1604 struct bgp_table *table;
1605 struct bgp_info *ri;
128ea8ab 1606
d62a17ae 1607 afi = AFI_L2VPN;
1608 safi = SAFI_EVPN;
128ea8ab 1609
d62a17ae 1610 rdrn = bgp_node_lookup(bgp->rib[afi][safi], (struct prefix *)&vpn->prd);
1611 if (rdrn && rdrn->info) {
1612 table = (struct bgp_table *)rdrn->info;
1613 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
1614 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
128ea8ab 1615
d62a17ae 1616 if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
1617 continue;
128ea8ab 1618
d62a17ae 1619 delete_evpn_route_entry(bgp, vpn, afi, safi, rn, &ri);
1620 if (ri)
1621 bgp_process(bgp, rn, afi, safi);
1622 }
1623 }
128ea8ab 1624
d62a17ae 1625 /* Unlock RD node. */
1626 if (rdrn)
1627 bgp_unlock_node(rdrn);
128ea8ab 1628
d62a17ae 1629 return 0;
128ea8ab 1630}
1631
1632/*
1633 * Delete all type-2 (MACIP) local routes for this VNI - from the global
1634 * table as well as the per-VNI route table.
1635 */
d62a17ae 1636static int delete_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 1637{
d62a17ae 1638 afi_t afi;
1639 safi_t safi;
1640 struct bgp_node *rn;
1641 struct bgp_info *ri;
128ea8ab 1642
d62a17ae 1643 afi = AFI_L2VPN;
1644 safi = SAFI_EVPN;
128ea8ab 1645
d62a17ae 1646 /* First, walk the global route table for this VNI's type-2 local
1647 * routes.
1648 * EVPN routes are a 2-level table, first get the RD table.
1649 */
1650 delete_global_type2_routes(bgp, vpn);
128ea8ab 1651
d62a17ae 1652 /* Next, walk this VNI's route table and delete local type-2 routes. */
1653 for (rn = bgp_table_top(vpn->route_table); rn;
1654 rn = bgp_route_next(rn)) {
1655 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
128ea8ab 1656
d62a17ae 1657 if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
1658 continue;
128ea8ab 1659
d62a17ae 1660 delete_evpn_route_entry(bgp, vpn, afi, safi, rn, &ri);
128ea8ab 1661
d62a17ae 1662 /* Route entry in local table gets deleted immediately. */
1663 if (ri)
1664 bgp_info_reap(rn, ri);
1665 }
128ea8ab 1666
d62a17ae 1667 return 0;
128ea8ab 1668}
1669
1670/*
1671 * Delete all routes in the per-VNI route table.
1672 */
d62a17ae 1673static int delete_all_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 1674{
d62a17ae 1675 struct bgp_node *rn;
1676 struct bgp_info *ri, *nextri;
128ea8ab 1677
d62a17ae 1678 /* Walk this VNI's route table and delete all routes. */
1679 for (rn = bgp_table_top(vpn->route_table); rn;
1680 rn = bgp_route_next(rn)) {
1681 for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1);
1682 ri = nextri) {
1683 bgp_info_delete(rn, ri);
1684 bgp_info_reap(rn, ri);
1685 }
1686 }
128ea8ab 1687
d62a17ae 1688 return 0;
128ea8ab 1689}
1690
1691/*
1692 * Update (and advertise) local routes for a VNI. Invoked upon the VNI
1693 * export RT getting modified or change to tunnel IP. Note that these
1694 * situations need the route in the per-VNI table as well as the global
1695 * table to be updated (as attributes change).
1696 */
d62a17ae 1697static int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 1698{
d62a17ae 1699 int ret;
1700 struct prefix_evpn p;
128ea8ab 1701
d62a17ae 1702 /* Update and advertise the type-3 route (only one) followed by the
1703 * locally learnt type-2 routes (MACIP) - for this VNI.
1704 */
1705 build_evpn_type3_prefix(&p, vpn->originator_ip);
1706 ret = update_evpn_route(bgp, vpn, &p, 0);
1707 if (ret)
1708 return ret;
128ea8ab 1709
d62a17ae 1710 return update_all_type2_routes(bgp, vpn);
128ea8ab 1711}
1712
1713/*
1714 * Delete (and withdraw) local routes for specified VNI from the global
1715 * table and per-VNI table. After this, remove all other routes from
1716 * the per-VNI table. Invoked upon the VNI being deleted or EVPN
1717 * (advertise-all-vni) being disabled.
1718 */
d62a17ae 1719static int delete_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 1720{
d62a17ae 1721 int ret;
1722 struct prefix_evpn p;
128ea8ab 1723
d62a17ae 1724 /* Delete and withdraw locally learnt type-2 routes (MACIP)
1725 * followed by type-3 routes (only one) - for this VNI.
1726 */
1727 ret = delete_all_type2_routes(bgp, vpn);
1728 if (ret)
1729 return ret;
128ea8ab 1730
d62a17ae 1731 build_evpn_type3_prefix(&p, vpn->originator_ip);
1732 ret = delete_evpn_route(bgp, vpn, &p);
1733 if (ret)
1734 return ret;
128ea8ab 1735
d62a17ae 1736 /* Delete all routes from the per-VNI table. */
1737 return delete_all_vni_routes(bgp, vpn);
128ea8ab 1738}
1739
1740/*
d1911c26 1741 * There is a tunnel endpoint IP address change for this VNI, delete
1742 * prior type-3 route (if needed) and update.
1743 * Note: Route re-advertisement happens elsewhere after other processing
1744 * other changes.
128ea8ab 1745 */
d62a17ae 1746static int handle_tunnel_ip_change(struct bgp *bgp, struct bgpevpn *vpn,
1747 struct in_addr originator_ip)
128ea8ab 1748{
d62a17ae 1749 struct prefix_evpn p;
128ea8ab 1750
ddd16ed5
MK
1751 /* If VNI is not live, we only need to update the originator ip */
1752 if (!is_vni_live(vpn)) {
1753 vpn->originator_ip = originator_ip;
1754 return 0;
1755 }
1756
db0e1937
MK
1757 /* Update the tunnel-ip hash */
1758 bgp_tip_del(bgp, &vpn->originator_ip);
1759 bgp_tip_add(bgp, &originator_ip);
1760
1761 /* filter routes as martian nexthop db has changed */
1762 bgp_filter_evpn_routes_upon_martian_nh_change(bgp);
1763
d62a17ae 1764 /* Need to withdraw type-3 route as the originator IP is part
1765 * of the key.
1766 */
1767 build_evpn_type3_prefix(&p, vpn->originator_ip);
1768 delete_evpn_route(bgp, vpn, &p);
128ea8ab 1769
d62a17ae 1770 /* Update the tunnel IP and re-advertise all routes for this VNI. */
1771 vpn->originator_ip = originator_ip;
d1911c26 1772 return 0;
128ea8ab 1773}
1774
d3135ba3 1775/*
1776 * Install route entry into the VRF routing table and invoke route selection.
1777 */
1778static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
1779 struct prefix_evpn *evp,
1780 struct bgp_info *parent_ri)
1781{
1782 struct bgp_node *rn;
1783 struct bgp_info *ri;
1ec31309 1784 struct attr attr;
d3135ba3 1785 struct attr *attr_new;
c4edf708 1786 int ret = 0;
d3135ba3 1787 struct prefix p;
1788 struct prefix *pp = &p;
1789 afi_t afi = 0;
1790 safi_t safi = 0;
1eb88002
MK
1791 char buf[PREFIX_STRLEN];
1792 char buf1[PREFIX_STRLEN];
d3135ba3 1793
1794 memset(pp, 0, sizeof(struct prefix));
90264d64
MK
1795 if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
1796 ip_prefix_from_type2_prefix(evp, pp);
523cafc4 1797 else if (evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE)
90264d64 1798 ip_prefix_from_type5_prefix(evp, pp);
d3135ba3 1799
1eb88002 1800 if (bgp_debug_zebra(NULL)) {
996c9314
LB
1801 zlog_debug(
1802 "installing evpn prefix %s as ip prefix %s in vrf %s",
1803 prefix2str(evp, buf, sizeof(buf)),
1804 prefix2str(pp, buf1, sizeof(buf)),
1805 vrf_id_to_name(bgp_vrf->vrf_id));
1eb88002
MK
1806 }
1807
d3135ba3 1808 /* Create (or fetch) route within the VRF. */
1809 /* NOTE: There is no RD here. */
1810 if (IS_EVPN_PREFIX_IPADDR_V4(evp)) {
1811 afi = AFI_IP;
1812 safi = SAFI_UNICAST;
1813 rn = bgp_node_get(bgp_vrf->rib[afi][safi], pp);
1814 } else if (IS_EVPN_PREFIX_IPADDR_V6(evp)) {
1815 afi = AFI_IP6;
1816 safi = SAFI_UNICAST;
1817 rn = bgp_node_get(bgp_vrf->rib[afi][safi], pp);
1818 } else
1819 return 0;
1820
1ec31309 1821 /* EVPN routes currently only support a IPv4 next hop which corresponds
1822 * to the remote VTEP. When importing into a VRF, if it is IPv6 host
1823 * route, we have to convert the next hop to an IPv4-mapped address
1824 * for the rest of the code to flow through.
1825 */
1826 bgp_attr_dup(&attr, parent_ri->attr);
1827 if (afi == AFI_IP6)
1828 evpn_convert_nexthop_to_ipv6(&attr);
1829
d3135ba3 1830 /* Check if route entry is already present. */
1831 for (ri = rn->info; ri; ri = ri->next)
1832 if (ri->extra
1833 && (struct bgp_info *)ri->extra->parent == parent_ri)
1834 break;
1835
1836 if (!ri) {
1837 /* Add (or update) attribute to hash. */
1ec31309 1838 attr_new = bgp_attr_intern(&attr);
d3135ba3 1839
1840 /* Create new route with its attribute. */
90f4f482 1841 ri = info_make(parent_ri->type, BGP_ROUTE_IMPORTED, 0,
d3135ba3 1842 parent_ri->peer, attr_new, rn);
1843 SET_FLAG(ri->flags, BGP_INFO_VALID);
1844 bgp_info_extra_get(ri);
1845 ri->extra->parent = parent_ri;
b57ba6d2 1846 if (parent_ri->extra) {
d3135ba3 1847 memcpy(&ri->extra->label, &parent_ri->extra->label,
b57ba6d2
MK
1848 sizeof(ri->extra->label));
1849 ri->extra->num_labels = parent_ri->extra->num_labels;
1850 }
d3135ba3 1851 bgp_info_add(rn, ri);
1852 } else {
1ec31309 1853 if (attrhash_cmp(ri->attr, &attr)
d3135ba3 1854 && !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
1855 bgp_unlock_node(rn);
1856 return 0;
1857 }
1858 /* The attribute has changed. */
1859 /* Add (or update) attribute to hash. */
1ec31309 1860 attr_new = bgp_attr_intern(&attr);
d3135ba3 1861
1862 /* Restore route, if needed. */
1863 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
1864 bgp_info_restore(rn, ri);
1865
1866 /* Mark if nexthop has changed. */
1ec31309 1867 if ((afi == AFI_IP &&
1868 !IPV4_ADDR_SAME(&ri->attr->nexthop, &attr_new->nexthop)) ||
1869 (afi == AFI_IP6 &&
1870 !IPV6_ADDR_SAME(&ri->attr->mp_nexthop_global,
1871 &attr_new->mp_nexthop_global)))
d3135ba3 1872 SET_FLAG(ri->flags, BGP_INFO_IGP_CHANGED);
1873
1874 /* Unintern existing, set to new. */
1875 bgp_attr_unintern(&ri->attr);
1876 ri->attr = attr_new;
1877 ri->uptime = bgp_clock();
1878 }
1879
1880 /* Perform route selection and update zebra, if required. */
1eb88002 1881 bgp_process(bgp_vrf, rn, afi, safi);
d3135ba3 1882
1883 return ret;
1884}
1885
128ea8ab 1886/*
1887 * Install route entry into the VNI routing table and invoke route selection.
1888 */
d62a17ae 1889static int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
1890 struct prefix_evpn *p,
1891 struct bgp_info *parent_ri)
1892{
1893 struct bgp_node *rn;
1894 struct bgp_info *ri;
1895 struct attr *attr_new;
1896 int ret;
1897
1898 /* Create (or fetch) route within the VNI. */
1899 /* NOTE: There is no RD here. */
1900 rn = bgp_node_get(vpn->route_table, (struct prefix *)p);
1901
1902 /* Check if route entry is already present. */
1903 for (ri = rn->info; ri; ri = ri->next)
1904 if (ri->extra
1905 && (struct bgp_info *)ri->extra->parent == parent_ri)
1906 break;
1907
1908 if (!ri) {
1909 /* Add (or update) attribute to hash. */
1910 attr_new = bgp_attr_intern(parent_ri->attr);
1911
1912 /* Create new route with its attribute. */
90f4f482 1913 ri = info_make(parent_ri->type, BGP_ROUTE_IMPORTED, 0,
d62a17ae 1914 parent_ri->peer, attr_new, rn);
1915 SET_FLAG(ri->flags, BGP_INFO_VALID);
1916 bgp_info_extra_get(ri);
1917 ri->extra->parent = parent_ri;
b57ba6d2 1918 if (parent_ri->extra) {
d62a17ae 1919 memcpy(&ri->extra->label, &parent_ri->extra->label,
b57ba6d2
MK
1920 sizeof(ri->extra->label));
1921 ri->extra->num_labels = parent_ri->extra->num_labels;
1922 }
d62a17ae 1923 bgp_info_add(rn, ri);
1924 } else {
1925 if (attrhash_cmp(ri->attr, parent_ri->attr)
1926 && !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
1927 bgp_unlock_node(rn);
1928 return 0;
1929 }
1930 /* The attribute has changed. */
1931 /* Add (or update) attribute to hash. */
1932 attr_new = bgp_attr_intern(parent_ri->attr);
1933
1934 /* Restore route, if needed. */
1935 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
1936 bgp_info_restore(rn, ri);
1937
1938 /* Mark if nexthop has changed. */
1939 if (!IPV4_ADDR_SAME(&ri->attr->nexthop, &attr_new->nexthop))
1940 SET_FLAG(ri->flags, BGP_INFO_IGP_CHANGED);
1941
1942 /* Unintern existing, set to new. */
1943 bgp_attr_unintern(&ri->attr);
1944 ri->attr = attr_new;
1945 ri->uptime = bgp_clock();
1946 }
1947
1948 /* Perform route selection and update zebra, if required. */
1949 ret = evpn_route_select_install(bgp, vpn, rn);
1950
1951 return ret;
128ea8ab 1952}
1953
d3135ba3 1954/*
1955 * Uninstall route entry from the VRF routing table and send message
1956 * to zebra, if appropriate.
1957 */
1958static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
1959 struct prefix_evpn *evp,
1960 struct bgp_info *parent_ri)
1961{
1962 struct bgp_node *rn;
1963 struct bgp_info *ri;
c4edf708 1964 int ret = 0;
d3135ba3 1965 struct prefix p;
1966 struct prefix *pp = &p;
1967 afi_t afi = 0;
1968 safi_t safi = 0;
1eb88002
MK
1969 char buf[PREFIX_STRLEN];
1970 char buf1[PREFIX_STRLEN];
d3135ba3 1971
1972 memset(pp, 0, sizeof(struct prefix));
42cb44f2
MK
1973 if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
1974 ip_prefix_from_type2_prefix(evp, pp);
655b04d1 1975 else if (evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE)
42cb44f2 1976 ip_prefix_from_type5_prefix(evp, pp);
d3135ba3 1977
1eb88002 1978 if (bgp_debug_zebra(NULL)) {
996c9314
LB
1979 zlog_debug(
1980 "uninstalling evpn prefix %s as ip prefix %s in vrf %s",
1981 prefix2str(evp, buf, sizeof(buf)),
1982 prefix2str(pp, buf1, sizeof(buf)),
1983 vrf_id_to_name(bgp_vrf->vrf_id));
1eb88002
MK
1984 }
1985
d3135ba3 1986 /* Locate route within the VRF. */
1987 /* NOTE: There is no RD here. */
1988 if (IS_EVPN_PREFIX_IPADDR_V4(evp)) {
1989 afi = AFI_IP;
1990 safi = SAFI_UNICAST;
1991 rn = bgp_node_lookup(bgp_vrf->rib[afi][safi], pp);
1992 } else {
1993 afi = AFI_IP6;
1994 safi = SAFI_UNICAST;
1995 rn = bgp_node_lookup(bgp_vrf->rib[afi][safi], pp);
1996 }
1997
1998 if (!rn)
1999 return 0;
2000
2001 /* Find matching route entry. */
2002 for (ri = rn->info; ri; ri = ri->next)
2003 if (ri->extra
2004 && (struct bgp_info *)ri->extra->parent == parent_ri)
2005 break;
2006
2007 if (!ri)
2008 return 0;
2009
2010 /* Mark entry for deletion */
2011 bgp_info_delete(rn, ri);
2012
2013 /* Perform route selection and update zebra, if required. */
1eb88002 2014 bgp_process(bgp_vrf, rn, afi, safi);
d3135ba3 2015
2016 /* Unlock route node. */
2017 bgp_unlock_node(rn);
2018
2019 return ret;
2020}
2021
128ea8ab 2022/*
2023 * Uninstall route entry from the VNI routing table and send message
2024 * to zebra, if appropriate.
2025 */
d62a17ae 2026static int uninstall_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
2027 struct prefix_evpn *p,
2028 struct bgp_info *parent_ri)
128ea8ab 2029{
d62a17ae 2030 struct bgp_node *rn;
2031 struct bgp_info *ri;
2032 int ret;
128ea8ab 2033
d62a17ae 2034 /* Locate route within the VNI. */
2035 /* NOTE: There is no RD here. */
2036 rn = bgp_node_lookup(vpn->route_table, (struct prefix *)p);
2037 if (!rn)
2038 return 0;
128ea8ab 2039
d62a17ae 2040 /* Find matching route entry. */
2041 for (ri = rn->info; ri; ri = ri->next)
2042 if (ri->extra
2043 && (struct bgp_info *)ri->extra->parent == parent_ri)
2044 break;
128ea8ab 2045
d62a17ae 2046 if (!ri)
2047 return 0;
128ea8ab 2048
d62a17ae 2049 /* Mark entry for deletion */
2050 bgp_info_delete(rn, ri);
128ea8ab 2051
d62a17ae 2052 /* Perform route selection and update zebra, if required. */
2053 ret = evpn_route_select_install(bgp, vpn, rn);
128ea8ab 2054
d62a17ae 2055 /* Unlock route node. */
2056 bgp_unlock_node(rn);
128ea8ab 2057
d62a17ae 2058 return ret;
128ea8ab 2059}
2060
5ba238b7
MK
2061/*
2062 * Given a route entry and a VRF, see if this route entry should be
2063 * imported into the VRF i.e., RTs match.
2064 */
996c9314 2065static int is_route_matching_for_vrf(struct bgp *bgp_vrf, struct bgp_info *ri)
5ba238b7
MK
2066{
2067 struct attr *attr = ri->attr;
2068 struct ecommunity *ecom;
2069 int i;
2070
2071 assert(attr);
2072 /* Route should have valid RT to be even considered. */
2073 if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
2074 return 0;
2075
2076 ecom = attr->ecommunity;
2077 if (!ecom || !ecom->size)
2078 return 0;
2079
2080 /* For each extended community RT, see if it matches this VNI. If any RT
2081 * matches, we're done.
2082 */
2083 for (i = 0; i < ecom->size; i++) {
d7c0a89a
QY
2084 uint8_t *pnt;
2085 uint8_t type, sub_type;
5ba238b7
MK
2086 struct ecommunity_val *eval;
2087 struct ecommunity_val eval_tmp;
2088 struct vrf_irt_node *irt;
2089
2090 /* Only deal with RTs */
2091 pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
2092 eval = (struct ecommunity_val *)(ecom->val
2093 + (i * ECOMMUNITY_SIZE));
2094 type = *pnt++;
2095 sub_type = *pnt++;
2096 if (sub_type != ECOMMUNITY_ROUTE_TARGET)
2097 continue;
2098
2099 /* See if this RT matches specified VNIs import RTs */
2100 irt = lookup_vrf_import_rt(eval);
2101 if (irt && irt->vrfs)
2102 if (is_vrf_present_in_irt_vrfs(irt->vrfs, bgp_vrf))
2103 return 1;
2104
2105 /* Also check for non-exact match. In this, we mask out the AS
2106 * and
2107 * only check on the local-admin sub-field. This is to
2108 * facilitate using
2109 * VNI as the RT for EBGP peering too.
2110 */
2111 irt = NULL;
2112 if (type == ECOMMUNITY_ENCODE_AS
2113 || type == ECOMMUNITY_ENCODE_AS4
2114 || type == ECOMMUNITY_ENCODE_IP) {
2115 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
2116 mask_ecom_global_admin(&eval_tmp, eval);
2117 irt = lookup_vrf_import_rt(&eval_tmp);
2118 }
2119 if (irt && irt->vrfs)
2120 if (is_vrf_present_in_irt_vrfs(irt->vrfs, bgp_vrf))
2121 return 1;
2122 }
2123
2124 return 0;
2125}
2126
128ea8ab 2127/*
2128 * Given a route entry and a VNI, see if this route entry should be
2129 * imported into the VNI i.e., RTs match.
2130 */
d62a17ae 2131static int is_route_matching_for_vni(struct bgp *bgp, struct bgpevpn *vpn,
2132 struct bgp_info *ri)
2133{
2134 struct attr *attr = ri->attr;
2135 struct ecommunity *ecom;
2136 int i;
2137
2138 assert(attr);
2139 /* Route should have valid RT to be even considered. */
2140 if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
2141 return 0;
2142
2143 ecom = attr->ecommunity;
2144 if (!ecom || !ecom->size)
2145 return 0;
2146
2147 /* For each extended community RT, see if it matches this VNI. If any RT
2148 * matches, we're done.
2149 */
2150 for (i = 0; i < ecom->size; i++) {
d7c0a89a
QY
2151 uint8_t *pnt;
2152 uint8_t type, sub_type;
d62a17ae 2153 struct ecommunity_val *eval;
2154 struct ecommunity_val eval_tmp;
2155 struct irt_node *irt;
2156
2157 /* Only deal with RTs */
2158 pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
2159 eval = (struct ecommunity_val *)(ecom->val
2160 + (i * ECOMMUNITY_SIZE));
2161 type = *pnt++;
2162 sub_type = *pnt++;
2163 if (sub_type != ECOMMUNITY_ROUTE_TARGET)
2164 continue;
2165
2166 /* See if this RT matches specified VNIs import RTs */
2167 irt = lookup_import_rt(bgp, eval);
2168 if (irt && irt->vnis)
2169 if (is_vni_present_in_irt_vnis(irt->vnis, vpn))
2170 return 1;
2171
2172 /* Also check for non-exact match. In this, we mask out the AS
2173 * and
2174 * only check on the local-admin sub-field. This is to
2175 * facilitate using
2176 * VNI as the RT for EBGP peering too.
2177 */
2178 irt = NULL;
2179 if (type == ECOMMUNITY_ENCODE_AS
2180 || type == ECOMMUNITY_ENCODE_AS4
2181 || type == ECOMMUNITY_ENCODE_IP) {
2182 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
2183 mask_ecom_global_admin(&eval_tmp, eval);
2184 irt = lookup_import_rt(bgp, &eval_tmp);
2185 }
2186 if (irt && irt->vnis)
2187 if (is_vni_present_in_irt_vnis(irt->vnis, vpn))
2188 return 1;
2189 }
2190
2191 return 0;
128ea8ab 2192}
2193
5ba238b7
MK
2194/*
2195 * Install or uninstall mac-ip routes are appropriate for this
2196 * particular VRF.
2197 */
996c9314 2198static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install)
5ba238b7
MK
2199{
2200 afi_t afi;
2201 safi_t safi;
2202 struct bgp_node *rd_rn, *rn;
2203 struct bgp_table *table;
2204 struct bgp_info *ri;
2205 int ret;
2206 char buf[PREFIX_STRLEN];
2207 struct bgp *bgp_def = NULL;
2208
2209 afi = AFI_L2VPN;
2210 safi = SAFI_EVPN;
2211 bgp_def = bgp_get_default();
2212 if (!bgp_def)
2213 return -1;
2214
2215 /* Walk entire global routing table and evaluate routes which could be
2216 * imported into this VRF. Note that we need to loop through all global
2217 * routes to determine which route matches the import rt on vrf
2218 */
2219 for (rd_rn = bgp_table_top(bgp_def->rib[afi][safi]); rd_rn;
2220 rd_rn = bgp_route_next(rd_rn)) {
2221 table = (struct bgp_table *)(rd_rn->info);
2222 if (!table)
2223 continue;
2224
2225 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
2226 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
2227
1eb88002 2228 /* if not mac-ip route skip this route */
996c9314
LB
2229 if (!(evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
2230 || evp->prefix.route_type
2231 == BGP_EVPN_IP_PREFIX_ROUTE))
5ba238b7
MK
2232 continue;
2233
1eb88002 2234 /* if not a mac+ip route skip this route */
996c9314
LB
2235 if (!(IS_EVPN_PREFIX_IPADDR_V4(evp)
2236 || IS_EVPN_PREFIX_IPADDR_V6(evp)))
1eb88002
MK
2237 continue;
2238
5ba238b7
MK
2239 for (ri = rn->info; ri; ri = ri->next) {
2240 /* Consider "valid" remote routes applicable for
523cafc4 2241 * this VRF.
2242 */
5ba238b7
MK
2243 if (!(CHECK_FLAG(ri->flags, BGP_INFO_VALID)
2244 && ri->type == ZEBRA_ROUTE_BGP
2245 && ri->sub_type == BGP_ROUTE_NORMAL))
2246 continue;
2247
2248 if (is_route_matching_for_vrf(bgp_vrf, ri)) {
2249 if (install)
996c9314 2250 ret = install_evpn_route_entry_in_vrf(
5ba238b7
MK
2251 bgp_vrf, evp, ri);
2252 else
996c9314 2253 ret = uninstall_evpn_route_entry_in_vrf(
5ba238b7
MK
2254 bgp_vrf, evp, ri);
2255
2256 if (ret) {
2257 zlog_err(
2258 "Failed to %s EVPN %s route in VRF %s",
2259 install ? "install"
2260 : "uninstall",
2261 prefix2str(evp, buf,
2262 sizeof(buf)),
996c9314
LB
2263 vrf_id_to_name(
2264 bgp_vrf->vrf_id));
5ba238b7
MK
2265 return ret;
2266 }
2267 }
2268 }
2269 }
2270 }
2271
2272 return 0;
2273}
2274
128ea8ab 2275/*
2276 * Install or uninstall routes of specified type that are appropriate for this
2277 * particular VNI.
2278 */
d62a17ae 2279static int install_uninstall_routes_for_vni(struct bgp *bgp,
2280 struct bgpevpn *vpn,
2281 bgp_evpn_route_type rtype,
2282 int install)
2283{
0291c246
MK
2284 afi_t afi;
2285 safi_t safi;
2286 struct bgp_node *rd_rn, *rn;
2287 struct bgp_table *table;
2288 struct bgp_info *ri;
2289 int ret;
d62a17ae 2290
2291 afi = AFI_L2VPN;
2292 safi = SAFI_EVPN;
2293
2294 /* Walk entire global routing table and evaluate routes which could be
2295 * imported into this VPN. Note that we cannot just look at the routes
2296 * for
2297 * the VNI's RD - remote routes applicable for this VNI could have any
2298 * RD.
2299 */
2300 /* EVPN routes are a 2-level table. */
2301 for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
2302 rd_rn = bgp_route_next(rd_rn)) {
2303 table = (struct bgp_table *)(rd_rn->info);
2304 if (!table)
2305 continue;
2306
2307 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
2308 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
2309
2310 if (evp->prefix.route_type != rtype)
2311 continue;
2312
2313 for (ri = rn->info; ri; ri = ri->next) {
2314 /* Consider "valid" remote routes applicable for
2315 * this VNI. */
2316 if (!(CHECK_FLAG(ri->flags, BGP_INFO_VALID)
2317 && ri->type == ZEBRA_ROUTE_BGP
2318 && ri->sub_type == BGP_ROUTE_NORMAL))
2319 continue;
2320
2321 if (is_route_matching_for_vni(bgp, vpn, ri)) {
2322 if (install)
2323 ret = install_evpn_route_entry(
60466a63 2324 bgp, vpn, evp, ri);
d62a17ae 2325 else
2326 ret = uninstall_evpn_route_entry(
2327 bgp, vpn, evp, ri);
2328
2329 if (ret) {
2330 zlog_err(
2331 "%u: Failed to %s EVPN %s route in VNI %u",
2332 bgp->vrf_id,
2333 install ? "install"
2334 : "uninstall",
2335 rtype == BGP_EVPN_MAC_IP_ROUTE
2336 ? "MACIP"
2337 : "IMET",
2338 vpn->vni);
2339 return ret;
2340 }
2341 }
2342 }
2343 }
2344 }
2345
2346 return 0;
128ea8ab 2347}
2348
5ba238b7 2349/* Install any existing remote routes applicable for this VRF into VRF RIB. This
523cafc4 2350 * is invoked upon l3vni-add or l3vni import rt change
2351 */
5ba238b7
MK
2352static int install_routes_for_vrf(struct bgp *bgp_vrf)
2353{
2354 install_uninstall_routes_for_vrf(bgp_vrf, 1);
2355 return 0;
2356}
2357
128ea8ab 2358/*
2359 * Install any existing remote routes applicable for this VNI into its
2360 * routing table. This is invoked when a VNI becomes "live" or its Import
2361 * RT is changed.
2362 */
d62a17ae 2363static int install_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 2364{
d62a17ae 2365 int ret;
128ea8ab 2366
d62a17ae 2367 /* Install type-3 routes followed by type-2 routes - the ones applicable
2368 * for this VNI.
2369 */
2370 ret = install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_IMET_ROUTE,
2371 1);
2372 if (ret)
2373 return ret;
128ea8ab 2374
d62a17ae 2375 return install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_MAC_IP_ROUTE,
2376 1);
128ea8ab 2377}
2378
5ba238b7
MK
2379/* uninstall routes from l3vni vrf. */
2380static int uninstall_routes_for_vrf(struct bgp *bgp_vrf)
2381{
2382 install_uninstall_routes_for_vrf(bgp_vrf, 0);
2383 return 0;
2384}
2385
90e60aa7 2386/*
2387 * Uninstall any existing remote routes for this VNI. One scenario in which
2388 * this is invoked is upon an import RT change.
2389 */
d62a17ae 2390static int uninstall_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 2391{
d62a17ae 2392 int ret;
90e60aa7 2393
d62a17ae 2394 /* Uninstall type-2 routes followed by type-3 routes - the ones
2395 * applicable
2396 * for this VNI.
2397 */
2398 ret = install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_MAC_IP_ROUTE,
2399 0);
2400 if (ret)
2401 return ret;
90e60aa7 2402
d62a17ae 2403 return install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_IMET_ROUTE,
2404 0);
90e60aa7 2405}
2406
d3135ba3 2407/*
2408 * Install or uninstall route in matching VRFs (list).
2409 */
2410static int install_uninstall_route_in_vrfs(struct bgp *bgp_def, afi_t afi,
2411 safi_t safi, struct prefix_evpn *evp,
2412 struct bgp_info *ri,
2413 struct list *vrfs, int install)
2414{
2415 char buf[PREFIX2STR_BUFFER];
2416 struct bgp *bgp_vrf;
2417 struct listnode *node, *nnode;
2418
90264d64 2419 /* Only type-2/type-5 routes go into a VRF */
996c9314
LB
2420 if (!(evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
2421 || evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE))
d3135ba3 2422 return 0;
2423
90264d64 2424 /* if it is type-2 route and not a mac+ip route skip this route */
996c9314
LB
2425 if ((evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
2426 && !(IS_EVPN_PREFIX_IPADDR_V4(evp)
2427 || IS_EVPN_PREFIX_IPADDR_V6(evp)))
30a30f57
MK
2428 return 0;
2429
d3135ba3 2430 for (ALL_LIST_ELEMENTS(vrfs, node, nnode, bgp_vrf)) {
2431 int ret;
2432
2433 if (install)
996c9314 2434 ret = install_evpn_route_entry_in_vrf(bgp_vrf, evp, ri);
d3135ba3 2435 else
996c9314
LB
2436 ret = uninstall_evpn_route_entry_in_vrf(bgp_vrf, evp,
2437 ri);
d3135ba3 2438
2439 if (ret) {
2440 zlog_err("%u: Failed to %s prefix %s in VRF %s",
2441 bgp_def->vrf_id,
2442 install ? "install" : "uninstall",
2443 prefix2str(evp, buf, sizeof(buf)),
2444 vrf_id_to_name(bgp_vrf->vrf_id));
2445 return ret;
2446 }
2447 }
2448
2449 return 0;
2450}
2451
128ea8ab 2452/*
2453 * Install or uninstall route in matching VNIs (list).
2454 */
d62a17ae 2455static int install_uninstall_route_in_vnis(struct bgp *bgp, afi_t afi,
2456 safi_t safi, struct prefix_evpn *evp,
2457 struct bgp_info *ri,
2458 struct list *vnis, int install)
128ea8ab 2459{
d62a17ae 2460 struct bgpevpn *vpn;
2461 struct listnode *node, *nnode;
128ea8ab 2462
d62a17ae 2463 for (ALL_LIST_ELEMENTS(vnis, node, nnode, vpn)) {
2464 int ret;
128ea8ab 2465
d62a17ae 2466 if (!is_vni_live(vpn))
2467 continue;
128ea8ab 2468
d62a17ae 2469 if (install)
2470 ret = install_evpn_route_entry(bgp, vpn, evp, ri);
2471 else
2472 ret = uninstall_evpn_route_entry(bgp, vpn, evp, ri);
128ea8ab 2473
d62a17ae 2474 if (ret) {
2475 zlog_err("%u: Failed to %s EVPN %s route in VNI %u",
2476 bgp->vrf_id, install ? "install" : "uninstall",
2477 evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
2478 ? "MACIP"
2479 : "IMET",
2480 vpn->vni);
2481 return ret;
2482 }
2483 }
128ea8ab 2484
d62a17ae 2485 return 0;
128ea8ab 2486}
2487
2488/*
2489 * Install or uninstall route for appropriate VNIs.
2490 */
d62a17ae 2491static int install_uninstall_evpn_route(struct bgp *bgp, afi_t afi, safi_t safi,
2492 struct prefix *p, struct bgp_info *ri,
2493 int import)
2494{
2495 struct prefix_evpn *evp = (struct prefix_evpn *)p;
2496 struct attr *attr = ri->attr;
2497 struct ecommunity *ecom;
2498 int i;
2499
2500 assert(attr);
2501
90264d64 2502 /* Only type-2 and type-3 and type-5 are supported currently */
d62a17ae 2503 if (!(evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
90264d64
MK
2504 || evp->prefix.route_type == BGP_EVPN_IMET_ROUTE
2505 || evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE))
d62a17ae 2506 return 0;
2507
2508 /* If we don't have Route Target, nothing much to do. */
2509 if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
2510 return 0;
2511
2512 ecom = attr->ecommunity;
2513 if (!ecom || !ecom->size)
2514 return -1;
2515
90264d64
MK
2516 /* For each extended community RT, see which VNIs/VRFs match and import
2517 * the route into matching VNIs/VRFs.
d62a17ae 2518 */
2519 for (i = 0; i < ecom->size; i++) {
d7c0a89a
QY
2520 uint8_t *pnt;
2521 uint8_t type, sub_type;
d62a17ae 2522 struct ecommunity_val *eval;
2523 struct ecommunity_val eval_tmp;
996c9314 2524 struct irt_node *irt; /* import rt for l2vni */
d3135ba3 2525 struct vrf_irt_node *vrf_irt; /* import rt for l3vni */
d62a17ae 2526
2527 /* Only deal with RTs */
2528 pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
2529 eval = (struct ecommunity_val *)(ecom->val
2530 + (i * ECOMMUNITY_SIZE));
2531 type = *pnt++;
2532 sub_type = *pnt++;
2533 if (sub_type != ECOMMUNITY_ROUTE_TARGET)
2534 continue;
2535
90264d64 2536 /* Import route into matching l2-vnis (type-2/type-3 routes go
523cafc4 2537 * into l2vni table)
2538 */
d62a17ae 2539 irt = lookup_import_rt(bgp, eval);
2540 if (irt && irt->vnis)
2541 install_uninstall_route_in_vnis(bgp, afi, safi, evp, ri,
2542 irt->vnis, import);
2543
90264d64 2544 /* Import route into matching l3-vnis (type-2/type-5 routes go
523cafc4 2545 * into l3vni/vrf table)
2546 */
d3135ba3 2547 vrf_irt = lookup_vrf_import_rt(eval);
2548 if (vrf_irt && vrf_irt->vrfs)
2549 install_uninstall_route_in_vrfs(bgp, afi, safi, evp, ri,
2550 vrf_irt->vrfs, import);
2551
90264d64
MK
2552 /* Also check for non-exact match. In this,
2553 * we mask out the AS and
2554 * only check on the local-admin sub-field.
2555 * This is to facilitate using
d62a17ae 2556 * VNI as the RT for EBGP peering too.
2557 */
2558 irt = NULL;
d3135ba3 2559 vrf_irt = NULL;
d62a17ae 2560 if (type == ECOMMUNITY_ENCODE_AS
2561 || type == ECOMMUNITY_ENCODE_AS4
2562 || type == ECOMMUNITY_ENCODE_IP) {
2563 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
2564 mask_ecom_global_admin(&eval_tmp, eval);
2565 irt = lookup_import_rt(bgp, &eval_tmp);
d3135ba3 2566 vrf_irt = lookup_vrf_import_rt(&eval_tmp);
d62a17ae 2567 }
2568 if (irt && irt->vnis)
2569 install_uninstall_route_in_vnis(bgp, afi, safi, evp, ri,
2570 irt->vnis, import);
d3135ba3 2571 if (vrf_irt && vrf_irt->vrfs)
996c9314
LB
2572 install_uninstall_route_in_vrfs(bgp, afi, safi, evp, ri,
2573 vrf_irt->vrfs, import);
d62a17ae 2574 }
2575
2576 return 0;
128ea8ab 2577}
2578
80b140af
MK
2579/* delete and withdraw all ipv4 and ipv6 routes in the vrf table as type-5
2580 * routes */
2581static void delete_withdraw_vrf_routes(struct bgp *bgp_vrf)
2582{
2583 /* delete all ipv4 routes and withdraw from peers */
fdf19f06
MK
2584 if (advertise_type5_routes(bgp_vrf, AFI_IP))
2585 bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
80b140af
MK
2586
2587 /* delete all ipv6 routes and withdraw from peers */
fdf19f06
MK
2588 if (advertise_type5_routes(bgp_vrf, AFI_IP6))
2589 bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
80b140af
MK
2590}
2591
2592/* update and advertise all ipv4 and ipv6 routes in thr vrf table as type-5
2593 * routes */
2594static void update_advertise_vrf_routes(struct bgp *bgp_vrf)
2595{
2596 /* update all ipv4 routes */
fdf19f06
MK
2597 if (advertise_type5_routes(bgp_vrf, AFI_IP))
2598 bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
80b140af
MK
2599
2600 /* update all ipv6 routes */
fdf19f06
MK
2601 if (advertise_type5_routes(bgp_vrf, AFI_IP6))
2602 bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
80b140af
MK
2603}
2604
676f83b9 2605/*
2606 * update and advertise local routes for a VRF as type-5 routes.
2607 * This is invoked upon RD change for a VRF. Note taht the processing is only
2608 * done in the global route table using the routes which already exist in the
2609 * VRF routing table
2610 */
80b140af 2611static void update_router_id_vrf(struct bgp *bgp_vrf)
676f83b9 2612{
80b140af
MK
2613 /* skip if the RD is configured */
2614 if (is_vrf_rd_configured(bgp_vrf))
2615 return;
2616
2617 /* derive the RD for the VRF based on new router-id */
2618 bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf);
2619
2620 /* update advertise ipv4|ipv6 routes as type-5 routes */
2621 update_advertise_vrf_routes(bgp_vrf);
676f83b9 2622}
2623
2624/*
2625 * Delete and withdraw all type-5 routes for the RD corresponding to VRF.
2626 * This is invoked upon VRF RD change. The processing is done only from global
2627 * table.
2628 */
80b140af 2629static void withdraw_router_id_vrf(struct bgp *bgp_vrf)
676f83b9 2630{
80b140af
MK
2631 /* skip if the RD is configured */
2632 if (is_vrf_rd_configured(bgp_vrf))
2633 return;
2634
2635 /* delete/withdraw ipv4|ipv6 routes as type-5 routes */
2636 delete_withdraw_vrf_routes(bgp_vrf);
676f83b9 2637}
2638
90e60aa7 2639/*
2640 * Update and advertise local routes for a VNI. Invoked upon router-id
2641 * change. Note that the processing is done only on the global route table
2642 * using routes that already exist in the per-VNI table.
2643 */
d62a17ae 2644static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
2645{
2646 struct prefix_evpn p;
2647 struct bgp_node *rn, *global_rn;
2648 struct bgp_info *ri, *global_ri;
2649 struct attr *attr;
2650 afi_t afi = AFI_L2VPN;
2651 safi_t safi = SAFI_EVPN;
2652
2653 /* Locate type-3 route for VNI in the per-VNI table and use its
2654 * attributes to create and advertise the type-3 route for this VNI
2655 * in the global table.
2656 */
2657 build_evpn_type3_prefix(&p, vpn->originator_ip);
2658 rn = bgp_node_lookup(vpn->route_table, (struct prefix *)&p);
2659 if (!rn) /* unexpected */
2660 return 0;
2661 for (ri = rn->info; ri; ri = ri->next)
2662 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
2663 && ri->sub_type == BGP_ROUTE_STATIC)
2664 break;
2665 if (!ri) /* unexpected */
2666 return 0;
2667 attr = ri->attr;
2668
2669 global_rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
2670 (struct prefix *)&p, &vpn->prd);
1a98c087
MK
2671 update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1, 0, &ri,
2672 0);
d62a17ae 2673
2674 /* Schedule for processing and unlock node. */
2675 bgp_process(bgp, global_rn, afi, safi);
2676 bgp_unlock_node(global_rn);
2677
2678 /* Now, walk this VNI's route table and use the route and its attribute
2679 * to create and schedule route in global table.
2680 */
2681 for (rn = bgp_table_top(vpn->route_table); rn;
2682 rn = bgp_route_next(rn)) {
2683 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
2684
2685 /* Identify MAC-IP local routes. */
2686 if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
2687 continue;
2688
2689 for (ri = rn->info; ri; ri = ri->next)
2690 if (ri->peer == bgp->peer_self
2691 && ri->type == ZEBRA_ROUTE_BGP
2692 && ri->sub_type == BGP_ROUTE_STATIC)
2693 break;
2694 if (!ri)
2695 continue;
2696
2697 /* Create route in global routing table using this route entry's
2698 * attribute.
2699 */
2700 attr = ri->attr;
2701 global_rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
2702 (struct prefix *)evp, &vpn->prd);
2703 assert(global_rn);
2704 update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1,
1a98c087 2705 0, &global_ri, 0);
d62a17ae 2706
2707 /* Schedule for processing and unlock node. */
2708 bgp_process(bgp, global_rn, afi, safi);
2709 bgp_unlock_node(global_rn);
2710 }
2711
2712 return 0;
90e60aa7 2713}
2714
2715/*
2716 * Delete (and withdraw) local routes for a VNI - only from the global
2717 * table. Invoked upon router-id change.
2718 */
d62a17ae 2719static int delete_withdraw_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 2720{
d62a17ae 2721 int ret;
2722 struct prefix_evpn p;
2723 struct bgp_node *global_rn;
2724 struct bgp_info *ri;
2725 afi_t afi = AFI_L2VPN;
2726 safi_t safi = SAFI_EVPN;
90e60aa7 2727
d62a17ae 2728 /* Delete and withdraw locally learnt type-2 routes (MACIP)
2729 * for this VNI - from the global table.
2730 */
2731 ret = delete_global_type2_routes(bgp, vpn);
2732 if (ret)
2733 return ret;
90e60aa7 2734
d62a17ae 2735 /* Remove type-3 route for this VNI from global table. */
2736 build_evpn_type3_prefix(&p, vpn->originator_ip);
2737 global_rn = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi,
2738 (struct prefix *)&p, &vpn->prd);
2739 if (global_rn) {
2740 /* Delete route entry in the global EVPN table. */
2741 delete_evpn_route_entry(bgp, vpn, afi, safi, global_rn, &ri);
90e60aa7 2742
d62a17ae 2743 /* Schedule for processing - withdraws to peers happen from
2744 * this table.
2745 */
2746 if (ri)
2747 bgp_process(bgp, global_rn, afi, safi);
2748 bgp_unlock_node(global_rn);
2749 }
90e60aa7 2750
d62a17ae 2751 return 0;
90e60aa7 2752}
2753
2d48ee25 2754/*
2755 * Handle router-id change. Update and advertise local routes corresponding
2756 * to this VNI from peers. Note that this is invoked after updating the
2757 * router-id. The routes in the per-VNI table are used to create routes in
2758 * the global table and schedule them.
2759 */
d62a17ae 2760static void update_router_id_vni(struct hash_backet *backet, struct bgp *bgp)
2d48ee25 2761{
d62a17ae 2762 struct bgpevpn *vpn;
2d48ee25 2763
d62a17ae 2764 vpn = (struct bgpevpn *)backet->data;
2d48ee25 2765
d62a17ae 2766 if (!vpn) {
2767 zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__);
2768 return;
2769 }
2d48ee25 2770
d62a17ae 2771 /* Skip VNIs with configured RD. */
2772 if (is_rd_configured(vpn))
2773 return;
2d48ee25 2774
d62a17ae 2775 bgp_evpn_derive_auto_rd(bgp, vpn);
2776 update_advertise_vni_routes(bgp, vpn);
2d48ee25 2777}
2778
2779/*
2780 * Handle router-id change. Delete and withdraw local routes corresponding
2781 * to this VNI from peers. Note that this is invoked prior to updating
2782 * the router-id and is done only on the global route table, the routes
2783 * are needed in the per-VNI table to re-advertise with new router id.
2784 */
d62a17ae 2785static void withdraw_router_id_vni(struct hash_backet *backet, struct bgp *bgp)
2d48ee25 2786{
d62a17ae 2787 struct bgpevpn *vpn;
2d48ee25 2788
d62a17ae 2789 vpn = (struct bgpevpn *)backet->data;
2d48ee25 2790
d62a17ae 2791 if (!vpn) {
2792 zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__);
2793 return;
2794 }
2d48ee25 2795
d62a17ae 2796 /* Skip VNIs with configured RD. */
2797 if (is_rd_configured(vpn))
2798 return;
2d48ee25 2799
d62a17ae 2800 delete_withdraw_vni_routes(bgp, vpn);
2d48ee25 2801}
2802
128ea8ab 2803/*
2804 * Process received EVPN type-2 route (advertise or withdraw).
2805 */
d62a17ae 2806static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
d7c0a89a
QY
2807 struct attr *attr, uint8_t *pfx, int psize,
2808 uint32_t addpath_id)
d62a17ae 2809{
2810 struct prefix_rd prd;
2811 struct prefix_evpn p;
554cd77a 2812 struct bgp_route_evpn evpn;
d7c0a89a
QY
2813 uint8_t ipaddr_len;
2814 uint8_t macaddr_len;
b57ba6d2 2815 mpls_label_t label[BGP_MAX_LABELS]; /* holds the VNI(s) as in packet */
d7c0a89a 2816 uint32_t num_labels = 0;
554cd77a 2817 uint32_t eth_tag;
d62a17ae 2818 int ret;
2819
2820 /* Type-2 route should be either 33, 37 or 49 bytes or an
2821 * additional 3 bytes if there is a second label (VNI):
2822 * RD (8), ESI (10), Eth Tag (4), MAC Addr Len (1),
2823 * MAC Addr (6), IP len (1), IP (0, 4 or 16),
2824 * MPLS Lbl1 (3), MPLS Lbl2 (0 or 3)
2825 */
2826 if (psize != 33 && psize != 37 && psize != 49 && psize != 36
2827 && psize != 40 && psize != 52) {
2828 zlog_err("%u:%s - Rx EVPN Type-2 NLRI with invalid length %d",
2829 peer->bgp->vrf_id, peer->host, psize);
2830 return -1;
2831 }
2832
554cd77a
VB
2833 memset(&evpn, 0, sizeof(evpn));
2834
d62a17ae 2835 /* Make prefix_rd */
2836 prd.family = AF_UNSPEC;
2837 prd.prefixlen = 64;
2838 memcpy(&prd.val, pfx, 8);
2839 pfx += 8;
2840
2841 /* Make EVPN prefix. */
2842 memset(&p, 0, sizeof(struct prefix_evpn));
b03b8898 2843 p.family = AF_EVPN;
d62a17ae 2844 p.prefixlen = EVPN_TYPE_2_ROUTE_PREFIXLEN;
2845 p.prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
2846
554cd77a
VB
2847 /* Copy Ethernet Seg Identifier */
2848 memcpy(&evpn.eth_s_id.val, pfx, ESI_LEN);
2849 pfx += ESI_LEN;
d62a17ae 2850
554cd77a
VB
2851 /* Copy Ethernet Tag */
2852 memcpy(&eth_tag, pfx, 4);
2853 p.prefix.eth_tag = ntohl(eth_tag);
d62a17ae 2854 pfx += 4;
2855
2856 /* Get the MAC Addr len */
2857 macaddr_len = *pfx++;
2858
2859 /* Get the MAC Addr */
28328ea9
DS
2860 if (macaddr_len == (ETH_ALEN * 8)) {
2861 memcpy(&p.prefix.mac.octet, pfx, ETH_ALEN);
2862 pfx += ETH_ALEN;
d62a17ae 2863 } else {
2864 zlog_err(
2865 "%u:%s - Rx EVPN Type-2 NLRI with unsupported MAC address length %d",
2866 peer->bgp->vrf_id, peer->host, macaddr_len);
2867 return -1;
2868 }
2869
2870
2871 /* Get the IP. */
2872 ipaddr_len = *pfx++;
2873 if (ipaddr_len != 0 && ipaddr_len != IPV4_MAX_BITLEN
2874 && ipaddr_len != IPV6_MAX_BITLEN) {
2875 zlog_err(
2876 "%u:%s - Rx EVPN Type-2 NLRI with unsupported IP address length %d",
2877 peer->bgp->vrf_id, peer->host, ipaddr_len);
2878 return -1;
2879 }
2880
2881 if (ipaddr_len) {
2882 ipaddr_len /= 8; /* Convert to bytes. */
2883 p.prefix.ip.ipa_type = (ipaddr_len == IPV4_MAX_BYTELEN)
2884 ? IPADDR_V4
2885 : IPADDR_V6;
2886 memcpy(&p.prefix.ip.ip.addr, pfx, ipaddr_len);
2887 }
2888 pfx += ipaddr_len;
2889
b57ba6d2
MK
2890 /* Get the VNI(s). Stored as bytes here. */
2891 num_labels++;
2892 memset(label, 0, sizeof(label));
2893 memcpy(&label[0], pfx, BGP_LABEL_BYTES);
1b817c78 2894 pfx += BGP_LABEL_BYTES;
b57ba6d2
MK
2895 psize -= (33 + ipaddr_len);
2896 /* Do we have a second VNI? */
2897 if (psize) {
2898 num_labels++;
2899 memcpy(&label[1], pfx, BGP_LABEL_BYTES);
6b11bd8d 2900 /*
2901 * If in future, we are required to access additional fields,
996c9314
LB
2902 * we MUST increment pfx by BGP_LABEL_BYTES in before reading
2903 * the next field
6b11bd8d 2904 */
b57ba6d2 2905 }
d62a17ae 2906
2907 /* Process the route. */
2908 if (attr)
2909 ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
2910 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
554cd77a 2911 &prd, &label[0], num_labels, 0, &evpn);
d62a17ae 2912 else
2913 ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
2914 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
554cd77a 2915 &prd, &label[0], num_labels, &evpn);
d62a17ae 2916 return ret;
128ea8ab 2917}
2918
2919/*
2920 * Process received EVPN type-3 route (advertise or withdraw).
2921 */
d62a17ae 2922static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,
d7c0a89a
QY
2923 struct attr *attr, uint8_t *pfx, int psize,
2924 uint32_t addpath_id)
d62a17ae 2925{
2926 struct prefix_rd prd;
2927 struct prefix_evpn p;
d7c0a89a 2928 uint8_t ipaddr_len;
554cd77a 2929 uint32_t eth_tag;
d62a17ae 2930 int ret;
2931
2932 /* Type-3 route should be either 17 or 29 bytes: RD (8), Eth Tag (4),
2933 * IP len (1) and IP (4 or 16).
2934 */
2935 if (psize != 17 && psize != 29) {
2936 zlog_err("%u:%s - Rx EVPN Type-3 NLRI with invalid length %d",
2937 peer->bgp->vrf_id, peer->host, psize);
2938 return -1;
2939 }
2940
7fd077aa 2941 /* If PMSI is present, log if it is anything other than IR.
2942 * Note: We just simply ignore the values as it is not clear if
2943 * doing anything else is better.
2944 */
2945 if (attr &&
2946 (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) {
2947 if (attr->pmsi_tnl_type != PMSI_TNLTYPE_INGR_REPL) {
d0be47e8 2948 zlog_warn("%u:%s - Rx EVPN Type-3 NLRI with unsupported PTA %d",
7fd077aa 2949 peer->bgp->vrf_id, peer->host,
2950 attr->pmsi_tnl_type);
2951 }
2952 }
2953
d62a17ae 2954 /* Make prefix_rd */
2955 prd.family = AF_UNSPEC;
2956 prd.prefixlen = 64;
2957 memcpy(&prd.val, pfx, 8);
2958 pfx += 8;
2959
2960 /* Make EVPN prefix. */
2961 memset(&p, 0, sizeof(struct prefix_evpn));
b03b8898 2962 p.family = AF_EVPN;
d62a17ae 2963 p.prefixlen = EVPN_TYPE_3_ROUTE_PREFIXLEN;
2964 p.prefix.route_type = BGP_EVPN_IMET_ROUTE;
2965
554cd77a
VB
2966 /* Copy Ethernet Tag */
2967 memcpy(&eth_tag, pfx, 4);
2968 p.prefix.eth_tag = ntohl(eth_tag);
d62a17ae 2969 pfx += 4;
2970
2971 /* Get the IP. */
2972 ipaddr_len = *pfx++;
2973 if (ipaddr_len == IPV4_MAX_BITLEN) {
2974 p.prefix.ip.ipa_type = IPADDR_V4;
2975 memcpy(&p.prefix.ip.ip.addr, pfx, IPV4_MAX_BYTELEN);
2976 } else {
2977 zlog_err(
2978 "%u:%s - Rx EVPN Type-3 NLRI with unsupported IP address length %d",
2979 peer->bgp->vrf_id, peer->host, ipaddr_len);
2980 return -1;
2981 }
2982
2983 /* Process the route. */
2984 if (attr)
2985 ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
2986 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
b57ba6d2 2987 &prd, NULL, 0, 0, NULL);
d62a17ae 2988 else
2989 ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
2990 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
b57ba6d2 2991 &prd, NULL, 0, NULL);
d62a17ae 2992 return ret;
128ea8ab 2993}
2994
2995/*
2996 * Process received EVPN type-5 route (advertise or withdraw).
2997 */
d62a17ae 2998static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
d7c0a89a
QY
2999 struct attr *attr, uint8_t *pfx, int psize,
3000 uint32_t addpath_id, int withdraw)
d62a17ae 3001{
3002 struct prefix_rd prd;
3003 struct prefix_evpn p;
3004 struct bgp_route_evpn evpn;
d7c0a89a
QY
3005 uint8_t ippfx_len;
3006 uint32_t eth_tag;
b57ba6d2 3007 mpls_label_t label; /* holds the VNI as in the packet */
d62a17ae 3008 int ret;
3009
3010 /* Type-5 route should be 34 or 58 bytes:
3011 * RD (8), ESI (10), Eth Tag (4), IP len (1), IP (4 or 16),
3012 * GW (4 or 16) and VNI (3).
3013 * Note that the IP and GW should both be IPv4 or both IPv6.
3014 */
3015 if (psize != 34 && psize != 58) {
3016 zlog_err("%u:%s - Rx EVPN Type-5 NLRI with invalid length %d",
3017 peer->bgp->vrf_id, peer->host, psize);
3018 return -1;
3019 }
3020
3021 /* Make prefix_rd */
3022 prd.family = AF_UNSPEC;
3023 prd.prefixlen = 64;
3024 memcpy(&prd.val, pfx, 8);
3025 pfx += 8;
3026
3027 /* Make EVPN prefix. */
3028 memset(&p, 0, sizeof(struct prefix_evpn));
b03b8898 3029 p.family = AF_EVPN;
e9fc2840 3030 p.prefixlen = EVPN_TYPE_5_ROUTE_PREFIXLEN;
d62a17ae 3031 p.prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE;
3032
3033 /* Additional information outside of prefix - ESI and GW IP */
3034 memset(&evpn, 0, sizeof(evpn));
3035
3036 /* Fetch ESI */
3037 memcpy(&evpn.eth_s_id.val, pfx, 10);
3038 pfx += 10;
3039
3040 /* Fetch Ethernet Tag. */
3041 memcpy(&eth_tag, pfx, 4);
3042 p.prefix.eth_tag = ntohl(eth_tag);
3043 pfx += 4;
3044
3045 /* Fetch IP prefix length. */
3046 ippfx_len = *pfx++;
3047 if (ippfx_len > IPV6_MAX_BITLEN) {
3048 zlog_err(
3049 "%u:%s - Rx EVPN Type-5 NLRI with invalid IP Prefix length %d",
3050 peer->bgp->vrf_id, peer->host, ippfx_len);
3051 return -1;
3052 }
3053 p.prefix.ip_prefix_length = ippfx_len;
3054
3055 /* Determine IPv4 or IPv6 prefix */
3056 /* Since the address and GW are from the same family, this just becomes
3057 * a simple check on the total size.
3058 */
3059 if (psize == 34) {
3060 SET_IPADDR_V4(&p.prefix.ip);
3061 memcpy(&p.prefix.ip.ipaddr_v4, pfx, 4);
3062 pfx += 4;
3063 memcpy(&evpn.gw_ip.ipv4, pfx, 4);
3064 pfx += 4;
d62a17ae 3065 } else {
3066 SET_IPADDR_V6(&p.prefix.ip);
3067 memcpy(&p.prefix.ip.ipaddr_v6, pfx, 16);
3068 pfx += 16;
3069 memcpy(&evpn.gw_ip.ipv6, pfx, 16);
3070 pfx += 16;
d62a17ae 3071 }
3072
b57ba6d2
MK
3073 /* Get the VNI (in MPLS label field). Stored as bytes here. */
3074 memset(&label, 0, sizeof(label));
3075 memcpy(&label, pfx, BGP_LABEL_BYTES);
6b11bd8d 3076
3077 /*
3078 * If in future, we are required to access additional fields,
996c9314
LB
3079 * we MUST increment pfx by BGP_LABEL_BYTES in before reading the next
3080 * field
6b11bd8d 3081 */
d62a17ae 3082
3083 /* Process the route. */
3084 if (!withdraw)
3085 ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
3086 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
b57ba6d2 3087 &prd, &label, 1, 0, &evpn);
d62a17ae 3088 else
3089 ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
3090 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
b57ba6d2 3091 &prd, &label, 1, &evpn);
d62a17ae 3092
3093 return ret;
3094}
3095
3096static void evpn_mpattr_encode_type5(struct stream *s, struct prefix *p,
996c9314 3097 struct prefix_rd *prd, mpls_label_t *label,
d7c0a89a 3098 uint32_t num_labels, struct attr *attr)
d62a17ae 3099{
3100 int len;
3101 char temp[16];
3102 struct evpn_addr *p_evpn_p;
3103
3104 memset(&temp, 0, 16);
b03b8898 3105 if (p->family != AF_EVPN)
d62a17ae 3106 return;
3107 p_evpn_p = &(p->u.prefix_evpn);
3108
e9fc2840 3109 /* len denites the total len of IP and GW-IP in the route
523cafc4 3110 IP and GW-IP have to be both ipv4 or ipv6
3111 */
d62a17ae 3112 if (IS_IPADDR_V4(&p_evpn_p->ip))
e9fc2840 3113 len = 8; /* IP and GWIP are both ipv4 */
d62a17ae 3114 else
e9fc2840 3115 len = 32; /* IP and GWIP are both ipv6 */
d62a17ae 3116 /* Prefix contains RD, ESI, EthTag, IP length, IP, GWIP and VNI */
3117 stream_putc(s, 8 + 10 + 4 + 1 + len + 3);
3118 stream_put(s, prd->val, 8);
0af35d90 3119 if (attr)
d62a17ae 3120 stream_put(s, &(attr->evpn_overlay.eth_s_id), 10);
3121 else
3122 stream_put(s, &temp, 10);
3123 stream_putl(s, p_evpn_p->eth_tag);
3124 stream_putc(s, p_evpn_p->ip_prefix_length);
3125 if (IS_IPADDR_V4(&p_evpn_p->ip))
3126 stream_put_ipv4(s, p_evpn_p->ip.ipaddr_v4.s_addr);
3127 else
3128 stream_put(s, &p_evpn_p->ip.ipaddr_v6, 16);
0af35d90 3129 if (attr) {
d62a17ae 3130 if (IS_IPADDR_V4(&p_evpn_p->ip))
3131 stream_put_ipv4(s,
3132 attr->evpn_overlay.gw_ip.ipv4.s_addr);
3133 else
3134 stream_put(s, &(attr->evpn_overlay.gw_ip.ipv6), 16);
3135 } else {
3136 if (IS_IPADDR_V4(&p_evpn_p->ip))
3137 stream_put_ipv4(s, 0);
3138 else
3139 stream_put(s, &temp, 16);
3140 }
3141
b57ba6d2 3142 if (num_labels)
d62a17ae 3143 stream_put(s, label, 3);
3144 else
3145 stream_put3(s, 0);
128ea8ab 3146}
3147
3148/*
3149 * Cleanup specific VNI upon EVPN (advertise-all-vni) being disabled.
3150 */
d62a17ae 3151static void cleanup_vni_on_disable(struct hash_backet *backet, struct bgp *bgp)
128ea8ab 3152{
d62a17ae 3153 struct bgpevpn *vpn = (struct bgpevpn *)backet->data;
128ea8ab 3154
d62a17ae 3155 /* Remove EVPN routes and schedule for processing. */
3156 delete_routes_for_vni(bgp, vpn);
128ea8ab 3157
d62a17ae 3158 /* Clear "live" flag and see if hash needs to be freed. */
3159 UNSET_FLAG(vpn->flags, VNI_FLAG_LIVE);
3160 if (!is_vni_configured(vpn))
3161 bgp_evpn_free(bgp, vpn);
128ea8ab 3162}
3163
3164/*
3165 * Free a VNI entry; iterator function called during cleanup.
3166 */
d62a17ae 3167static void free_vni_entry(struct hash_backet *backet, struct bgp *bgp)
128ea8ab 3168{
d62a17ae 3169 struct bgpevpn *vpn;
128ea8ab 3170
d62a17ae 3171 vpn = (struct bgpevpn *)backet->data;
3172 delete_all_vni_routes(bgp, vpn);
3173 bgp_evpn_free(bgp, vpn);
128ea8ab 3174}
3175
c581d8b0
MK
3176/*
3177 * Derive AUTO import RT for BGP VRF - L3VNI
3178 */
3179static void evpn_auto_rt_import_add_for_vrf(struct bgp *bgp_vrf)
3180{
10ebe1ab
MK
3181 struct bgp *bgp_def = NULL;
3182
c581d8b0 3183 form_auto_rt(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_import_rtl);
10ebe1ab
MK
3184 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD);
3185
3186 /* Map RT to VRF */
3187 bgp_def = bgp_get_default();
3188 if (!bgp_def)
3189 return;
3190 bgp_evpn_map_vrf_to_its_rts(bgp_vrf);
c581d8b0
MK
3191}
3192
3193/*
3194 * Delete AUTO import RT from BGP VRF - L3VNI
3195 */
3196static void evpn_auto_rt_import_delete_for_vrf(struct bgp *bgp_vrf)
3197{
3198 evpn_rt_delete_auto(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_import_rtl);
3199}
3200
3201/*
3202 * Derive AUTO export RT for BGP VRF - L3VNI
3203 */
3204static void evpn_auto_rt_export_add_for_vrf(struct bgp *bgp_vrf)
3205{
3206 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD);
3207 form_auto_rt(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_export_rtl);
3208}
3209
3210/*
3211 * Delete AUTO export RT from BGP VRF - L3VNI
3212 */
3213static void evpn_auto_rt_export_delete_for_vrf(struct bgp *bgp_vrf)
3214{
3215 evpn_rt_delete_auto(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_export_rtl);
3216}
128ea8ab 3217
f1f8b53c
MK
3218static void bgp_evpn_handle_export_rt_change_for_vrf(struct bgp *bgp_vrf)
3219{
3220 struct bgp *bgp_def = NULL;
3221 struct listnode *node = NULL;
3222 struct bgpevpn *vpn = NULL;
3223
3224 bgp_def = bgp_get_default();
3225 if (!bgp_def)
3226 return;
3227
4992b4ae
MK
3228 /* update all type-5 routes */
3229 update_advertise_vrf_routes(bgp_vrf);
3230
3231 /* update all type-2 routes */
f1f8b53c
MK
3232 for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn))
3233 update_routes_for_vni(bgp_def, vpn);
3234}
3235
128ea8ab 3236/*
3237 * Public functions.
3238 */
3239
5424b7ba 3240/* withdraw type-5 route corresponding to ip prefix */
31310b25 3241void bgp_evpn_withdraw_type5_route(struct bgp *bgp_vrf, struct prefix *p,
5424b7ba
MK
3242 afi_t afi, safi_t safi)
3243{
3244 int ret = 0;
3245 struct prefix_evpn evp;
3246 char buf[PREFIX_STRLEN];
3247
31310b25 3248 build_type5_prefix_from_ip_prefix(&evp, p);
5424b7ba
MK
3249 ret = delete_evpn_type5_route(bgp_vrf, &evp);
3250 if (ret) {
3251 zlog_err(
996c9314
LB
3252 "%u failed to delete type-5 route for prefix %s in vrf %s",
3253 bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf)),
3254 vrf_id_to_name(bgp_vrf->vrf_id));
5424b7ba
MK
3255 }
3256}
3257
342dd0c6 3258/* withdraw all type-5 routes for an address family */
996c9314 3259void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, afi_t afi, safi_t safi)
342dd0c6 3260{
3261 struct bgp_table *table = NULL;
3262 struct bgp_node *rn = NULL;
25f2ca53 3263 struct bgp_info *ri;
342dd0c6 3264
053905d2 3265 table = bgp_vrf->rib[afi][safi];
25f2ca53 3266 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
3267 /* Only care about "selected" routes - non-imported. */
3268 /* TODO: Support for AddPath for EVPN. */
3269 for (ri = rn->info; ri; ri = ri->next) {
996c9314
LB
3270 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)
3271 && (!ri->extra || !ri->extra->parent)) {
25f2ca53 3272 bgp_evpn_withdraw_type5_route(bgp_vrf, &rn->p,
3273 afi, safi);
3274 break;
3275 }
3276 }
3277 }
5424b7ba 3278}
342dd0c6 3279
2f69f6d3 3280/*
3281 * Advertise IP prefix as type-5 route. The afi/safi and src_attr passed
3282 * to this function correspond to those of the source IP prefix (best
3283 * path in the case of the attr. In the case of a local prefix (when we
3284 * are advertising local subnets), the src_attr will be NULL.
3285 */
31310b25 3286void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p,
996c9314
LB
3287 struct attr *src_attr, afi_t afi,
3288 safi_t safi)
5424b7ba
MK
3289{
3290 int ret = 0;
3291 struct prefix_evpn evp;
3292 char buf[PREFIX_STRLEN];
7b1bf203 3293
31310b25 3294 build_type5_prefix_from_ip_prefix(&evp, p);
2f69f6d3 3295 ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr);
3296 if (ret)
996c9314
LB
3297 zlog_err("%u: Failed to create type-5 route for prefix %s",
3298 bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf)));
342dd0c6 3299}
3300
2f69f6d3 3301/* Inject all prefixes of a particular address-family (currently, IPv4 or
3302 * IPv6 unicast) into EVPN as type-5 routes. This is invoked when the
3303 * advertisement is enabled.
3304 */
996c9314
LB
3305void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi,
3306 safi_t safi)
342dd0c6 3307{
3308 struct bgp_table *table = NULL;
3309 struct bgp_node *rn = NULL;
2f69f6d3 3310 struct bgp_info *ri;
342dd0c6 3311
053905d2 3312 table = bgp_vrf->rib[afi][safi];
31310b25 3313 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
2f69f6d3 3314 /* Need to identify the "selected" route entry to use its
25f2ca53 3315 * attribute. Also, we only consider "non-imported" routes.
2f69f6d3 3316 * TODO: Support for AddPath for EVPN.
3317 */
3318 for (ri = rn->info; ri; ri = ri->next) {
996c9314
LB
3319 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)
3320 && (!ri->extra || !ri->extra->parent)) {
53c84f78
MK
3321
3322 /* apply the route-map */
3323 if (bgp_vrf->adv_cmd_rmap[afi][safi].map) {
3324 int ret = 0;
3325
996c9314
LB
3326 ret = route_map_apply(
3327 bgp_vrf->adv_cmd_rmap[afi][safi]
3328 .map,
3329 &rn->p, RMAP_BGP, ri);
53c84f78
MK
3330 if (ret == RMAP_DENYMATCH)
3331 continue;
3332 }
996c9314
LB
3333 bgp_evpn_advertise_type5_route(
3334 bgp_vrf, &rn->p, ri->attr, afi, safi);
2f69f6d3 3335 break;
3336 }
3337 }
31310b25 3338 }
342dd0c6 3339}
3340
996c9314 3341void evpn_rt_delete_auto(struct bgp *bgp, vni_t vni, struct list *rtl)
c581d8b0
MK
3342{
3343 struct listnode *node, *nnode, *node_to_del;
3344 struct ecommunity *ecom, *ecom_auto;
3345 struct ecommunity_val eval;
3346
3347 encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
3348
3349 ecom_auto = ecommunity_new();
3350 ecommunity_add_val(ecom_auto, &eval);
3351 node_to_del = NULL;
3352
3353 for (ALL_LIST_ELEMENTS(rtl, node, nnode, ecom)) {
3354 if (ecommunity_match(ecom, ecom_auto)) {
3355 ecommunity_free(&ecom);
3356 node_to_del = node;
3357 }
3358 }
3359
3360 if (node_to_del)
3361 list_delete_node(rtl, node_to_del);
3362
3363 ecommunity_free(&ecom_auto);
3364}
3365
3366void bgp_evpn_configure_import_rt_for_vrf(struct bgp *bgp_vrf,
10ebe1ab 3367 struct ecommunity *ecomadd)
c581d8b0 3368{
5ba238b7
MK
3369 /* uninstall routes from vrf */
3370 uninstall_routes_for_vrf(bgp_vrf);
10ebe1ab
MK
3371
3372 /* Cleanup the RT to VRF mapping */
3373 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf);
3374
c581d8b0
MK
3375 /* Remove auto generated RT */
3376 evpn_auto_rt_import_delete_for_vrf(bgp_vrf);
3377
3378 /* Add the newly configured RT to RT list */
3379 listnode_add_sort(bgp_vrf->vrf_import_rtl, ecomadd);
3380 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD);
3381
10ebe1ab
MK
3382 /* map VRF to its RTs */
3383 bgp_evpn_map_vrf_to_its_rts(bgp_vrf);
3384
5ba238b7
MK
3385 /* install routes matching the new VRF */
3386 install_routes_for_vrf(bgp_vrf);
c581d8b0
MK
3387}
3388
3389void bgp_evpn_unconfigure_import_rt_for_vrf(struct bgp *bgp_vrf,
3390 struct ecommunity *ecomdel)
3391{
3392 struct listnode *node = NULL, *nnode = NULL, *node_to_del = NULL;
3393 struct ecommunity *ecom = NULL;
3394
5ba238b7
MK
3395 /* uninstall routes from vrf */
3396 uninstall_routes_for_vrf(bgp_vrf);
10ebe1ab
MK
3397
3398 /* Cleanup the RT to VRF mapping */
3399 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf);
3400
c581d8b0
MK
3401 /* remove the RT from the RT list */
3402 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_import_rtl, node, nnode, ecom)) {
3403 if (ecommunity_match(ecom, ecomdel)) {
3404 ecommunity_free(&ecom);
3405 node_to_del = node;
3406 break;
3407 }
3408 }
3409
3410 if (node_to_del)
3411 list_delete_node(bgp_vrf->vrf_import_rtl, node_to_del);
3412
3413 /* fallback to auto import rt, if this was the last RT */
3414 if (list_isempty(bgp_vrf->vrf_import_rtl)) {
3415 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD);
3416 evpn_auto_rt_import_add_for_vrf(bgp_vrf);
3417 }
3418
10ebe1ab
MK
3419 /* map VRFs to its RTs */
3420 bgp_evpn_map_vrf_to_its_rts(bgp_vrf);
3421
5ba238b7
MK
3422 /* install routes matching this new RT */
3423 install_routes_for_vrf(bgp_vrf);
c581d8b0
MK
3424}
3425
3426void bgp_evpn_configure_export_rt_for_vrf(struct bgp *bgp_vrf,
3427 struct ecommunity *ecomadd)
3428{
3429 /* remove auto-generated RT */
3430 evpn_auto_rt_export_delete_for_vrf(bgp_vrf);
3431
3432 /* Add the new RT to the RT list */
3433 listnode_add_sort(bgp_vrf->vrf_export_rtl, ecomadd);
3434 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD);
3435
f1f8b53c 3436 bgp_evpn_handle_export_rt_change_for_vrf(bgp_vrf);
c581d8b0
MK
3437}
3438
3439void bgp_evpn_unconfigure_export_rt_for_vrf(struct bgp *bgp_vrf,
3440 struct ecommunity *ecomdel)
3441{
3442 struct listnode *node = NULL, *nnode = NULL, *node_to_del = NULL;
3443 struct ecommunity *ecom = NULL;
3444
3445 /* Remove the RT from the RT list */
3446 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_export_rtl, node, nnode, ecom)) {
3447 if (ecommunity_match(ecom, ecomdel)) {
3448 ecommunity_free(&ecom);
3449 node_to_del = node;
3450 break;
3451 }
3452 }
3453
3454 if (node_to_del)
3455 list_delete_node(bgp_vrf->vrf_export_rtl, node_to_del);
3456
3457 /* fall back to auto-generated RT if this was the last RT */
877702e7 3458 if (bgp_vrf->vrf_export_rtl && list_isempty(bgp_vrf->vrf_export_rtl)) {
c581d8b0
MK
3459 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD);
3460 evpn_auto_rt_export_add_for_vrf(bgp_vrf);
3461 }
3462
f1f8b53c 3463 bgp_evpn_handle_export_rt_change_for_vrf(bgp_vrf);
c581d8b0
MK
3464}
3465
2d48ee25 3466/*
3467 * Handle change to BGP router id. This is invoked twice by the change
3468 * handler, first before the router id has been changed and then after
3469 * the router id has been changed. The first invocation will result in
676f83b9 3470 * local routes for all VNIs/VRF being deleted and withdrawn and the next
2d48ee25 3471 * will result in the routes being re-advertised.
3472 */
d62a17ae 3473void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw)
2d48ee25 3474{
676f83b9 3475 if (withdraw) {
3476
3477 /* delete and withdraw all the type-5 routes
523cafc4 3478 stored in the global table for this vrf
3479 */
80b140af 3480 withdraw_router_id_vrf(bgp);
676f83b9 3481
3482 /* delete all the VNI routes (type-2/type-3) routes for all the
523cafc4 3483 * L2-VNIs
3484 */
d62a17ae 3485 hash_iterate(bgp->vnihash,
3486 (void (*)(struct hash_backet *,
3487 void *))withdraw_router_id_vni,
3488 bgp);
676f83b9 3489 } else {
3490
3491 /* advertise all routes in the vrf as type-5 routes with the new
523cafc4 3492 * RD
3493 */
80b140af 3494 update_router_id_vrf(bgp);
676f83b9 3495
3496 /* advertise all the VNI routes (type-2/type-3) routes with the
523cafc4 3497 * new RD
3498 */
d62a17ae 3499 hash_iterate(bgp->vnihash,
3500 (void (*)(struct hash_backet *,
3501 void *))update_router_id_vni,
3502 bgp);
676f83b9 3503 }
2d48ee25 3504}
3505
90e60aa7 3506/*
3507 * Handle change to export RT - update and advertise local routes.
3508 */
d62a17ae 3509int bgp_evpn_handle_export_rt_change(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 3510{
d62a17ae 3511 return update_routes_for_vni(bgp, vpn);
90e60aa7 3512}
3513
996c9314 3514void bgp_evpn_handle_vrf_rd_change(struct bgp *bgp_vrf, int withdraw)
676f83b9 3515{
3516 if (withdraw)
3517 delete_withdraw_vrf_routes(bgp_vrf);
3518 else
3519 update_advertise_vrf_routes(bgp_vrf);
3520}
3521
90e60aa7 3522/*
3523 * Handle change to RD. This is invoked twice by the change handler,
3524 * first before the RD has been changed and then after the RD has
3525 * been changed. The first invocation will result in local routes
3526 * of this VNI being deleted and withdrawn and the next will result
3527 * in the routes being re-advertised.
3528 */
d62a17ae 3529void bgp_evpn_handle_rd_change(struct bgp *bgp, struct bgpevpn *vpn,
3530 int withdraw)
90e60aa7 3531{
d62a17ae 3532 if (withdraw)
3533 delete_withdraw_vni_routes(bgp, vpn);
3534 else
3535 update_advertise_vni_routes(bgp, vpn);
90e60aa7 3536}
3537
3538/*
3539 * Install routes for this VNI. Invoked upon change to Import RT.
3540 */
d62a17ae 3541int bgp_evpn_install_routes(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 3542{
d62a17ae 3543 return install_routes_for_vni(bgp, vpn);
90e60aa7 3544}
3545
3546/*
3547 * Uninstall all routes installed for this VNI. Invoked upon change
3548 * to Import RT.
3549 */
d62a17ae 3550int bgp_evpn_uninstall_routes(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 3551{
d62a17ae 3552 return uninstall_routes_for_vni(bgp, vpn);
90e60aa7 3553}
3554
b16031a2 3555/*
b57ba6d2 3556 * TODO: Hardcoded for a maximum of 2 VNIs right now
b16031a2 3557 */
d7c0a89a 3558char *bgp_evpn_label2str(mpls_label_t *label, uint32_t num_labels, char *buf,
996c9314 3559 int len)
b16031a2 3560{
b57ba6d2 3561 vni_t vni1, vni2;
b16031a2 3562
b57ba6d2
MK
3563 vni1 = label2vni(label);
3564 if (num_labels == 2) {
996c9314 3565 vni2 = label2vni(label + 1);
b57ba6d2
MK
3566 snprintf(buf, len, "%u/%u", vni1, vni2);
3567 } else
3568 snprintf(buf, len, "%u", vni1);
d62a17ae 3569 return buf;
b16031a2 3570}
3571
9c92b5f7
MK
3572/*
3573 * Function to convert evpn route to json format.
3574 * NOTE: We don't use prefix2str as the output here is a bit different.
3575 */
57f7feb6 3576void bgp_evpn_route2json(struct prefix_evpn *p, json_object *json)
9c92b5f7 3577{
b682f6de 3578 char buf1[ETHER_ADDR_STRLEN];
3579 char buf2[PREFIX2STR_BUFFER];
9c92b5f7 3580
b682f6de 3581 if (!json)
3582 return;
9c92b5f7 3583
dff8f48d 3584 if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) {
b682f6de 3585 json_object_int_add(json, "routeType", p->prefix.route_type);
554cd77a 3586 json_object_int_add(json, "ethTag", p->prefix.eth_tag);
57f7feb6
MK
3587 json_object_int_add(json, "ipLen",
3588 IS_EVPN_PREFIX_IPADDR_V4(p)
3589 ? IPV4_MAX_BITLEN
3590 : IPV6_MAX_BITLEN);
b682f6de 3591 json_object_string_add(json, "ip",
57f7feb6
MK
3592 inet_ntoa(p->prefix.ip.ipaddr_v4));
3593 } else if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
dff8f48d 3594 if (IS_EVPN_PREFIX_IPADDR_NONE(p)) {
57f7feb6
MK
3595 json_object_int_add(json, "routeType",
3596 p->prefix.route_type);
554cd77a 3597 json_object_int_add(json, "ethTag", p->prefix.eth_tag);
57f7feb6
MK
3598 json_object_int_add(json, "macLen", 8 * ETH_ALEN);
3599 json_object_string_add(json, "mac",
3600 prefix_mac2str(&p->prefix.mac,
3601 buf1,
3602 sizeof(buf1)));
dff8f48d 3603 } else {
d7c0a89a 3604 uint8_t family;
dff8f48d 3605
57f7feb6
MK
3606 family = IS_EVPN_PREFIX_IPADDR_V4(p) ? AF_INET
3607 : AF_INET6;
dff8f48d 3608
b682f6de 3609 json_object_int_add(json, "routeType",
57f7feb6 3610 p->prefix.route_type);
554cd77a 3611 json_object_int_add(json, "ethTag", p->prefix.eth_tag);
57f7feb6 3612 json_object_int_add(json, "macLen", 8 * ETH_ALEN);
b682f6de 3613 json_object_string_add(json, "mac",
57f7feb6
MK
3614 prefix_mac2str(&p->prefix.mac,
3615 buf1,
3616 sizeof(buf1)));
b682f6de 3617 json_object_int_add(json, "ipLen",
57f7feb6
MK
3618 IS_EVPN_PREFIX_IPADDR_V4(p)
3619 ? IPV4_MAX_BITLEN
3620 : IPV6_MAX_BITLEN);
3621 json_object_string_add(
3622 json, "ip",
3623 inet_ntop(family, &p->prefix.ip.ip.addr, buf2,
3624 PREFIX2STR_BUFFER));
dff8f48d
MK
3625 }
3626 } else {
3627 /* Currently, this is to cater to other AF_ETHERNET code. */
3628 }
9c92b5f7
MK
3629}
3630
520d5d76 3631/*
3632 * Function to convert evpn route to string.
3633 * NOTE: We don't use prefix2str as the output here is a bit different.
3634 */
d62a17ae 3635char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len)
3636{
3637 char buf1[ETHER_ADDR_STRLEN];
3638 char buf2[PREFIX2STR_BUFFER];
3639
3640 if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) {
554cd77a
VB
3641 snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]", p->prefix.route_type,
3642 p->prefix.eth_tag,
d62a17ae 3643 IS_EVPN_PREFIX_IPADDR_V4(p) ? IPV4_MAX_BITLEN
3644 : IPV6_MAX_BITLEN,
3645 inet_ntoa(p->prefix.ip.ipaddr_v4));
3646 } else if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
3647 if (IS_EVPN_PREFIX_IPADDR_NONE(p))
554cd77a
VB
3648 snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]",
3649 p->prefix.route_type,
3650 p->prefix.eth_tag,
3651 8 * ETH_ALEN,
d62a17ae 3652 prefix_mac2str(&p->prefix.mac, buf1,
3653 sizeof(buf1)));
3654 else {
d7c0a89a 3655 uint8_t family;
d62a17ae 3656
3657 family = IS_EVPN_PREFIX_IPADDR_V4(p) ? AF_INET
3658 : AF_INET6;
554cd77a
VB
3659 snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]:[%d]:[%s]",
3660 p->prefix.route_type,
3661 p->prefix.eth_tag,
3662 8 * ETH_ALEN,
d62a17ae 3663 prefix_mac2str(&p->prefix.mac, buf1,
3664 sizeof(buf1)),
3665 family == AF_INET ? IPV4_MAX_BITLEN
3666 : IPV6_MAX_BITLEN,
3667 inet_ntop(family, &p->prefix.ip.ip.addr, buf2,
3668 PREFIX2STR_BUFFER));
3669 }
342dd0c6 3670 } else if (p->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE) {
554cd77a
VB
3671 snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]",
3672 p->prefix.route_type,
3673 p->prefix.eth_tag,
3674 p->prefix.ip_prefix_length,
996c9314
LB
3675 IS_EVPN_PREFIX_IPADDR_V4(p)
3676 ? inet_ntoa(p->prefix.ip.ipaddr_v4)
3677 : inet6_ntoa(p->prefix.ip.ipaddr_v6));
d62a17ae 3678 } else {
b03b8898 3679 /* For EVPN route types not supported yet. */
f9aa3e55
QY
3680 snprintf(buf, len, "(unsupported route type %d)",
3681 p->prefix.route_type);
d62a17ae 3682 }
3683
3684 return (buf);
520d5d76 3685}
3686
128ea8ab 3687/*
3688 * Encode EVPN prefix in Update (MP_REACH)
3689 */
d62a17ae 3690void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
996c9314 3691 struct prefix_rd *prd, mpls_label_t *label,
d7c0a89a
QY
3692 uint32_t num_labels, struct attr *attr,
3693 int addpath_encode, uint32_t addpath_tx_id)
d62a17ae 3694{
3695 struct prefix_evpn *evp = (struct prefix_evpn *)p;
b57ba6d2 3696 int len, ipa_len = 0;
d62a17ae 3697
3698 if (addpath_encode)
3699 stream_putl(s, addpath_tx_id);
3700
3701 /* Route type */
3702 stream_putc(s, evp->prefix.route_type);
3703
3704 switch (evp->prefix.route_type) {
3705 case BGP_EVPN_MAC_IP_ROUTE:
3706 if (IS_EVPN_PREFIX_IPADDR_V4(evp))
3707 ipa_len = IPV4_MAX_BYTELEN;
3708 else if (IS_EVPN_PREFIX_IPADDR_V6(evp))
3709 ipa_len = IPV6_MAX_BYTELEN;
b57ba6d2
MK
3710 /* RD, ESI, EthTag, MAC+len, IP len, [IP], 1 VNI */
3711 len = 8 + 10 + 4 + 1 + 6 + 1 + ipa_len + 3;
3712 if (ipa_len && num_labels > 1) /* There are 2 VNIs */
3713 len += 3;
3714 stream_putc(s, len);
996c9314 3715 stream_put(s, prd->val, 8); /* RD */
554cd77a
VB
3716 if (attr)
3717 stream_put(s, &attr->evpn_overlay.eth_s_id, ESI_LEN);
3718 else
3719 stream_put(s, 0, 10);
3720 stream_putl(s, evp->prefix.eth_tag); /* Ethernet Tag ID */
28328ea9 3721 stream_putc(s, 8 * ETH_ALEN); /* Mac Addr Len - bits */
d62a17ae 3722 stream_put(s, evp->prefix.mac.octet, 6); /* Mac Addr */
3723 stream_putc(s, 8 * ipa_len); /* IP address Length */
996c9314 3724 if (ipa_len) /* IP */
b57ba6d2
MK
3725 stream_put(s, &evp->prefix.ip.ip.addr, ipa_len);
3726 /* 1st label is the L2 VNI */
3727 stream_put(s, label, BGP_LABEL_BYTES);
3728 /* Include 2nd label (L3 VNI) if advertising MAC+IP */
3729 if (ipa_len && num_labels > 1)
996c9314 3730 stream_put(s, label + 1, BGP_LABEL_BYTES);
d62a17ae 3731 break;
3732
3733 case BGP_EVPN_IMET_ROUTE:
3734 stream_putc(s, 17); // TODO: length - assumes IPv4 address
3735 stream_put(s, prd->val, 8); /* RD */
554cd77a 3736 stream_putl(s, evp->prefix.eth_tag); /* Ethernet Tag ID */
d62a17ae 3737 stream_putc(s, IPV4_MAX_BITLEN); /* IP address Length - bits */
3738 /* Originating Router's IP Addr */
3739 stream_put_in_addr(s, &evp->prefix.ip.ipaddr_v4);
3740 break;
3741
3742 case BGP_EVPN_IP_PREFIX_ROUTE:
3743 /* TODO: AddPath support. */
b57ba6d2 3744 evpn_mpattr_encode_type5(s, p, prd, label, num_labels, attr);
d62a17ae 3745 break;
3746
3747 default:
3748 break;
3749 }
3750}
3751
3752int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
3753 struct bgp_nlri *packet, int withdraw)
3754{
d7c0a89a
QY
3755 uint8_t *pnt;
3756 uint8_t *lim;
d62a17ae 3757 afi_t afi;
3758 safi_t safi;
d7c0a89a 3759 uint32_t addpath_id;
d62a17ae 3760 int addpath_encoded;
3761 int psize = 0;
d7c0a89a
QY
3762 uint8_t rtype;
3763 uint8_t rlen;
d62a17ae 3764 struct prefix p;
3765
d62a17ae 3766 /* Start processing the NLRI - there may be multiple in the MP_REACH */
3767 pnt = packet->nlri;
3768 lim = pnt + packet->length;
3769 afi = packet->afi;
3770 safi = packet->safi;
3771 addpath_id = 0;
3772
3773 addpath_encoded =
3774 (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
3775 && CHECK_FLAG(peer->af_cap[afi][safi],
3776 PEER_CAP_ADDPATH_AF_TX_RCV));
3777
3778 for (; pnt < lim; pnt += psize) {
3779 /* Clear prefix structure. */
3780 memset(&p, 0, sizeof(struct prefix));
3781
3782 /* Deal with path-id if AddPath is supported. */
3783 if (addpath_encoded) {
3784 /* When packet overflow occurs return immediately. */
3785 if (pnt + BGP_ADDPATH_ID_LEN > lim)
3786 return -1;
3787
3788 addpath_id = ntohl(*((uint32_t *)pnt));
3789 pnt += BGP_ADDPATH_ID_LEN;
3790 }
3791
3792 /* All EVPN NLRI types start with type and length. */
3793 if (pnt + 2 > lim)
3794 return -1;
3795
3796 rtype = *pnt++;
3797 psize = rlen = *pnt++;
3798
3799 /* When packet overflow occur return immediately. */
3800 if (pnt + psize > lim)
3801 return -1;
3802
3803 switch (rtype) {
3804 case BGP_EVPN_MAC_IP_ROUTE:
3805 if (process_type2_route(peer, afi, safi,
3806 withdraw ? NULL : attr, pnt,
3807 psize, addpath_id)) {
3808 zlog_err(
3809 "%u:%s - Error in processing EVPN type-2 NLRI size %d",
3810 peer->bgp->vrf_id, peer->host, psize);
3811 return -1;
3812 }
3813 break;
3814
3815 case BGP_EVPN_IMET_ROUTE:
3816 if (process_type3_route(peer, afi, safi,
3817 withdraw ? NULL : attr, pnt,
3818 psize, addpath_id)) {
3819 zlog_err(
3820 "%u:%s - Error in processing EVPN type-3 NLRI size %d",
3821 peer->bgp->vrf_id, peer->host, psize);
3822 return -1;
3823 }
3824 break;
3825
3826 case BGP_EVPN_IP_PREFIX_ROUTE:
3827 if (process_type5_route(peer, afi, safi, attr, pnt,
3828 psize, addpath_id, withdraw)) {
3829 zlog_err(
3830 "%u:%s - Error in processing EVPN type-5 NLRI size %d",
3831 peer->bgp->vrf_id, peer->host, psize);
3832 return -1;
3833 }
3834 break;
3835
3836 default:
3837 break;
3838 }
3839 }
3840
3841 /* Packet length consistency check. */
3842 if (pnt != lim)
3843 return -1;
3844
3845 return 0;
128ea8ab 3846}
3847
10ebe1ab
MK
3848/*
3849 * Map the RTs (configured or automatically derived) of a VRF to the VRF.
3850 * The mapping will be used during route processing.
3851 * bgp_def: default bgp instance
3852 * bgp_vrf: specific bgp vrf instance on which RT is configured
3853 */
3854void bgp_evpn_map_vrf_to_its_rts(struct bgp *bgp_vrf)
3855{
3856 int i = 0;
3857 struct ecommunity_val *eval = NULL;
3858 struct listnode *node = NULL, *nnode = NULL;
3859 struct ecommunity *ecom = NULL;
3860
3861 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_import_rtl, node, nnode, ecom)) {
3862 for (i = 0; i < ecom->size; i++) {
3863 eval = (struct ecommunity_val *)(ecom->val
3864 + (i
3865 * ECOMMUNITY_SIZE));
3866 map_vrf_to_rt(bgp_vrf, eval);
3867 }
3868 }
3869}
3870
3871/*
3872 * Unmap the RTs (configured or automatically derived) of a VRF from the VRF.
3873 */
3874void bgp_evpn_unmap_vrf_from_its_rts(struct bgp *bgp_vrf)
3875{
3876 int i;
3877 struct ecommunity_val *eval;
3878 struct listnode *node, *nnode;
3879 struct ecommunity *ecom;
3880
3881 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_import_rtl, node, nnode, ecom)) {
3882 for (i = 0; i < ecom->size; i++) {
3883 struct vrf_irt_node *irt;
3884 struct ecommunity_val eval_tmp;
3885
3886 eval = (struct ecommunity_val *)(ecom->val
3887 + (i
3888 * ECOMMUNITY_SIZE));
3889 /* If using "automatic" RT, we only care about the
3890 * local-admin sub-field.
3891 * This is to facilitate using VNI as the RT for EBGP
3892 * peering too.
3893 */
3894 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
3895 if (!CHECK_FLAG(bgp_vrf->vrf_flags,
3896 BGP_VRF_IMPORT_RT_CFGD))
3897 mask_ecom_global_admin(&eval_tmp, eval);
3898
3899 irt = lookup_vrf_import_rt(&eval_tmp);
3900 if (irt)
3901 unmap_vrf_from_rt(bgp_vrf, irt);
3902 }
3903 }
3904}
3905
3906
128ea8ab 3907/*
3908 * Map the RTs (configured or automatically derived) of a VNI to the VNI.
3909 * The mapping will be used during route processing.
3910 */
d62a17ae 3911void bgp_evpn_map_vni_to_its_rts(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 3912{
d62a17ae 3913 int i;
3914 struct ecommunity_val *eval;
3915 struct listnode *node, *nnode;
3916 struct ecommunity *ecom;
128ea8ab 3917
d62a17ae 3918 for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
3919 for (i = 0; i < ecom->size; i++) {
3920 eval = (struct ecommunity_val *)(ecom->val
3921 + (i
3922 * ECOMMUNITY_SIZE));
3923 map_vni_to_rt(bgp, vpn, eval);
3924 }
3925 }
128ea8ab 3926}
3927
3928/*
3929 * Unmap the RTs (configured or automatically derived) of a VNI from the VNI.
3930 */
d62a17ae 3931void bgp_evpn_unmap_vni_from_its_rts(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 3932{
d62a17ae 3933 int i;
3934 struct ecommunity_val *eval;
3935 struct listnode *node, *nnode;
3936 struct ecommunity *ecom;
128ea8ab 3937
d62a17ae 3938 for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
3939 for (i = 0; i < ecom->size; i++) {
3940 struct irt_node *irt;
3941 struct ecommunity_val eval_tmp;
128ea8ab 3942
d62a17ae 3943 eval = (struct ecommunity_val *)(ecom->val
3944 + (i
3945 * ECOMMUNITY_SIZE));
3946 /* If using "automatic" RT, we only care about the
3947 * local-admin sub-field.
3948 * This is to facilitate using VNI as the RT for EBGP
3949 * peering too.
3950 */
3951 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
3952 if (!is_import_rt_configured(vpn))
3953 mask_ecom_global_admin(&eval_tmp, eval);
128ea8ab 3954
d62a17ae 3955 irt = lookup_import_rt(bgp, &eval_tmp);
3956 if (irt)
3957 unmap_vni_from_rt(bgp, vpn, irt);
3958 }
3959 }
128ea8ab 3960}
3961
3962/*
3963 * Derive Import RT automatically for VNI and map VNI to RT.
3964 * The mapping will be used during route processing.
3965 */
d62a17ae 3966void bgp_evpn_derive_auto_rt_import(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 3967{
c581d8b0 3968 form_auto_rt(bgp, vpn->vni, vpn->import_rtl);
d62a17ae 3969 UNSET_FLAG(vpn->flags, VNI_FLAG_IMPRT_CFGD);
128ea8ab 3970
d62a17ae 3971 /* Map RT to VNI */
3972 bgp_evpn_map_vni_to_its_rts(bgp, vpn);
128ea8ab 3973}
3974
3975/*
3976 * Derive Export RT automatically for VNI.
3977 */
d62a17ae 3978void bgp_evpn_derive_auto_rt_export(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 3979{
c581d8b0 3980 form_auto_rt(bgp, vpn->vni, vpn->export_rtl);
d62a17ae 3981 UNSET_FLAG(vpn->flags, VNI_FLAG_EXPRT_CFGD);
128ea8ab 3982}
3983
676f83b9 3984/*
3985 * Derive RD automatically for VNI using passed information - it
3986 * is of the form RouterId:unique-id-for-vni.
3987 */
3988void bgp_evpn_derive_auto_rd_for_vrf(struct bgp *bgp)
3989{
92708db6 3990 form_auto_rd(bgp->router_id, bgp->vrf_rd_id, &bgp->vrf_prd);
676f83b9 3991}
3992
128ea8ab 3993/*
3994 * Derive RD automatically for VNI using passed information - it
3995 * is of the form RouterId:unique-id-for-vni.
3996 */
d62a17ae 3997void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 3998{
d62a17ae 3999 char buf[100];
128ea8ab 4000
d62a17ae 4001 vpn->prd.family = AF_UNSPEC;
4002 vpn->prd.prefixlen = 64;
4003 sprintf(buf, "%s:%hu", inet_ntoa(bgp->router_id), vpn->rd_id);
cbb65f5e 4004 (void)str2prefix_rd(buf, &vpn->prd);
d62a17ae 4005 UNSET_FLAG(vpn->flags, VNI_FLAG_RD_CFGD);
128ea8ab 4006}
4007
4008/*
4009 * Lookup VNI.
4010 */
d62a17ae 4011struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni)
128ea8ab 4012{
d62a17ae 4013 struct bgpevpn *vpn;
4014 struct bgpevpn tmp;
128ea8ab 4015
d62a17ae 4016 memset(&tmp, 0, sizeof(struct bgpevpn));
4017 tmp.vni = vni;
4018 vpn = hash_lookup(bgp->vnihash, &tmp);
4019 return vpn;
128ea8ab 4020}
4021
4022/*
4023 * Create a new vpn - invoked upon configuration or zebra notification.
4024 */
d62a17ae 4025struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
29c53922
MK
4026 struct in_addr originator_ip,
4027 vrf_id_t tenant_vrf_id)
128ea8ab 4028{
d62a17ae 4029 struct bgpevpn *vpn;
128ea8ab 4030
d62a17ae 4031 if (!bgp)
4032 return NULL;
128ea8ab 4033
d62a17ae 4034 vpn = XCALLOC(MTYPE_BGP_EVPN, sizeof(struct bgpevpn));
4035 if (!vpn)
4036 return NULL;
128ea8ab 4037
d62a17ae 4038 /* Set values - RD and RT set to defaults. */
4039 vpn->vni = vni;
4040 vpn->originator_ip = originator_ip;
29c53922 4041 vpn->tenant_vrf_id = tenant_vrf_id;
128ea8ab 4042
d62a17ae 4043 /* Initialize route-target import and export lists */
4044 vpn->import_rtl = list_new();
4045 vpn->import_rtl->cmp = (int (*)(void *, void *))evpn_route_target_cmp;
4046 vpn->export_rtl = list_new();
4047 vpn->export_rtl->cmp = (int (*)(void *, void *))evpn_route_target_cmp;
e9eb5f63 4048 bf_assign_index(bm->rd_idspace, vpn->rd_id);
d62a17ae 4049 derive_rd_rt_for_vni(bgp, vpn);
128ea8ab 4050
d62a17ae 4051 /* Initialize EVPN route table. */
960035b2 4052 vpn->route_table = bgp_table_init(bgp, AFI_L2VPN, SAFI_EVPN);
128ea8ab 4053
d62a17ae 4054 /* Add to hash */
4055 if (!hash_get(bgp->vnihash, vpn, hash_alloc_intern)) {
4056 XFREE(MTYPE_BGP_EVPN, vpn);
4057 return NULL;
4058 }
6a8657d0
MK
4059
4060 /* add to l2vni list on corresponding vrf */
4061 bgpevpn_link_to_l3vni(vpn);
4062
d62a17ae 4063 QOBJ_REG(vpn, bgpevpn);
4064 return vpn;
128ea8ab 4065}
4066
4067/*
4068 * Free a given VPN - called in multiple scenarios such as zebra
4069 * notification, configuration being deleted, advertise-all-vni disabled etc.
4070 * This just frees appropriate memory, caller should have taken other
4071 * needed actions.
4072 */
d62a17ae 4073void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 4074{
6a8657d0 4075 bgpevpn_unlink_from_l3vni(vpn);
d62a17ae 4076 bgp_table_unlock(vpn->route_table);
4077 bgp_evpn_unmap_vni_from_its_rts(bgp, vpn);
affe9e99
DS
4078 list_delete_and_null(&vpn->import_rtl);
4079 list_delete_and_null(&vpn->export_rtl);
e9eb5f63 4080 bf_release_index(bm->rd_idspace, vpn->rd_id);
d62a17ae 4081 hash_release(bgp->vnihash, vpn);
4082 QOBJ_UNREG(vpn);
4083 XFREE(MTYPE_BGP_EVPN, vpn);
128ea8ab 4084}
4085
4086/*
4087 * Import route into matching VNI(s).
4088 */
d62a17ae 4089int bgp_evpn_import_route(struct bgp *bgp, afi_t afi, safi_t safi,
4090 struct prefix *p, struct bgp_info *ri)
128ea8ab 4091{
d62a17ae 4092 return install_uninstall_evpn_route(bgp, afi, safi, p, ri, 1);
128ea8ab 4093}
4094
4095/*
4096 * Unimport route from matching VNI(s).
4097 */
d62a17ae 4098int bgp_evpn_unimport_route(struct bgp *bgp, afi_t afi, safi_t safi,
4099 struct prefix *p, struct bgp_info *ri)
128ea8ab 4100{
d62a17ae 4101 return install_uninstall_evpn_route(bgp, afi, safi, p, ri, 0);
128ea8ab 4102}
4103
db0e1937
MK
4104/* filter routes which have martian next hops */
4105int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp)
4106{
0291c246
MK
4107 afi_t afi;
4108 safi_t safi;
4109 struct bgp_node *rd_rn, *rn;
4110 struct bgp_table *table;
4111 struct bgp_info *ri;
db0e1937
MK
4112
4113 afi = AFI_L2VPN;
4114 safi = SAFI_EVPN;
4115
4116 /* Walk entire global routing table and evaluate routes which could be
4117 * imported into this VPN. Note that we cannot just look at the routes
4118 * for the VNI's RD -
4119 * remote routes applicable for this VNI could have any RD.
4120 */
4121 /* EVPN routes are a 2-level table. */
4122 for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
4123 rd_rn = bgp_route_next(rd_rn)) {
4124 table = (struct bgp_table *)(rd_rn->info);
4125 if (!table)
4126 continue;
4127
4128 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
4129
4130 for (ri = rn->info; ri; ri = ri->next) {
4131
4132 /* Consider "valid" remote routes applicable for
4133 * this VNI. */
4134 if (!(ri->type == ZEBRA_ROUTE_BGP
4135 && ri->sub_type == BGP_ROUTE_NORMAL))
4136 continue;
4137
60466a63 4138 if (bgp_nexthop_self(bgp, ri->attr->nexthop)) {
db0e1937
MK
4139
4140 char attr_str[BUFSIZ];
4141 char pbuf[PREFIX_STRLEN];
4142
4143 bgp_dump_attr(ri->attr, attr_str,
4144 BUFSIZ);
4145
4146 if (bgp_debug_update(ri->peer, &rn->p,
4147 NULL, 1))
4148 zlog_debug(
b682f6de 4149 "%u: prefix %s with attr %s - DENIED due to martian or self nexthop",
db0e1937
MK
4150 bgp->vrf_id,
4151 prefix2str(
60466a63 4152 &rn->p, pbuf,
db0e1937
MK
4153 sizeof(pbuf)),
4154 attr_str);
4155
4156 bgp_evpn_unimport_route(bgp, afi, safi,
4157 &rn->p, ri);
4158
60466a63
QY
4159 bgp_rib_remove(rn, ri, ri->peer, afi,
4160 safi);
db0e1937 4161 }
db0e1937
MK
4162 }
4163 }
4164 }
4165
4166 return 0;
4167}
4168
128ea8ab 4169/*
4170 * Handle del of a local MACIP.
4171 */
d62a17ae 4172int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
4173 struct ipaddr *ip)
128ea8ab 4174{
d62a17ae 4175 struct bgpevpn *vpn;
4176 struct prefix_evpn p;
128ea8ab 4177
d62a17ae 4178 if (!bgp->vnihash) {
4179 zlog_err("%u: VNI hash not created", bgp->vrf_id);
4180 return -1;
4181 }
128ea8ab 4182
d62a17ae 4183 /* Lookup VNI hash - should exist. */
4184 vpn = bgp_evpn_lookup_vni(bgp, vni);
4185 if (!vpn || !is_vni_live(vpn)) {
4186 zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP DEL",
4187 bgp->vrf_id, vni, vpn ? "not live" : "not found");
4188 return -1;
4189 }
128ea8ab 4190
d62a17ae 4191 /* Remove EVPN type-2 route and schedule for processing. */
4192 build_evpn_type2_prefix(&p, mac, ip);
4193 delete_evpn_route(bgp, vpn, &p);
128ea8ab 4194
d62a17ae 4195 return 0;
128ea8ab 4196}
4197
4198/*
4199 * Handle add of a local MACIP.
4200 */
d62a17ae 4201int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
d7c0a89a 4202 struct ipaddr *ip, uint8_t flags)
128ea8ab 4203{
d62a17ae 4204 struct bgpevpn *vpn;
4205 struct prefix_evpn p;
128ea8ab 4206
d62a17ae 4207 if (!bgp->vnihash) {
4208 zlog_err("%u: VNI hash not created", bgp->vrf_id);
4209 return -1;
4210 }
128ea8ab 4211
d62a17ae 4212 /* Lookup VNI hash - should exist. */
4213 vpn = bgp_evpn_lookup_vni(bgp, vni);
4214 if (!vpn || !is_vni_live(vpn)) {
4215 zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP ADD",
4216 bgp->vrf_id, vni, vpn ? "not live" : "not found");
4217 return -1;
4218 }
128ea8ab 4219
d62a17ae 4220 /* Create EVPN type-2 route and schedule for processing. */
4221 build_evpn_type2_prefix(&p, mac, ip);
1a98c087 4222 if (update_evpn_route(bgp, vpn, &p, flags)) {
d62a17ae 4223 char buf[ETHER_ADDR_STRLEN];
4224 char buf2[INET6_ADDRSTRLEN];
128ea8ab 4225
d62a17ae 4226 zlog_err(
ead40654 4227 "%u:Failed to create Type-2 route, VNI %u %s MAC %s IP %s (flags: 0x%x)",
1a98c087 4228 bgp->vrf_id, vpn->vni,
996c9314
LB
4229 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY)
4230 ? "sticky gateway"
4231 : "",
d62a17ae 4232 prefix_mac2str(mac, buf, sizeof(buf)),
996c9314 4233 ipaddr2str(ip, buf2, sizeof(buf2)), flags);
d62a17ae 4234 return -1;
4235 }
128ea8ab 4236
d62a17ae 4237 return 0;
128ea8ab 4238}
4239
6a8657d0
MK
4240static void link_l2vni_hash_to_l3vni(struct hash_backet *backet,
4241 struct bgp *bgp_vrf)
4242{
4243 struct bgpevpn *vpn = NULL;
4244 struct bgp *bgp_def = NULL;
4245
4246 bgp_def = bgp_get_default();
4247 assert(bgp_def);
4248
4249 vpn = (struct bgpevpn *)backet->data;
4250 if (vpn->tenant_vrf_id == bgp_vrf->vrf_id)
4251 bgpevpn_link_to_l3vni(vpn);
4252}
4253
996c9314
LB
4254int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac,
4255 struct in_addr originator_ip, int filter)
fe1dc5a3
MK
4256{
4257 struct bgp *bgp_vrf = NULL; /* bgp VRF instance */
4258 struct bgp *bgp_def = NULL; /* default bgp instance */
f1f8b53c
MK
4259 struct listnode *node = NULL;
4260 struct bgpevpn *vpn = NULL;
fe1dc5a3
MK
4261 as_t as = 0;
4262
4263 /* get the default instamce - required to get the AS number for VRF
523cafc4 4264 * auto-creatio
4265 */
fe1dc5a3
MK
4266 bgp_def = bgp_get_default();
4267 if (!bgp_def) {
996c9314
LB
4268 zlog_err(
4269 "Cannot process L3VNI %u ADD - default BGP instance not yet created",
4270 l3vni);
fe1dc5a3
MK
4271 return -1;
4272 }
4273 as = bgp_def->as;
4274
4275 /* if the BGP vrf instance doesnt exist - create one */
0b5131c9 4276 bgp_vrf = bgp_lookup_by_name(vrf_id_to_name(vrf_id));
fe1dc5a3
MK
4277 if (!bgp_vrf) {
4278
4279 int ret = 0;
4280
4281 ret = bgp_get(&bgp_vrf, &as, vrf_id_to_name(vrf_id),
4282 BGP_INSTANCE_TYPE_VRF);
4283 switch (ret) {
4284 case BGP_ERR_MULTIPLE_INSTANCE_NOT_SET:
4285 zlog_err("'bgp multiple-instance' not present\n");
4286 return -1;
4287 case BGP_ERR_AS_MISMATCH:
4288 zlog_err("BGP is already running; AS is %u\n", as);
4289 return -1;
4290 case BGP_ERR_INSTANCE_MISMATCH:
4291 zlog_err("BGP instance name and AS number mismatch\n");
4292 return -1;
4293 }
4294
4295 /* mark as auto created */
4296 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_AUTO);
4297 }
4298
4299 /* associate with l3vni */
4300 bgp_vrf->l3vni = l3vni;
4301
4302 /* set the router mac - to be used in mac-ip routes for this vrf */
4303 memcpy(&bgp_vrf->rmac, rmac, sizeof(struct ethaddr));
4304
b67a60d2 4305 /* set the originator ip */
4306 bgp_vrf->originator_ip = originator_ip;
4307
c48d9f5f
MK
4308 /* set the right filter - are we using l3vni only for prefix routes? */
4309 if (filter)
4310 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY);
4311
c581d8b0
MK
4312 /* auto derive RD/RT */
4313 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD))
4314 evpn_auto_rt_import_add_for_vrf(bgp_vrf);
4315 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD))
4316 evpn_auto_rt_export_add_for_vrf(bgp_vrf);
676f83b9 4317 bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf);
fe1dc5a3 4318
6a8657d0
MK
4319 /* link all corresponding l2vnis */
4320 hash_iterate(bgp_def->vnihash,
996c9314
LB
4321 (void (*)(struct hash_backet *,
4322 void *))link_l2vni_hash_to_l3vni,
6a8657d0
MK
4323 bgp_vrf);
4324
c48d9f5f
MK
4325 /* Only update all corresponding type-2 routes if we are advertising two
4326 * labels along with type-2 routes
4327 */
4328 if (!filter)
4329 for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn))
4330 update_routes_for_vni(bgp_def, vpn);
fe1dc5a3 4331
06d2e8f3
MK
4332 /* advertise type-5 routes if needed */
4333 update_advertise_vrf_routes(bgp_vrf);
4334
5ba238b7
MK
4335 /* install all remote routes belonging to this l3vni into correspondng
4336 * vrf */
4337 install_routes_for_vrf(bgp_vrf);
fe1dc5a3
MK
4338
4339 return 0;
4340}
4341
996c9314 4342int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id)
fe1dc5a3
MK
4343{
4344 struct bgp *bgp_vrf = NULL; /* bgp vrf instance */
f1f8b53c
MK
4345 struct bgp *bgp_def = NULL; /* default bgp instance */
4346 struct listnode *node = NULL;
18abc1eb 4347 struct listnode *next = NULL;
f1f8b53c 4348 struct bgpevpn *vpn = NULL;
fe1dc5a3
MK
4349
4350 bgp_vrf = bgp_lookup_by_vrf_id(vrf_id);
4351 if (!bgp_vrf) {
996c9314
LB
4352 zlog_err(
4353 "Cannot process L3VNI %u Del - Could not find BGP instance",
4354 l3vni);
fe1dc5a3
MK
4355 return -1;
4356 }
4357
f1f8b53c
MK
4358 bgp_def = bgp_get_default();
4359 if (!bgp_def) {
996c9314
LB
4360 zlog_err(
4361 "Cannot process L3VNI %u Del - Could not find default BGP instance",
4362 l3vni);
f1f8b53c
MK
4363 return -1;
4364 }
4365
1eb88002 4366 /* unimport remote routes from VRF, if it is AUTO vrf bgp_delete will
523cafc4 4367 * take care of uninstalling the routes from zebra
4368 */
1eb88002
MK
4369 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_AUTO))
4370 uninstall_routes_for_vrf(bgp_vrf);
5ba238b7 4371
06d2e8f3
MK
4372 /* delete/withdraw all type-5 routes */
4373 delete_withdraw_vrf_routes(bgp_vrf);
4374
fe1dc5a3
MK
4375 /* remove the l3vni from vrf instance */
4376 bgp_vrf->l3vni = 0;
4377
4378 /* remove the Rmac from the BGP vrf */
4379 memset(&bgp_vrf->rmac, 0, sizeof(struct ethaddr));
4380
c581d8b0 4381 /* delete RD/RT */
23a06e11 4382 if (bgp_vrf->vrf_import_rtl && !list_isempty(bgp_vrf->vrf_import_rtl)) {
10ebe1ab 4383 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf);
5ba238b7 4384 list_delete_all_node(bgp_vrf->vrf_import_rtl);
23a06e11
MK
4385 }
4386 if (bgp_vrf->vrf_export_rtl && !list_isempty(bgp_vrf->vrf_export_rtl)) {
5ba238b7 4387 list_delete_all_node(bgp_vrf->vrf_export_rtl);
23a06e11 4388 }
fe1dc5a3 4389
f1f8b53c 4390 /* update all corresponding local mac-ip routes */
c48d9f5f
MK
4391 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY)) {
4392 for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn)) {
4393 UNSET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS);
4394 update_routes_for_vni(bgp_def, vpn);
4395 }
4396 }
fe1dc5a3 4397
18abc1eb 4398 /* If any L2VNIs point to this instance, unlink them. */
4399 for (ALL_LIST_ELEMENTS(bgp_vrf->l2vnis, node, next, vpn))
4400 bgpevpn_unlink_from_l3vni(vpn);
4401
fe1dc5a3
MK
4402 /* Delete the instance if it was autocreated */
4403 if (CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_AUTO))
4404 bgp_delete(bgp_vrf);
4405
4406 return 0;
4407}
4408
128ea8ab 4409/*
4410 * Handle del of a local VNI.
4411 */
d62a17ae 4412int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni)
128ea8ab 4413{
d62a17ae 4414 struct bgpevpn *vpn;
128ea8ab 4415
d62a17ae 4416 if (!bgp->vnihash) {
4417 zlog_err("%u: VNI hash not created", bgp->vrf_id);
4418 return -1;
4419 }
128ea8ab 4420
d62a17ae 4421 /* Locate VNI hash */
4422 vpn = bgp_evpn_lookup_vni(bgp, vni);
4423 if (!vpn) {
4424 zlog_warn("%u: VNI hash entry for VNI %u not found at DEL",
4425 bgp->vrf_id, vni);
4426 return 0;
4427 }
128ea8ab 4428
d62a17ae 4429 /* Remove all local EVPN routes and schedule for processing (to
4430 * withdraw from peers).
4431 */
4432 delete_routes_for_vni(bgp, vpn);
128ea8ab 4433
db0e1937
MK
4434 /*
4435 * tunnel is no longer active, del tunnel ip address from tip_hash
4436 */
4437 bgp_tip_del(bgp, &vpn->originator_ip);
4438
d62a17ae 4439 /* Clear "live" flag and see if hash needs to be freed. */
4440 UNSET_FLAG(vpn->flags, VNI_FLAG_LIVE);
4441 if (!is_vni_configured(vpn))
4442 bgp_evpn_free(bgp, vpn);
128ea8ab 4443
d62a17ae 4444 return 0;
128ea8ab 4445}
4446
4447/*
d1911c26 4448 * Handle add (or update) of a local VNI. The VNI changes we care
4449 * about are for the local-tunnel-ip and the (tenant) VRF.
128ea8ab 4450 */
d62a17ae 4451int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
996c9314 4452 struct in_addr originator_ip, vrf_id_t tenant_vrf_id)
d62a17ae 4453{
4454 struct bgpevpn *vpn;
4455 struct prefix_evpn p;
4456
4457 if (!bgp->vnihash) {
4458 zlog_err("%u: VNI hash not created", bgp->vrf_id);
4459 return -1;
4460 }
4461
4462 /* Lookup VNI. If present and no change, exit. */
4463 vpn = bgp_evpn_lookup_vni(bgp, vni);
ddd16ed5 4464 if (vpn) {
29c53922 4465
d1911c26 4466 if (is_vni_live(vpn)
4467 && IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip)
4468 && vpn->tenant_vrf_id == tenant_vrf_id)
4469 /* Probably some other param has changed that we don't
4470 * care about. */
4471 return 0;
4472
4473 /* Update tenant_vrf_id if it has changed. */
6a8657d0
MK
4474 if (vpn->tenant_vrf_id != tenant_vrf_id) {
4475 bgpevpn_unlink_from_l3vni(vpn);
29c53922 4476 vpn->tenant_vrf_id = tenant_vrf_id;
6a8657d0
MK
4477 bgpevpn_link_to_l3vni(vpn);
4478 }
29c53922 4479
d1911c26 4480 /* If tunnel endpoint IP has changed, update (and delete prior
4481 * type-3 route, if needed.)
4482 */
4483 if (!IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip))
4484 handle_tunnel_ip_change(bgp, vpn, originator_ip);
d62a17ae 4485
d1911c26 4486 /* Update all routes with new endpoint IP and/or export RT
4487 * for VRFs
4488 */
4489 if (is_vni_live(vpn))
4490 update_routes_for_vni(bgp, vpn);
d62a17ae 4491 }
4492
4493 /* Create or update as appropriate. */
4494 if (!vpn) {
29c53922 4495 vpn = bgp_evpn_new(bgp, vni, originator_ip, tenant_vrf_id);
d62a17ae 4496 if (!vpn) {
4497 zlog_err(
4498 "%u: Failed to allocate VNI entry for VNI %u - at Add",
4499 bgp->vrf_id, vni);
4500 return -1;
4501 }
4502 }
4503
db0e1937 4504 /* if the VNI is live already, there is nothing more to do */
ddd16ed5
MK
4505 if (is_vni_live(vpn))
4506 return 0;
4507
d62a17ae 4508 /* Mark as "live" */
4509 SET_FLAG(vpn->flags, VNI_FLAG_LIVE);
4510
db0e1937
MK
4511 /* tunnel is now active, add tunnel-ip to db */
4512 bgp_tip_add(bgp, &originator_ip);
4513
4514 /* filter routes as nexthop database has changed */
4515 bgp_filter_evpn_routes_upon_martian_nh_change(bgp);
4516
d62a17ae 4517 /* Create EVPN type-3 route and schedule for processing. */
4518 build_evpn_type3_prefix(&p, vpn->originator_ip);
4519 if (update_evpn_route(bgp, vpn, &p, 0)) {
4520 zlog_err("%u: Type3 route creation failure for VNI %u",
4521 bgp->vrf_id, vni);
4522 return -1;
4523 }
4524
4525 /* If we have learnt and retained remote routes (VTEPs, MACs) for this
4526 * VNI,
4527 * install them.
4528 */
4529 install_routes_for_vni(bgp, vpn);
4530
d7d97010
MK
4531 /* If we are advertising gateway mac-ip
4532 It needs to be conveyed again to zebra */
4533 bgp_zebra_advertise_gw_macip(bgp, vpn->advertise_gw_macip, vpn->vni);
4534
d62a17ae 4535 return 0;
b18825eb 4536}
14c1a7bf 4537
7724c0a1 4538/*
4539 * Cleanup EVPN information on disable - Need to delete and withdraw
4540 * EVPN routes from peers.
4541 */
d62a17ae 4542void bgp_evpn_cleanup_on_disable(struct bgp *bgp)
7724c0a1 4543{
9d303b37
DL
4544 hash_iterate(bgp->vnihash, (void (*)(struct hash_backet *,
4545 void *))cleanup_vni_on_disable,
4546 bgp);
7724c0a1 4547}
4548
14c1a7bf 4549/*
4550 * Cleanup EVPN information - invoked at the time of bgpd exit or when the
4551 * BGP instance (default) is being freed.
4552 */
d62a17ae 4553void bgp_evpn_cleanup(struct bgp *bgp)
14c1a7bf 4554{
d62a17ae 4555 if (bgp->vnihash)
9d303b37
DL
4556 hash_iterate(bgp->vnihash, (void (*)(struct hash_backet *,
4557 void *))free_vni_entry,
4558 bgp);
d62a17ae 4559 if (bgp->import_rt_hash)
4560 hash_free(bgp->import_rt_hash);
4561 bgp->import_rt_hash = NULL;
10ebe1ab
MK
4562 if (bgp->vrf_import_rt_hash)
4563 hash_free(bgp->vrf_import_rt_hash);
4564 bgp->vrf_import_rt_hash = NULL;
d62a17ae 4565 if (bgp->vnihash)
4566 hash_free(bgp->vnihash);
4567 bgp->vnihash = NULL;
c581d8b0 4568 if (bgp->vrf_import_rtl)
bb7a24ab 4569 list_delete_and_null(&bgp->vrf_import_rtl);
c581d8b0 4570 if (bgp->vrf_export_rtl)
bb7a24ab 4571 list_delete_and_null(&bgp->vrf_export_rtl);
6a8657d0 4572 if (bgp->l2vnis)
bb7a24ab 4573 list_delete_and_null(&bgp->l2vnis);
14c1a7bf 4574}
4575
4576/*
4577 * Initialization for EVPN
4578 * Create
4579 * VNI hash table
4580 * hash for RT to VNI
14c1a7bf 4581 */
d62a17ae 4582void bgp_evpn_init(struct bgp *bgp)
4583{
4584 bgp->vnihash =
4585 hash_create(vni_hash_key_make, vni_hash_cmp, "BGP VNI Hash");
4586 bgp->import_rt_hash =
4587 hash_create(import_rt_hash_key_make, import_rt_hash_cmp,
4588 "BGP Import RT Hash");
10ebe1ab
MK
4589 bgp->vrf_import_rt_hash =
4590 hash_create(vrf_import_rt_hash_key_make, vrf_import_rt_hash_cmp,
4591 "BGP VRF Import RT Hash");
c581d8b0
MK
4592 bgp->vrf_import_rtl = list_new();
4593 bgp->vrf_import_rtl->cmp =
4594 (int (*)(void *, void *))evpn_route_target_cmp;
4595
4596 bgp->vrf_export_rtl = list_new();
4597 bgp->vrf_export_rtl->cmp =
4598 (int (*)(void *, void *))evpn_route_target_cmp;
6a8657d0 4599 bgp->l2vnis = list_new();
996c9314 4600 bgp->l2vnis->cmp = (int (*)(void *, void *))vni_hash_cmp;
14c1a7bf 4601}
10ebe1ab
MK
4602
4603void bgp_evpn_vrf_delete(struct bgp *bgp_vrf)
4604{
4605 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf);
4606}