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