]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_evpn.c
tools, doc: update checkpatch for u_int_*
[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"
32#include "bitfield.h"
128ea8ab 33#include "zclient.h"
7ef5a232
PG
34
35#include "bgpd/bgp_attr_evpn.h"
36#include "bgpd/bgpd.h"
37#include "bgpd/bgp_table.h"
38#include "bgpd/bgp_route.h"
39#include "bgpd/bgp_attr.h"
40#include "bgpd/bgp_mplsvpn.h"
9bedbb1e 41#include "bgpd/bgp_label.h"
7ef5a232 42#include "bgpd/bgp_evpn.h"
14c1a7bf 43#include "bgpd/bgp_evpn_private.h"
44#include "bgpd/bgp_ecommunity.h"
128ea8ab 45#include "bgpd/bgp_encap_types.h"
46#include "bgpd/bgp_debug.h"
47#include "bgpd/bgp_aspath.h"
d7d97010 48#include "bgpd/bgp_zebra.h"
db0e1937 49#include "bgpd/bgp_nexthop.h"
128ea8ab 50
51/*
52 * Definitions and external declarations.
53 */
54extern struct zclient *zclient;
55
56DEFINE_QOBJ_TYPE(bgpevpn)
57
58
59/*
60 * Static function declarations
61 */
d62a17ae 62static void delete_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
63 afi_t afi, safi_t safi, struct bgp_node *rn,
64 struct bgp_info **ri);
65static int delete_all_vni_routes(struct bgp *bgp, struct bgpevpn *vpn);
14c1a7bf 66
67/*
68 * Private functions.
69 */
70
71/*
72 * Make vni hash key.
73 */
d62a17ae 74static unsigned int vni_hash_key_make(void *p)
14c1a7bf 75{
d62a17ae 76 struct bgpevpn *vpn = p;
77 return (jhash_1word(vpn->vni, 0));
14c1a7bf 78}
79
80/*
81 * Comparison function for vni hash
82 */
d62a17ae 83static int vni_hash_cmp(const void *p1, const void *p2)
14c1a7bf 84{
d62a17ae 85 const struct bgpevpn *vpn1 = p1;
86 const struct bgpevpn *vpn2 = p2;
14c1a7bf 87
d62a17ae 88 if (!vpn1 && !vpn2)
89 return 1;
90 if (!vpn1 || !vpn2)
91 return 0;
92 return (vpn1->vni == vpn2->vni);
14c1a7bf 93}
94
10ebe1ab
MK
95/*
96 * Make vrf import route target hash key.
97 */
98static unsigned int vrf_import_rt_hash_key_make(void *p)
99{
100 struct vrf_irt_node *irt = p;
101 char *pnt = irt->rt.val;
5a1b3fb5
DS
102
103 return jhash(pnt, 8, 0x5abc1234);
10ebe1ab
MK
104}
105
106/*
107 * Comparison function for vrf import rt hash
108 */
109static int vrf_import_rt_hash_cmp(const void *p1, const void *p2)
110{
111 const struct vrf_irt_node *irt1 = p1;
112 const struct vrf_irt_node *irt2 = p2;
113
114 if (irt1 == NULL && irt2 == NULL)
115 return 1;
116
117 if (irt1 == NULL || irt2 == NULL)
118 return 0;
119
120 return (memcmp(irt1->rt.val, irt2->rt.val, ECOMMUNITY_SIZE) == 0);
121}
122
123/*
124 * Create a new vrf import_rt in default instance
125 */
126static struct vrf_irt_node *vrf_import_rt_new(struct ecommunity_val *rt)
127{
128 struct bgp *bgp_def = NULL;
129 struct vrf_irt_node *irt;
130
131 bgp_def = bgp_get_default();
132 if (!bgp_def) {
133 zlog_err("vrf import rt new - def instance not created yet");
134 return NULL;
135 }
136
137 irt = XCALLOC(MTYPE_BGP_EVPN_VRF_IMPORT_RT,
138 sizeof(struct vrf_irt_node));
139 if (!irt)
140 return NULL;
141
142 irt->rt = *rt;
143 irt->vrfs = list_new();
144
145 /* Add to hash */
146 if (!hash_get(bgp_def->vrf_import_rt_hash, irt, hash_alloc_intern)) {
147 XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT, irt);
148 return NULL;
149 }
150
151 return irt;
152}
153
154/*
155 * Free the vrf import rt node
156 */
157static void vrf_import_rt_free(struct vrf_irt_node *irt)
158{
159 struct bgp *bgp_def = NULL;
160
161 bgp_def = bgp_get_default();
162 if (!bgp_def) {
163 zlog_err("vrf import rt free - def instance not created yet");
164 return;
165 }
166
167 hash_release(bgp_def->vrf_import_rt_hash, irt);
168 XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT, irt);
169}
170
171/*
172 * Function to lookup Import RT node - used to map a RT to set of
173 * VNIs importing routes with that RT.
174 */
175static struct vrf_irt_node *lookup_vrf_import_rt(struct ecommunity_val *rt)
176{
177 struct bgp *bgp_def = NULL;
178 struct vrf_irt_node *irt;
179 struct vrf_irt_node tmp;
180
181 bgp_def = bgp_get_default();
182 if (!bgp_def) {
183 zlog_err("vrf import rt lookup - def instance not created yet");
184 return NULL;
185 }
186
187 memset(&tmp, 0, sizeof(struct vrf_irt_node));
188 memcpy(&tmp.rt, rt, ECOMMUNITY_SIZE);
189 irt = hash_lookup(bgp_def->vrf_import_rt_hash, &tmp);
190 return irt;
191}
192
193/*
194 * Is specified VRF present on the RT's list of "importing" VRFs?
195 */
996c9314 196static int is_vrf_present_in_irt_vrfs(struct list *vrfs, struct bgp *bgp_vrf)
10ebe1ab
MK
197{
198 struct listnode *node = NULL, *nnode = NULL;
199 struct bgp *tmp_bgp_vrf = NULL;
200
201 for (ALL_LIST_ELEMENTS(vrfs, node, nnode, tmp_bgp_vrf)) {
202 if (tmp_bgp_vrf == bgp_vrf)
203 return 1;
204 }
205 return 0;
206}
207
14c1a7bf 208/*
209 * Make import route target hash key.
210 */
d62a17ae 211static unsigned int import_rt_hash_key_make(void *p)
14c1a7bf 212{
d62a17ae 213 struct irt_node *irt = p;
214 char *pnt = irt->rt.val;
5a1b3fb5
DS
215
216 return jhash(pnt, 8, 0xdeadbeef);
14c1a7bf 217}
218
219/*
220 * Comparison function for import rt hash
221 */
d62a17ae 222static int import_rt_hash_cmp(const void *p1, const void *p2)
14c1a7bf 223{
d62a17ae 224 const struct irt_node *irt1 = p1;
225 const struct irt_node *irt2 = p2;
14c1a7bf 226
d62a17ae 227 if (irt1 == NULL && irt2 == NULL)
228 return 1;
14c1a7bf 229
d62a17ae 230 if (irt1 == NULL || irt2 == NULL)
231 return 0;
14c1a7bf 232
d62a17ae 233 return (memcmp(irt1->rt.val, irt2->rt.val, ECOMMUNITY_SIZE) == 0);
14c1a7bf 234}
235
7724c0a1 236/*
128ea8ab 237 * Create a new import_rt
238 */
d62a17ae 239static struct irt_node *import_rt_new(struct bgp *bgp,
240 struct ecommunity_val *rt)
128ea8ab 241{
d62a17ae 242 struct irt_node *irt;
128ea8ab 243
d62a17ae 244 if (!bgp)
245 return NULL;
128ea8ab 246
d62a17ae 247 irt = XCALLOC(MTYPE_BGP_EVPN_IMPORT_RT, sizeof(struct irt_node));
248 if (!irt)
249 return NULL;
128ea8ab 250
d62a17ae 251 irt->rt = *rt;
252 irt->vnis = list_new();
128ea8ab 253
d62a17ae 254 /* Add to hash */
255 if (!hash_get(bgp->import_rt_hash, irt, hash_alloc_intern)) {
256 XFREE(MTYPE_BGP_EVPN_IMPORT_RT, irt);
257 return NULL;
258 }
128ea8ab 259
d62a17ae 260 return irt;
128ea8ab 261}
262
263/*
264 * Free the import rt node
7724c0a1 265 */
d62a17ae 266static void import_rt_free(struct bgp *bgp, struct irt_node *irt)
7724c0a1 267{
d62a17ae 268 hash_release(bgp->import_rt_hash, irt);
269 XFREE(MTYPE_BGP_EVPN_IMPORT_RT, irt);
7724c0a1 270}
271
14c1a7bf 272/*
128ea8ab 273 * Function to lookup Import RT node - used to map a RT to set of
274 * VNIs importing routes with that RT.
275 */
d62a17ae 276static struct irt_node *lookup_import_rt(struct bgp *bgp,
277 struct ecommunity_val *rt)
128ea8ab 278{
d62a17ae 279 struct irt_node *irt;
280 struct irt_node tmp;
128ea8ab 281
d62a17ae 282 memset(&tmp, 0, sizeof(struct irt_node));
283 memcpy(&tmp.rt, rt, ECOMMUNITY_SIZE);
284 irt = hash_lookup(bgp->import_rt_hash, &tmp);
285 return irt;
128ea8ab 286}
287
288/*
289 * Is specified VNI present on the RT's list of "importing" VNIs?
290 */
d62a17ae 291static int is_vni_present_in_irt_vnis(struct list *vnis, struct bgpevpn *vpn)
128ea8ab 292{
d62a17ae 293 struct listnode *node, *nnode;
294 struct bgpevpn *tmp_vpn;
128ea8ab 295
d62a17ae 296 for (ALL_LIST_ELEMENTS(vnis, node, nnode, tmp_vpn)) {
297 if (tmp_vpn == vpn)
298 return 1;
299 }
128ea8ab 300
d62a17ae 301 return 0;
128ea8ab 302}
303
304/*
305 * Compare Route Targets.
306 */
d62a17ae 307static int evpn_route_target_cmp(struct ecommunity *ecom1,
308 struct ecommunity *ecom2)
128ea8ab 309{
d62a17ae 310 if (ecom1 && !ecom2)
311 return -1;
128ea8ab 312
d62a17ae 313 if (!ecom1 && ecom2)
314 return 1;
128ea8ab 315
d62a17ae 316 if (!ecom1 && !ecom2)
317 return 0;
128ea8ab 318
d62a17ae 319 if (ecom1->str && !ecom2->str)
320 return -1;
128ea8ab 321
d62a17ae 322 if (!ecom1->str && ecom2->str)
323 return 1;
128ea8ab 324
d62a17ae 325 if (!ecom1->str && !ecom2->str)
326 return 0;
128ea8ab 327
d62a17ae 328 return strcmp(ecom1->str, ecom2->str);
128ea8ab 329}
330
331/*
332 * Mask off global-admin field of specified extended community (RT),
333 * just retain the local-admin field.
334 */
d62a17ae 335static inline void mask_ecom_global_admin(struct ecommunity_val *dst,
336 struct ecommunity_val *src)
128ea8ab 337{
d62a17ae 338 u_char type;
128ea8ab 339
d62a17ae 340 type = src->val[0];
341 dst->val[0] = 0;
342 if (type == ECOMMUNITY_ENCODE_AS) {
343 dst->val[2] = dst->val[3] = 0;
344 } else if (type == ECOMMUNITY_ENCODE_AS4
345 || type == ECOMMUNITY_ENCODE_IP) {
346 dst->val[2] = dst->val[3] = 0;
347 dst->val[4] = dst->val[5] = 0;
348 }
128ea8ab 349}
350
10ebe1ab
MK
351/*
352 * Map one RT to specified VRF.
353 * bgp_vrf = BGP vrf instance
354 */
996c9314 355static void map_vrf_to_rt(struct bgp *bgp_vrf, struct ecommunity_val *eval)
10ebe1ab
MK
356{
357 struct vrf_irt_node *irt = NULL;
358 struct ecommunity_val eval_tmp;
359
360 /* If using "automatic" RT,
361 * we only care about the local-admin sub-field.
362 * This is to facilitate using L3VNI(VRF-VNI)
363 * as the RT for EBGP peering too.
364 */
365 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
996c9314 366 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD))
10ebe1ab
MK
367 mask_ecom_global_admin(&eval_tmp, eval);
368
369 irt = lookup_vrf_import_rt(&eval_tmp);
e066d6d0
DS
370 if (irt && is_vrf_present_in_irt_vrfs(irt->vrfs, bgp_vrf))
371 /* Already mapped. */
372 return;
10ebe1ab 373
e066d6d0 374 if (!irt)
10ebe1ab 375 irt = vrf_import_rt_new(&eval_tmp);
10ebe1ab
MK
376
377 /* Add VRF to the list for this RT. */
378 listnode_add(irt->vrfs, bgp_vrf);
379}
380
381/*
382 * Unmap specified VRF from specified RT. If there are no other
383 * VRFs for this RT, then the RT hash is deleted.
384 * bgp_vrf: BGP VRF specific instance
385 */
996c9314 386static void unmap_vrf_from_rt(struct bgp *bgp_vrf, struct vrf_irt_node *irt)
10ebe1ab
MK
387{
388 /* Delete VRF from list for this RT. */
389 listnode_delete(irt->vrfs, bgp_vrf);
390 if (!listnode_head(irt->vrfs)) {
bb7a24ab 391 list_delete_and_null(&irt->vrfs);
10ebe1ab
MK
392 vrf_import_rt_free(irt);
393 }
394}
395
128ea8ab 396/*
397 * Map one RT to specified VNI.
14c1a7bf 398 */
d62a17ae 399static void map_vni_to_rt(struct bgp *bgp, struct bgpevpn *vpn,
400 struct ecommunity_val *eval)
128ea8ab 401{
d62a17ae 402 struct irt_node *irt;
403 struct ecommunity_val eval_tmp;
128ea8ab 404
d62a17ae 405 /* If using "automatic" RT, we only care about the local-admin
406 * sub-field.
407 * This is to facilitate using VNI as the RT for EBGP peering too.
408 */
409 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
410 if (!is_import_rt_configured(vpn))
411 mask_ecom_global_admin(&eval_tmp, eval);
128ea8ab 412
d62a17ae 413 irt = lookup_import_rt(bgp, &eval_tmp);
414 if (irt && irt->vnis)
415 if (is_vni_present_in_irt_vnis(irt->vnis, vpn))
416 /* Already mapped. */
417 return;
128ea8ab 418
d62a17ae 419 if (!irt) {
420 irt = import_rt_new(bgp, &eval_tmp);
421 assert(irt);
422 }
128ea8ab 423
d62a17ae 424 /* Add VNI to the hash list for this RT. */
425 listnode_add(irt->vnis, vpn);
128ea8ab 426}
427
428/*
429 * Unmap specified VNI from specified RT. If there are no other
430 * VNIs for this RT, then the RT hash is deleted.
431 */
d62a17ae 432static void unmap_vni_from_rt(struct bgp *bgp, struct bgpevpn *vpn,
433 struct irt_node *irt)
14c1a7bf 434{
d62a17ae 435 /* Delete VNI from hash list for this RT. */
436 listnode_delete(irt->vnis, vpn);
437 if (!listnode_head(irt->vnis)) {
acdf5e25 438 list_delete_and_null(&irt->vnis);
d62a17ae 439 import_rt_free(bgp, irt);
440 }
14c1a7bf 441}
442
128ea8ab 443/*
444 * Create RT extended community automatically from passed information:
445 * of the form AS:VNI.
446 * NOTE: We use only the lower 16 bits of the AS. This is sufficient as
447 * the need is to get a RT value that will be unique across different
448 * VNIs but the same across routers (in the same AS) for a particular
449 * VNI.
450 */
c581d8b0 451static void form_auto_rt(struct bgp *bgp, vni_t vni, struct list *rtl)
128ea8ab 452{
d62a17ae 453 struct ecommunity_val eval;
454 struct ecommunity *ecomadd;
128ea8ab 455
c581d8b0 456 encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
128ea8ab 457
d62a17ae 458 ecomadd = ecommunity_new();
459 ecommunity_add_val(ecomadd, &eval);
460 listnode_add_sort(rtl, ecomadd);
128ea8ab 461}
14c1a7bf 462
463/*
128ea8ab 464 * Derive RD and RT for a VNI automatically. Invoked at the time of
465 * creation of a VNI.
466 */
d62a17ae 467static void derive_rd_rt_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 468{
d62a17ae 469 bgp_evpn_derive_auto_rd(bgp, vpn);
470 bgp_evpn_derive_auto_rt_import(bgp, vpn);
471 bgp_evpn_derive_auto_rt_export(bgp, vpn);
128ea8ab 472}
473
1ec31309 474/*
475 * Convert nexthop (remote VTEP IP) into an IPv6 address.
476 */
477static void evpn_convert_nexthop_to_ipv6(struct attr *attr)
478{
479 if (BGP_ATTR_NEXTHOP_AFI_IP6(attr))
480 return;
481 ipv4_to_ipv4_mapped_ipv6(&attr->mp_nexthop_global, attr->nexthop);
482 attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
483}
484
128ea8ab 485/*
486 * Add (update) or delete MACIP from zebra.
14c1a7bf 487 */
d62a17ae 488static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
489 struct prefix_evpn *p,
490 struct in_addr remote_vtep_ip, int add,
ead40654 491 u_char flags)
d62a17ae 492{
493 struct stream *s;
494 int ipa_len;
495 char buf1[ETHER_ADDR_STRLEN];
496 char buf2[INET6_ADDRSTRLEN];
497 char buf3[INET6_ADDRSTRLEN];
498
499 /* Check socket. */
500 if (!zclient || zclient->sock < 0)
501 return 0;
502
503 /* Don't try to register if Zebra doesn't know of this instance. */
504 if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
505 return 0;
506
507 s = zclient->obuf;
508 stream_reset(s);
509
996c9314
LB
510 zclient_create_header(
511 s, add ? ZEBRA_REMOTE_MACIP_ADD : ZEBRA_REMOTE_MACIP_DEL,
512 bgp->vrf_id);
d62a17ae 513 stream_putl(s, vpn->vni);
28328ea9 514 stream_put(s, &p->prefix.mac.octet, ETH_ALEN); /* Mac Addr */
d62a17ae 515 /* IP address length and IP address, if any. */
516 if (IS_EVPN_PREFIX_IPADDR_NONE(p))
517 stream_putl(s, 0);
518 else {
519 ipa_len = IS_EVPN_PREFIX_IPADDR_V4(p) ? IPV4_MAX_BYTELEN
520 : IPV6_MAX_BYTELEN;
521 stream_putl(s, ipa_len);
522 stream_put(s, &p->prefix.ip.ip.addr, ipa_len);
523 }
524 stream_put_in_addr(s, &remote_vtep_ip);
525
ead40654 526 /* TX flags - MAC sticky status and/or gateway mac */
d62a17ae 527 if (add)
ead40654 528 stream_putc(s, flags);
d62a17ae 529
530 stream_putw_at(s, 0, stream_get_endp(s));
531
532 if (bgp_debug_zebra(NULL))
996c9314
LB
533 zlog_debug(
534 "Tx %s MACIP, VNI %u MAC %s IP %s (flags: 0x%x) remote VTEP %s",
535 add ? "ADD" : "DEL", vpn->vni,
536 prefix_mac2str(&p->prefix.mac, buf1, sizeof(buf1)),
537 ipaddr2str(&p->prefix.ip, buf3, sizeof(buf3)), flags,
538 inet_ntop(AF_INET, &remote_vtep_ip, buf2,
539 sizeof(buf2)));
d62a17ae 540
541 return zclient_send_message(zclient);
7ef5a232 542}
b18825eb 543
128ea8ab 544/*
545 * Add (update) or delete remote VTEP from zebra.
546 */
d62a17ae 547static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
548 struct prefix_evpn *p, int add)
128ea8ab 549{
d62a17ae 550 struct stream *s;
128ea8ab 551
d62a17ae 552 /* Check socket. */
553 if (!zclient || zclient->sock < 0)
554 return 0;
128ea8ab 555
d62a17ae 556 /* Don't try to register if Zebra doesn't know of this instance. */
557 if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
558 return 0;
128ea8ab 559
d62a17ae 560 s = zclient->obuf;
561 stream_reset(s);
128ea8ab 562
996c9314
LB
563 zclient_create_header(
564 s, add ? ZEBRA_REMOTE_VTEP_ADD : ZEBRA_REMOTE_VTEP_DEL,
565 bgp->vrf_id);
d62a17ae 566 stream_putl(s, vpn->vni);
567 if (IS_EVPN_PREFIX_IPADDR_V4(p))
568 stream_put_in_addr(s, &p->prefix.ip.ipaddr_v4);
569 else if (IS_EVPN_PREFIX_IPADDR_V6(p)) {
570 zlog_err(
571 "Bad remote IP when trying to %s remote VTEP for VNI %u",
572 add ? "ADD" : "DEL", vpn->vni);
573 return -1;
574 }
128ea8ab 575
d62a17ae 576 stream_putw_at(s, 0, stream_get_endp(s));
128ea8ab 577
d62a17ae 578 if (bgp_debug_zebra(NULL))
579 zlog_debug("Tx %s Remote VTEP, VNI %u remote VTEP %s",
580 add ? "ADD" : "DEL", vpn->vni,
581 inet_ntoa(p->prefix.ip.ipaddr_v4));
128ea8ab 582
d62a17ae 583 return zclient_send_message(zclient);
128ea8ab 584}
585
342dd0c6 586/*
587 * Build extended communities for EVPN prefix route.
588 */
589static void build_evpn_type5_route_extcomm(struct bgp *bgp_vrf,
590 struct attr *attr)
591{
592 struct ecommunity ecom_encap;
593 struct ecommunity ecom_rmac;
594 struct ecommunity_val eval;
595 struct ecommunity_val eval_rmac;
596 bgp_encap_types tnl_type;
597 struct listnode *node, *nnode;
598 struct ecommunity *ecom;
599 struct list *vrf_export_rtl = NULL;
600
601 /* Encap */
602 tnl_type = BGP_ENCAP_TYPE_VXLAN;
603 memset(&ecom_encap, 0, sizeof(ecom_encap));
604 encode_encap_extcomm(tnl_type, &eval);
605 ecom_encap.size = 1;
606 ecom_encap.val = (u_int8_t *)eval.val;
607
608 /* Add Encap */
609 attr->ecommunity = ecommunity_dup(&ecom_encap);
610
611 /* Add the export RTs for L3VNI/VRF */
612 vrf_export_rtl = bgp_vrf->vrf_export_rtl;
613 if (vrf_export_rtl && !list_isempty(vrf_export_rtl)) {
614 for (ALL_LIST_ELEMENTS(vrf_export_rtl, node, nnode, ecom))
996c9314
LB
615 attr->ecommunity =
616 ecommunity_merge(attr->ecommunity, ecom);
342dd0c6 617 }
618
619 /* add the router mac extended community */
620 if (!is_zero_mac(&attr->rmac)) {
621 memset(&ecom_rmac, 0, sizeof(ecom_rmac));
622 encode_rmac_extcomm(&eval_rmac, &attr->rmac);
623 ecom_rmac.size = 1;
624 ecom_rmac.val = (uint8_t *)eval_rmac.val;
996c9314
LB
625 attr->ecommunity =
626 ecommunity_merge(attr->ecommunity, &ecom_rmac);
342dd0c6 627 }
628
629 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
630}
631
128ea8ab 632/*
1ec31309 633 * Build extended communities for EVPN route.
634 * This function is applicable for type-2 and type-3 routes. The layer-2 RT
635 * and ENCAP extended communities are applicable for all routes.
636 * The default gateway extended community and MAC mobility (sticky) extended
637 * community are added as needed based on passed settings - only for type-2
638 * routes. Likewise, the layer-3 RT and Router MAC extended communities are
639 * added, if present, based on passed settings - only for non-link-local
640 * type-2 routes.
128ea8ab 641 */
7ec156a9 642static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
1ec31309 643 int add_l3_ecomm)
128ea8ab 644{
d62a17ae 645 struct ecommunity ecom_encap;
646 struct ecommunity ecom_sticky;
ead40654 647 struct ecommunity ecom_default_gw;
bc59a672 648 struct ecommunity ecom_rmac;
d62a17ae 649 struct ecommunity_val eval;
650 struct ecommunity_val eval_sticky;
ead40654 651 struct ecommunity_val eval_default_gw;
bc59a672 652 struct ecommunity_val eval_rmac;
d62a17ae 653 bgp_encap_types tnl_type;
654 struct listnode *node, *nnode;
655 struct ecommunity *ecom;
656 u_int32_t seqnum;
7a3e76f1 657 struct list *vrf_export_rtl = NULL;
128ea8ab 658
d62a17ae 659 /* Encap */
660 tnl_type = BGP_ENCAP_TYPE_VXLAN;
661 memset(&ecom_encap, 0, sizeof(ecom_encap));
662 encode_encap_extcomm(tnl_type, &eval);
663 ecom_encap.size = 1;
664 ecom_encap.val = (u_int8_t *)eval.val;
128ea8ab 665
d62a17ae 666 /* Add Encap */
667 attr->ecommunity = ecommunity_dup(&ecom_encap);
128ea8ab 668
7a3e76f1 669 /* Add the export RTs for L2VNI */
d62a17ae 670 for (ALL_LIST_ELEMENTS(vpn->export_rtl, node, nnode, ecom))
671 attr->ecommunity = ecommunity_merge(attr->ecommunity, ecom);
128ea8ab 672
1ec31309 673 /* Add the export RTs for L3VNI if told to - caller determines
674 * when this should be done.
523cafc4 675 */
1ec31309 676 if (add_l3_ecomm) {
7ec156a9
MK
677 vrf_export_rtl = bgpevpn_get_vrf_export_rtl(vpn);
678 if (vrf_export_rtl && !list_isempty(vrf_export_rtl)) {
679 for (ALL_LIST_ELEMENTS(vrf_export_rtl, node, nnode,
680 ecom))
996c9314
LB
681 attr->ecommunity = ecommunity_merge(
682 attr->ecommunity, ecom);
7ec156a9 683 }
f1f8b53c 684 }
7a3e76f1 685
1ec31309 686 /* Add MAC mobility (sticky) if needed. */
d62a17ae 687 if (attr->sticky) {
688 seqnum = 0;
689 memset(&ecom_sticky, 0, sizeof(ecom_sticky));
690 encode_mac_mobility_extcomm(1, seqnum, &eval_sticky);
691 ecom_sticky.size = 1;
692 ecom_sticky.val = (u_int8_t *)eval_sticky.val;
693 attr->ecommunity =
694 ecommunity_merge(attr->ecommunity, &ecom_sticky);
695 }
c85c03c7 696
1ec31309 697 /* Add RMAC, if told to. */
698 if (add_l3_ecomm) {
bc59a672
MK
699 memset(&ecom_rmac, 0, sizeof(ecom_rmac));
700 encode_rmac_extcomm(&eval_rmac, &attr->rmac);
701 ecom_rmac.size = 1;
702 ecom_rmac.val = (uint8_t *)eval_rmac.val;
996c9314
LB
703 attr->ecommunity =
704 ecommunity_merge(attr->ecommunity, &ecom_rmac);
bc59a672
MK
705 }
706
1ec31309 707 /* Add default gateway, if needed. */
ead40654
MK
708 if (attr->default_gw) {
709 memset(&ecom_default_gw, 0, sizeof(ecom_default_gw));
710 encode_default_gw_extcomm(&eval_default_gw);
711 ecom_default_gw.size = 1;
712 ecom_default_gw.val = (uint8_t *)eval_default_gw.val;
996c9314
LB
713 attr->ecommunity =
714 ecommunity_merge(attr->ecommunity, &ecom_default_gw);
ead40654
MK
715 }
716
d62a17ae 717 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
128ea8ab 718}
719
720/*
721 * Add MAC mobility extended community to attribute.
722 */
d62a17ae 723static void add_mac_mobility_to_attr(u_int32_t seq_num, struct attr *attr)
724{
725 struct ecommunity ecom_tmp;
726 struct ecommunity_val eval;
421bb26a 727 u_int8_t *ecom_val_ptr;
d62a17ae 728 int i;
729 u_int8_t *pnt;
730 int type = 0;
731 int sub_type = 0;
732
733 /* Build MM */
734 encode_mac_mobility_extcomm(0, seq_num, &eval);
735
736 /* Find current MM ecommunity */
421bb26a 737 ecom_val_ptr = NULL;
d62a17ae 738
739 if (attr->ecommunity) {
740 for (i = 0; i < attr->ecommunity->size; i++) {
741 pnt = attr->ecommunity->val + (i * 8);
742 type = *pnt++;
743 sub_type = *pnt++;
744
745 if (type == ECOMMUNITY_ENCODE_EVPN
746 && sub_type
747 == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY) {
421bb26a
MK
748 ecom_val_ptr =
749 (u_int8_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;
764 ecom_tmp.val = (u_int8_t *)eval.val;
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,
ead40654 774 struct in_addr remote_vtep_ip, u_char 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;
996c9314 851 u_char 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,
1a98c087 1114 struct bgp_info **ri, u_char flags)
d62a17ae 1115{
1116 struct bgp_info *tmp_ri;
1117 struct bgp_info *local_ri, *remote_ri;
1118 struct attr *attr_new;
b57ba6d2
MK
1119 mpls_label_t label[BGP_MAX_LABELS];
1120 u_int32_t num_labels = 1;
d62a17ae 1121 int route_change = 1;
1122 u_char 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)) {
d62a17ae 1170 u_int32_t cur_seqnum;
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,
1a98c087 1263 struct prefix_evpn *p, u_char 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 &&
1298 (IS_EVPN_PREFIX_IPADDR_V4(p) ||
1299 !IN6_IS_ADDR_LINKLOCAL(&p->prefix.ip.ipaddr_v6)) &&
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
1ec31309 1544 if (IS_EVPN_PREFIX_IPADDR_V6(evp) &&
1545 IN6_IS_ADDR_LINKLOCAL(&evp->prefix.ip.ipaddr_v6))
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));
90264d64
MK
1797 if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
1798 ip_prefix_from_type2_prefix(evp, pp);
523cafc4 1799 else if (evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE)
90264d64 1800 ip_prefix_from_type5_prefix(evp, pp);
d3135ba3 1801
1eb88002 1802 if (bgp_debug_zebra(NULL)) {
996c9314
LB
1803 zlog_debug(
1804 "installing evpn prefix %s as ip prefix %s in vrf %s",
1805 prefix2str(evp, buf, sizeof(buf)),
1806 prefix2str(pp, buf1, sizeof(buf)),
1807 vrf_id_to_name(bgp_vrf->vrf_id));
1eb88002
MK
1808 }
1809
d3135ba3 1810 /* Create (or fetch) route within the VRF. */
1811 /* NOTE: There is no RD here. */
1812 if (IS_EVPN_PREFIX_IPADDR_V4(evp)) {
1813 afi = AFI_IP;
1814 safi = SAFI_UNICAST;
1815 rn = bgp_node_get(bgp_vrf->rib[afi][safi], pp);
1816 } else if (IS_EVPN_PREFIX_IPADDR_V6(evp)) {
1817 afi = AFI_IP6;
1818 safi = SAFI_UNICAST;
1819 rn = bgp_node_get(bgp_vrf->rib[afi][safi], pp);
1820 } else
1821 return 0;
1822
1ec31309 1823 /* EVPN routes currently only support a IPv4 next hop which corresponds
1824 * to the remote VTEP. When importing into a VRF, if it is IPv6 host
1825 * route, we have to convert the next hop to an IPv4-mapped address
1826 * for the rest of the code to flow through.
1827 */
1828 bgp_attr_dup(&attr, parent_ri->attr);
1829 if (afi == AFI_IP6)
1830 evpn_convert_nexthop_to_ipv6(&attr);
1831
d3135ba3 1832 /* Check if route entry is already present. */
1833 for (ri = rn->info; ri; ri = ri->next)
1834 if (ri->extra
1835 && (struct bgp_info *)ri->extra->parent == parent_ri)
1836 break;
1837
1838 if (!ri) {
1839 /* Add (or update) attribute to hash. */
1ec31309 1840 attr_new = bgp_attr_intern(&attr);
d3135ba3 1841
1842 /* Create new route with its attribute. */
90f4f482 1843 ri = info_make(parent_ri->type, BGP_ROUTE_IMPORTED, 0,
d3135ba3 1844 parent_ri->peer, attr_new, rn);
1845 SET_FLAG(ri->flags, BGP_INFO_VALID);
1846 bgp_info_extra_get(ri);
1847 ri->extra->parent = parent_ri;
b57ba6d2 1848 if (parent_ri->extra) {
d3135ba3 1849 memcpy(&ri->extra->label, &parent_ri->extra->label,
b57ba6d2
MK
1850 sizeof(ri->extra->label));
1851 ri->extra->num_labels = parent_ri->extra->num_labels;
1852 }
d3135ba3 1853 bgp_info_add(rn, ri);
1854 } else {
1ec31309 1855 if (attrhash_cmp(ri->attr, &attr)
d3135ba3 1856 && !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
1857 bgp_unlock_node(rn);
1858 return 0;
1859 }
1860 /* The attribute has changed. */
1861 /* Add (or update) attribute to hash. */
1ec31309 1862 attr_new = bgp_attr_intern(&attr);
d3135ba3 1863
1864 /* Restore route, if needed. */
1865 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
1866 bgp_info_restore(rn, ri);
1867
1868 /* Mark if nexthop has changed. */
1ec31309 1869 if ((afi == AFI_IP &&
1870 !IPV4_ADDR_SAME(&ri->attr->nexthop, &attr_new->nexthop)) ||
1871 (afi == AFI_IP6 &&
1872 !IPV6_ADDR_SAME(&ri->attr->mp_nexthop_global,
1873 &attr_new->mp_nexthop_global)))
d3135ba3 1874 SET_FLAG(ri->flags, BGP_INFO_IGP_CHANGED);
1875
1876 /* Unintern existing, set to new. */
1877 bgp_attr_unintern(&ri->attr);
1878 ri->attr = attr_new;
1879 ri->uptime = bgp_clock();
1880 }
1881
1882 /* Perform route selection and update zebra, if required. */
1eb88002 1883 bgp_process(bgp_vrf, rn, afi, safi);
d3135ba3 1884
1885 return ret;
1886}
1887
128ea8ab 1888/*
1889 * Install route entry into the VNI routing table and invoke route selection.
1890 */
d62a17ae 1891static int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
1892 struct prefix_evpn *p,
1893 struct bgp_info *parent_ri)
1894{
1895 struct bgp_node *rn;
1896 struct bgp_info *ri;
1897 struct attr *attr_new;
1898 int ret;
1899
1900 /* Create (or fetch) route within the VNI. */
1901 /* NOTE: There is no RD here. */
1902 rn = bgp_node_get(vpn->route_table, (struct prefix *)p);
1903
1904 /* Check if route entry is already present. */
1905 for (ri = rn->info; ri; ri = ri->next)
1906 if (ri->extra
1907 && (struct bgp_info *)ri->extra->parent == parent_ri)
1908 break;
1909
1910 if (!ri) {
1911 /* Add (or update) attribute to hash. */
1912 attr_new = bgp_attr_intern(parent_ri->attr);
1913
1914 /* Create new route with its attribute. */
90f4f482 1915 ri = info_make(parent_ri->type, BGP_ROUTE_IMPORTED, 0,
d62a17ae 1916 parent_ri->peer, attr_new, rn);
1917 SET_FLAG(ri->flags, BGP_INFO_VALID);
1918 bgp_info_extra_get(ri);
1919 ri->extra->parent = parent_ri;
b57ba6d2 1920 if (parent_ri->extra) {
d62a17ae 1921 memcpy(&ri->extra->label, &parent_ri->extra->label,
b57ba6d2
MK
1922 sizeof(ri->extra->label));
1923 ri->extra->num_labels = parent_ri->extra->num_labels;
1924 }
d62a17ae 1925 bgp_info_add(rn, ri);
1926 } else {
1927 if (attrhash_cmp(ri->attr, parent_ri->attr)
1928 && !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
1929 bgp_unlock_node(rn);
1930 return 0;
1931 }
1932 /* The attribute has changed. */
1933 /* Add (or update) attribute to hash. */
1934 attr_new = bgp_attr_intern(parent_ri->attr);
1935
1936 /* Restore route, if needed. */
1937 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
1938 bgp_info_restore(rn, ri);
1939
1940 /* Mark if nexthop has changed. */
1941 if (!IPV4_ADDR_SAME(&ri->attr->nexthop, &attr_new->nexthop))
1942 SET_FLAG(ri->flags, BGP_INFO_IGP_CHANGED);
1943
1944 /* Unintern existing, set to new. */
1945 bgp_attr_unintern(&ri->attr);
1946 ri->attr = attr_new;
1947 ri->uptime = bgp_clock();
1948 }
1949
1950 /* Perform route selection and update zebra, if required. */
1951 ret = evpn_route_select_install(bgp, vpn, rn);
1952
1953 return ret;
128ea8ab 1954}
1955
d3135ba3 1956/*
1957 * Uninstall route entry from the VRF routing table and send message
1958 * to zebra, if appropriate.
1959 */
1960static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
1961 struct prefix_evpn *evp,
1962 struct bgp_info *parent_ri)
1963{
1964 struct bgp_node *rn;
1965 struct bgp_info *ri;
c4edf708 1966 int ret = 0;
d3135ba3 1967 struct prefix p;
1968 struct prefix *pp = &p;
1969 afi_t afi = 0;
1970 safi_t safi = 0;
1eb88002
MK
1971 char buf[PREFIX_STRLEN];
1972 char buf1[PREFIX_STRLEN];
d3135ba3 1973
1974 memset(pp, 0, sizeof(struct prefix));
42cb44f2
MK
1975 if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
1976 ip_prefix_from_type2_prefix(evp, pp);
655b04d1 1977 else if (evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE)
42cb44f2 1978 ip_prefix_from_type5_prefix(evp, pp);
d3135ba3 1979
1eb88002 1980 if (bgp_debug_zebra(NULL)) {
996c9314
LB
1981 zlog_debug(
1982 "uninstalling evpn prefix %s as ip prefix %s in vrf %s",
1983 prefix2str(evp, buf, sizeof(buf)),
1984 prefix2str(pp, buf1, sizeof(buf)),
1985 vrf_id_to_name(bgp_vrf->vrf_id));
1eb88002
MK
1986 }
1987
d3135ba3 1988 /* Locate route within the VRF. */
1989 /* NOTE: There is no RD here. */
1990 if (IS_EVPN_PREFIX_IPADDR_V4(evp)) {
1991 afi = AFI_IP;
1992 safi = SAFI_UNICAST;
1993 rn = bgp_node_lookup(bgp_vrf->rib[afi][safi], pp);
1994 } else {
1995 afi = AFI_IP6;
1996 safi = SAFI_UNICAST;
1997 rn = bgp_node_lookup(bgp_vrf->rib[afi][safi], pp);
1998 }
1999
2000 if (!rn)
2001 return 0;
2002
2003 /* Find matching route entry. */
2004 for (ri = rn->info; ri; ri = ri->next)
2005 if (ri->extra
2006 && (struct bgp_info *)ri->extra->parent == parent_ri)
2007 break;
2008
2009 if (!ri)
2010 return 0;
2011
2012 /* Mark entry for deletion */
2013 bgp_info_delete(rn, ri);
2014
2015 /* Perform route selection and update zebra, if required. */
1eb88002 2016 bgp_process(bgp_vrf, rn, afi, safi);
d3135ba3 2017
2018 /* Unlock route node. */
2019 bgp_unlock_node(rn);
2020
2021 return ret;
2022}
2023
128ea8ab 2024/*
2025 * Uninstall route entry from the VNI routing table and send message
2026 * to zebra, if appropriate.
2027 */
d62a17ae 2028static int uninstall_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
2029 struct prefix_evpn *p,
2030 struct bgp_info *parent_ri)
128ea8ab 2031{
d62a17ae 2032 struct bgp_node *rn;
2033 struct bgp_info *ri;
2034 int ret;
128ea8ab 2035
d62a17ae 2036 /* Locate route within the VNI. */
2037 /* NOTE: There is no RD here. */
2038 rn = bgp_node_lookup(vpn->route_table, (struct prefix *)p);
2039 if (!rn)
2040 return 0;
128ea8ab 2041
d62a17ae 2042 /* Find matching route entry. */
2043 for (ri = rn->info; ri; ri = ri->next)
2044 if (ri->extra
2045 && (struct bgp_info *)ri->extra->parent == parent_ri)
2046 break;
128ea8ab 2047
d62a17ae 2048 if (!ri)
2049 return 0;
128ea8ab 2050
d62a17ae 2051 /* Mark entry for deletion */
2052 bgp_info_delete(rn, ri);
128ea8ab 2053
d62a17ae 2054 /* Perform route selection and update zebra, if required. */
2055 ret = evpn_route_select_install(bgp, vpn, rn);
128ea8ab 2056
d62a17ae 2057 /* Unlock route node. */
2058 bgp_unlock_node(rn);
128ea8ab 2059
d62a17ae 2060 return ret;
128ea8ab 2061}
2062
5ba238b7
MK
2063/*
2064 * Given a route entry and a VRF, see if this route entry should be
2065 * imported into the VRF i.e., RTs match.
2066 */
996c9314 2067static int is_route_matching_for_vrf(struct bgp *bgp_vrf, struct bgp_info *ri)
5ba238b7
MK
2068{
2069 struct attr *attr = ri->attr;
2070 struct ecommunity *ecom;
2071 int i;
2072
2073 assert(attr);
2074 /* Route should have valid RT to be even considered. */
2075 if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
2076 return 0;
2077
2078 ecom = attr->ecommunity;
2079 if (!ecom || !ecom->size)
2080 return 0;
2081
2082 /* For each extended community RT, see if it matches this VNI. If any RT
2083 * matches, we're done.
2084 */
2085 for (i = 0; i < ecom->size; i++) {
2086 u_char *pnt;
2087 u_char type, sub_type;
2088 struct ecommunity_val *eval;
2089 struct ecommunity_val eval_tmp;
2090 struct vrf_irt_node *irt;
2091
2092 /* Only deal with RTs */
2093 pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
2094 eval = (struct ecommunity_val *)(ecom->val
2095 + (i * ECOMMUNITY_SIZE));
2096 type = *pnt++;
2097 sub_type = *pnt++;
2098 if (sub_type != ECOMMUNITY_ROUTE_TARGET)
2099 continue;
2100
2101 /* See if this RT matches specified VNIs import RTs */
2102 irt = lookup_vrf_import_rt(eval);
2103 if (irt && irt->vrfs)
2104 if (is_vrf_present_in_irt_vrfs(irt->vrfs, bgp_vrf))
2105 return 1;
2106
2107 /* Also check for non-exact match. In this, we mask out the AS
2108 * and
2109 * only check on the local-admin sub-field. This is to
2110 * facilitate using
2111 * VNI as the RT for EBGP peering too.
2112 */
2113 irt = NULL;
2114 if (type == ECOMMUNITY_ENCODE_AS
2115 || type == ECOMMUNITY_ENCODE_AS4
2116 || type == ECOMMUNITY_ENCODE_IP) {
2117 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
2118 mask_ecom_global_admin(&eval_tmp, eval);
2119 irt = lookup_vrf_import_rt(&eval_tmp);
2120 }
2121 if (irt && irt->vrfs)
2122 if (is_vrf_present_in_irt_vrfs(irt->vrfs, bgp_vrf))
2123 return 1;
2124 }
2125
2126 return 0;
2127}
2128
128ea8ab 2129/*
2130 * Given a route entry and a VNI, see if this route entry should be
2131 * imported into the VNI i.e., RTs match.
2132 */
d62a17ae 2133static int is_route_matching_for_vni(struct bgp *bgp, struct bgpevpn *vpn,
2134 struct bgp_info *ri)
2135{
2136 struct attr *attr = ri->attr;
2137 struct ecommunity *ecom;
2138 int i;
2139
2140 assert(attr);
2141 /* Route should have valid RT to be even considered. */
2142 if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
2143 return 0;
2144
2145 ecom = attr->ecommunity;
2146 if (!ecom || !ecom->size)
2147 return 0;
2148
2149 /* For each extended community RT, see if it matches this VNI. If any RT
2150 * matches, we're done.
2151 */
2152 for (i = 0; i < ecom->size; i++) {
2153 u_char *pnt;
2154 u_char type, sub_type;
2155 struct ecommunity_val *eval;
2156 struct ecommunity_val eval_tmp;
2157 struct irt_node *irt;
2158
2159 /* Only deal with RTs */
2160 pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
2161 eval = (struct ecommunity_val *)(ecom->val
2162 + (i * ECOMMUNITY_SIZE));
2163 type = *pnt++;
2164 sub_type = *pnt++;
2165 if (sub_type != ECOMMUNITY_ROUTE_TARGET)
2166 continue;
2167
2168 /* See if this RT matches specified VNIs import RTs */
2169 irt = lookup_import_rt(bgp, eval);
2170 if (irt && irt->vnis)
2171 if (is_vni_present_in_irt_vnis(irt->vnis, vpn))
2172 return 1;
2173
2174 /* Also check for non-exact match. In this, we mask out the AS
2175 * and
2176 * only check on the local-admin sub-field. This is to
2177 * facilitate using
2178 * VNI as the RT for EBGP peering too.
2179 */
2180 irt = NULL;
2181 if (type == ECOMMUNITY_ENCODE_AS
2182 || type == ECOMMUNITY_ENCODE_AS4
2183 || type == ECOMMUNITY_ENCODE_IP) {
2184 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
2185 mask_ecom_global_admin(&eval_tmp, eval);
2186 irt = lookup_import_rt(bgp, &eval_tmp);
2187 }
2188 if (irt && irt->vnis)
2189 if (is_vni_present_in_irt_vnis(irt->vnis, vpn))
2190 return 1;
2191 }
2192
2193 return 0;
128ea8ab 2194}
2195
5ba238b7
MK
2196/*
2197 * Install or uninstall mac-ip routes are appropriate for this
2198 * particular VRF.
2199 */
996c9314 2200static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install)
5ba238b7
MK
2201{
2202 afi_t afi;
2203 safi_t safi;
2204 struct bgp_node *rd_rn, *rn;
2205 struct bgp_table *table;
2206 struct bgp_info *ri;
2207 int ret;
2208 char buf[PREFIX_STRLEN];
2209 struct bgp *bgp_def = NULL;
2210
2211 afi = AFI_L2VPN;
2212 safi = SAFI_EVPN;
2213 bgp_def = bgp_get_default();
2214 if (!bgp_def)
2215 return -1;
2216
2217 /* Walk entire global routing table and evaluate routes which could be
2218 * imported into this VRF. Note that we need to loop through all global
2219 * routes to determine which route matches the import rt on vrf
2220 */
2221 for (rd_rn = bgp_table_top(bgp_def->rib[afi][safi]); rd_rn;
2222 rd_rn = bgp_route_next(rd_rn)) {
2223 table = (struct bgp_table *)(rd_rn->info);
2224 if (!table)
2225 continue;
2226
2227 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
2228 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
2229
1eb88002 2230 /* if not mac-ip route skip this route */
996c9314
LB
2231 if (!(evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
2232 || evp->prefix.route_type
2233 == BGP_EVPN_IP_PREFIX_ROUTE))
5ba238b7
MK
2234 continue;
2235
1eb88002 2236 /* if not a mac+ip route skip this route */
996c9314
LB
2237 if (!(IS_EVPN_PREFIX_IPADDR_V4(evp)
2238 || IS_EVPN_PREFIX_IPADDR_V6(evp)))
1eb88002
MK
2239 continue;
2240
5ba238b7
MK
2241 for (ri = rn->info; ri; ri = ri->next) {
2242 /* Consider "valid" remote routes applicable for
523cafc4 2243 * this VRF.
2244 */
5ba238b7
MK
2245 if (!(CHECK_FLAG(ri->flags, BGP_INFO_VALID)
2246 && ri->type == ZEBRA_ROUTE_BGP
2247 && ri->sub_type == BGP_ROUTE_NORMAL))
2248 continue;
2249
2250 if (is_route_matching_for_vrf(bgp_vrf, ri)) {
2251 if (install)
996c9314 2252 ret = install_evpn_route_entry_in_vrf(
5ba238b7
MK
2253 bgp_vrf, evp, ri);
2254 else
996c9314 2255 ret = uninstall_evpn_route_entry_in_vrf(
5ba238b7
MK
2256 bgp_vrf, evp, ri);
2257
2258 if (ret) {
2259 zlog_err(
2260 "Failed to %s EVPN %s route in VRF %s",
2261 install ? "install"
2262 : "uninstall",
2263 prefix2str(evp, buf,
2264 sizeof(buf)),
996c9314
LB
2265 vrf_id_to_name(
2266 bgp_vrf->vrf_id));
5ba238b7
MK
2267 return ret;
2268 }
2269 }
2270 }
2271 }
2272 }
2273
2274 return 0;
2275}
2276
128ea8ab 2277/*
2278 * Install or uninstall routes of specified type that are appropriate for this
2279 * particular VNI.
2280 */
d62a17ae 2281static int install_uninstall_routes_for_vni(struct bgp *bgp,
2282 struct bgpevpn *vpn,
2283 bgp_evpn_route_type rtype,
2284 int install)
2285{
0291c246
MK
2286 afi_t afi;
2287 safi_t safi;
2288 struct bgp_node *rd_rn, *rn;
2289 struct bgp_table *table;
2290 struct bgp_info *ri;
2291 int ret;
d62a17ae 2292
2293 afi = AFI_L2VPN;
2294 safi = SAFI_EVPN;
2295
2296 /* Walk entire global routing table and evaluate routes which could be
2297 * imported into this VPN. Note that we cannot just look at the routes
2298 * for
2299 * the VNI's RD - remote routes applicable for this VNI could have any
2300 * RD.
2301 */
2302 /* EVPN routes are a 2-level table. */
2303 for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
2304 rd_rn = bgp_route_next(rd_rn)) {
2305 table = (struct bgp_table *)(rd_rn->info);
2306 if (!table)
2307 continue;
2308
2309 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
2310 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
2311
2312 if (evp->prefix.route_type != rtype)
2313 continue;
2314
2315 for (ri = rn->info; ri; ri = ri->next) {
2316 /* Consider "valid" remote routes applicable for
2317 * this VNI. */
2318 if (!(CHECK_FLAG(ri->flags, BGP_INFO_VALID)
2319 && ri->type == ZEBRA_ROUTE_BGP
2320 && ri->sub_type == BGP_ROUTE_NORMAL))
2321 continue;
2322
2323 if (is_route_matching_for_vni(bgp, vpn, ri)) {
2324 if (install)
2325 ret = install_evpn_route_entry(
60466a63 2326 bgp, vpn, evp, ri);
d62a17ae 2327 else
2328 ret = uninstall_evpn_route_entry(
2329 bgp, vpn, evp, ri);
2330
2331 if (ret) {
2332 zlog_err(
2333 "%u: Failed to %s EVPN %s route in VNI %u",
2334 bgp->vrf_id,
2335 install ? "install"
2336 : "uninstall",
2337 rtype == BGP_EVPN_MAC_IP_ROUTE
2338 ? "MACIP"
2339 : "IMET",
2340 vpn->vni);
2341 return ret;
2342 }
2343 }
2344 }
2345 }
2346 }
2347
2348 return 0;
128ea8ab 2349}
2350
5ba238b7 2351/* Install any existing remote routes applicable for this VRF into VRF RIB. This
523cafc4 2352 * is invoked upon l3vni-add or l3vni import rt change
2353 */
5ba238b7
MK
2354static int install_routes_for_vrf(struct bgp *bgp_vrf)
2355{
2356 install_uninstall_routes_for_vrf(bgp_vrf, 1);
2357 return 0;
2358}
2359
128ea8ab 2360/*
2361 * Install any existing remote routes applicable for this VNI into its
2362 * routing table. This is invoked when a VNI becomes "live" or its Import
2363 * RT is changed.
2364 */
d62a17ae 2365static int install_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 2366{
d62a17ae 2367 int ret;
128ea8ab 2368
d62a17ae 2369 /* Install type-3 routes followed by type-2 routes - the ones applicable
2370 * for this VNI.
2371 */
2372 ret = install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_IMET_ROUTE,
2373 1);
2374 if (ret)
2375 return ret;
128ea8ab 2376
d62a17ae 2377 return install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_MAC_IP_ROUTE,
2378 1);
128ea8ab 2379}
2380
5ba238b7
MK
2381/* uninstall routes from l3vni vrf. */
2382static int uninstall_routes_for_vrf(struct bgp *bgp_vrf)
2383{
2384 install_uninstall_routes_for_vrf(bgp_vrf, 0);
2385 return 0;
2386}
2387
90e60aa7 2388/*
2389 * Uninstall any existing remote routes for this VNI. One scenario in which
2390 * this is invoked is upon an import RT change.
2391 */
d62a17ae 2392static int uninstall_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 2393{
d62a17ae 2394 int ret;
90e60aa7 2395
d62a17ae 2396 /* Uninstall type-2 routes followed by type-3 routes - the ones
2397 * applicable
2398 * for this VNI.
2399 */
2400 ret = install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_MAC_IP_ROUTE,
2401 0);
2402 if (ret)
2403 return ret;
90e60aa7 2404
d62a17ae 2405 return install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_IMET_ROUTE,
2406 0);
90e60aa7 2407}
2408
d3135ba3 2409/*
2410 * Install or uninstall route in matching VRFs (list).
2411 */
2412static int install_uninstall_route_in_vrfs(struct bgp *bgp_def, afi_t afi,
2413 safi_t safi, struct prefix_evpn *evp,
2414 struct bgp_info *ri,
2415 struct list *vrfs, int install)
2416{
2417 char buf[PREFIX2STR_BUFFER];
2418 struct bgp *bgp_vrf;
2419 struct listnode *node, *nnode;
2420
90264d64 2421 /* Only type-2/type-5 routes go into a VRF */
996c9314
LB
2422 if (!(evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
2423 || evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE))
d3135ba3 2424 return 0;
2425
90264d64 2426 /* if it is type-2 route and not a mac+ip route skip this route */
996c9314
LB
2427 if ((evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
2428 && !(IS_EVPN_PREFIX_IPADDR_V4(evp)
2429 || IS_EVPN_PREFIX_IPADDR_V6(evp)))
30a30f57
MK
2430 return 0;
2431
d3135ba3 2432 for (ALL_LIST_ELEMENTS(vrfs, node, nnode, bgp_vrf)) {
2433 int ret;
2434
2435 if (install)
996c9314 2436 ret = install_evpn_route_entry_in_vrf(bgp_vrf, evp, ri);
d3135ba3 2437 else
996c9314
LB
2438 ret = uninstall_evpn_route_entry_in_vrf(bgp_vrf, evp,
2439 ri);
d3135ba3 2440
2441 if (ret) {
2442 zlog_err("%u: Failed to %s prefix %s in VRF %s",
2443 bgp_def->vrf_id,
2444 install ? "install" : "uninstall",
2445 prefix2str(evp, buf, sizeof(buf)),
2446 vrf_id_to_name(bgp_vrf->vrf_id));
2447 return ret;
2448 }
2449 }
2450
2451 return 0;
2452}
2453
128ea8ab 2454/*
2455 * Install or uninstall route in matching VNIs (list).
2456 */
d62a17ae 2457static int install_uninstall_route_in_vnis(struct bgp *bgp, afi_t afi,
2458 safi_t safi, struct prefix_evpn *evp,
2459 struct bgp_info *ri,
2460 struct list *vnis, int install)
128ea8ab 2461{
d62a17ae 2462 struct bgpevpn *vpn;
2463 struct listnode *node, *nnode;
128ea8ab 2464
d62a17ae 2465 for (ALL_LIST_ELEMENTS(vnis, node, nnode, vpn)) {
2466 int ret;
128ea8ab 2467
d62a17ae 2468 if (!is_vni_live(vpn))
2469 continue;
128ea8ab 2470
d62a17ae 2471 if (install)
2472 ret = install_evpn_route_entry(bgp, vpn, evp, ri);
2473 else
2474 ret = uninstall_evpn_route_entry(bgp, vpn, evp, ri);
128ea8ab 2475
d62a17ae 2476 if (ret) {
2477 zlog_err("%u: Failed to %s EVPN %s route in VNI %u",
2478 bgp->vrf_id, install ? "install" : "uninstall",
2479 evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
2480 ? "MACIP"
2481 : "IMET",
2482 vpn->vni);
2483 return ret;
2484 }
2485 }
128ea8ab 2486
d62a17ae 2487 return 0;
128ea8ab 2488}
2489
2490/*
2491 * Install or uninstall route for appropriate VNIs.
2492 */
d62a17ae 2493static int install_uninstall_evpn_route(struct bgp *bgp, afi_t afi, safi_t safi,
2494 struct prefix *p, struct bgp_info *ri,
2495 int import)
2496{
2497 struct prefix_evpn *evp = (struct prefix_evpn *)p;
2498 struct attr *attr = ri->attr;
2499 struct ecommunity *ecom;
2500 int i;
2501
2502 assert(attr);
2503
90264d64 2504 /* Only type-2 and type-3 and type-5 are supported currently */
d62a17ae 2505 if (!(evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
90264d64
MK
2506 || evp->prefix.route_type == BGP_EVPN_IMET_ROUTE
2507 || evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE))
d62a17ae 2508 return 0;
2509
2510 /* If we don't have Route Target, nothing much to do. */
2511 if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
2512 return 0;
2513
2514 ecom = attr->ecommunity;
2515 if (!ecom || !ecom->size)
2516 return -1;
2517
90264d64
MK
2518 /* For each extended community RT, see which VNIs/VRFs match and import
2519 * the route into matching VNIs/VRFs.
d62a17ae 2520 */
2521 for (i = 0; i < ecom->size; i++) {
2522 u_char *pnt;
2523 u_char type, sub_type;
2524 struct ecommunity_val *eval;
2525 struct ecommunity_val eval_tmp;
996c9314 2526 struct irt_node *irt; /* import rt for l2vni */
d3135ba3 2527 struct vrf_irt_node *vrf_irt; /* import rt for l3vni */
d62a17ae 2528
2529 /* Only deal with RTs */
2530 pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
2531 eval = (struct ecommunity_val *)(ecom->val
2532 + (i * ECOMMUNITY_SIZE));
2533 type = *pnt++;
2534 sub_type = *pnt++;
2535 if (sub_type != ECOMMUNITY_ROUTE_TARGET)
2536 continue;
2537
90264d64 2538 /* Import route into matching l2-vnis (type-2/type-3 routes go
523cafc4 2539 * into l2vni table)
2540 */
d62a17ae 2541 irt = lookup_import_rt(bgp, eval);
2542 if (irt && irt->vnis)
2543 install_uninstall_route_in_vnis(bgp, afi, safi, evp, ri,
2544 irt->vnis, import);
2545
90264d64 2546 /* Import route into matching l3-vnis (type-2/type-5 routes go
523cafc4 2547 * into l3vni/vrf table)
2548 */
d3135ba3 2549 vrf_irt = lookup_vrf_import_rt(eval);
2550 if (vrf_irt && vrf_irt->vrfs)
2551 install_uninstall_route_in_vrfs(bgp, afi, safi, evp, ri,
2552 vrf_irt->vrfs, import);
2553
90264d64
MK
2554 /* Also check for non-exact match. In this,
2555 * we mask out the AS and
2556 * only check on the local-admin sub-field.
2557 * This is to facilitate using
d62a17ae 2558 * VNI as the RT for EBGP peering too.
2559 */
2560 irt = NULL;
d3135ba3 2561 vrf_irt = NULL;
d62a17ae 2562 if (type == ECOMMUNITY_ENCODE_AS
2563 || type == ECOMMUNITY_ENCODE_AS4
2564 || type == ECOMMUNITY_ENCODE_IP) {
2565 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
2566 mask_ecom_global_admin(&eval_tmp, eval);
2567 irt = lookup_import_rt(bgp, &eval_tmp);
d3135ba3 2568 vrf_irt = lookup_vrf_import_rt(&eval_tmp);
d62a17ae 2569 }
2570 if (irt && irt->vnis)
2571 install_uninstall_route_in_vnis(bgp, afi, safi, evp, ri,
2572 irt->vnis, import);
d3135ba3 2573 if (vrf_irt && vrf_irt->vrfs)
996c9314
LB
2574 install_uninstall_route_in_vrfs(bgp, afi, safi, evp, ri,
2575 vrf_irt->vrfs, import);
d62a17ae 2576 }
2577
2578 return 0;
128ea8ab 2579}
2580
80b140af
MK
2581/* delete and withdraw all ipv4 and ipv6 routes in the vrf table as type-5
2582 * routes */
2583static void delete_withdraw_vrf_routes(struct bgp *bgp_vrf)
2584{
2585 /* delete all ipv4 routes and withdraw from peers */
fdf19f06
MK
2586 if (advertise_type5_routes(bgp_vrf, AFI_IP))
2587 bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
80b140af
MK
2588
2589 /* delete all ipv6 routes and withdraw from peers */
fdf19f06
MK
2590 if (advertise_type5_routes(bgp_vrf, AFI_IP6))
2591 bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
80b140af
MK
2592}
2593
2594/* update and advertise all ipv4 and ipv6 routes in thr vrf table as type-5
2595 * routes */
2596static void update_advertise_vrf_routes(struct bgp *bgp_vrf)
2597{
2598 /* update all ipv4 routes */
fdf19f06
MK
2599 if (advertise_type5_routes(bgp_vrf, AFI_IP))
2600 bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
80b140af
MK
2601
2602 /* update all ipv6 routes */
fdf19f06
MK
2603 if (advertise_type5_routes(bgp_vrf, AFI_IP6))
2604 bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
80b140af
MK
2605}
2606
676f83b9 2607/*
2608 * update and advertise local routes for a VRF as type-5 routes.
2609 * This is invoked upon RD change for a VRF. Note taht the processing is only
2610 * done in the global route table using the routes which already exist in the
2611 * VRF routing table
2612 */
80b140af 2613static void update_router_id_vrf(struct bgp *bgp_vrf)
676f83b9 2614{
80b140af
MK
2615 /* skip if the RD is configured */
2616 if (is_vrf_rd_configured(bgp_vrf))
2617 return;
2618
2619 /* derive the RD for the VRF based on new router-id */
2620 bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf);
2621
2622 /* update advertise ipv4|ipv6 routes as type-5 routes */
2623 update_advertise_vrf_routes(bgp_vrf);
676f83b9 2624}
2625
2626/*
2627 * Delete and withdraw all type-5 routes for the RD corresponding to VRF.
2628 * This is invoked upon VRF RD change. The processing is done only from global
2629 * table.
2630 */
80b140af 2631static void withdraw_router_id_vrf(struct bgp *bgp_vrf)
676f83b9 2632{
80b140af
MK
2633 /* skip if the RD is configured */
2634 if (is_vrf_rd_configured(bgp_vrf))
2635 return;
2636
2637 /* delete/withdraw ipv4|ipv6 routes as type-5 routes */
2638 delete_withdraw_vrf_routes(bgp_vrf);
676f83b9 2639}
2640
90e60aa7 2641/*
2642 * Update and advertise local routes for a VNI. Invoked upon router-id
2643 * change. Note that the processing is done only on the global route table
2644 * using routes that already exist in the per-VNI table.
2645 */
d62a17ae 2646static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
2647{
2648 struct prefix_evpn p;
2649 struct bgp_node *rn, *global_rn;
2650 struct bgp_info *ri, *global_ri;
2651 struct attr *attr;
2652 afi_t afi = AFI_L2VPN;
2653 safi_t safi = SAFI_EVPN;
2654
2655 /* Locate type-3 route for VNI in the per-VNI table and use its
2656 * attributes to create and advertise the type-3 route for this VNI
2657 * in the global table.
2658 */
2659 build_evpn_type3_prefix(&p, vpn->originator_ip);
2660 rn = bgp_node_lookup(vpn->route_table, (struct prefix *)&p);
2661 if (!rn) /* unexpected */
2662 return 0;
2663 for (ri = rn->info; ri; ri = ri->next)
2664 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
2665 && ri->sub_type == BGP_ROUTE_STATIC)
2666 break;
2667 if (!ri) /* unexpected */
2668 return 0;
2669 attr = ri->attr;
2670
2671 global_rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
2672 (struct prefix *)&p, &vpn->prd);
1a98c087
MK
2673 update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1, 0, &ri,
2674 0);
d62a17ae 2675
2676 /* Schedule for processing and unlock node. */
2677 bgp_process(bgp, global_rn, afi, safi);
2678 bgp_unlock_node(global_rn);
2679
2680 /* Now, walk this VNI's route table and use the route and its attribute
2681 * to create and schedule route in global table.
2682 */
2683 for (rn = bgp_table_top(vpn->route_table); rn;
2684 rn = bgp_route_next(rn)) {
2685 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
2686
2687 /* Identify MAC-IP local routes. */
2688 if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
2689 continue;
2690
2691 for (ri = rn->info; ri; ri = ri->next)
2692 if (ri->peer == bgp->peer_self
2693 && ri->type == ZEBRA_ROUTE_BGP
2694 && ri->sub_type == BGP_ROUTE_STATIC)
2695 break;
2696 if (!ri)
2697 continue;
2698
2699 /* Create route in global routing table using this route entry's
2700 * attribute.
2701 */
2702 attr = ri->attr;
2703 global_rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
2704 (struct prefix *)evp, &vpn->prd);
2705 assert(global_rn);
2706 update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1,
1a98c087 2707 0, &global_ri, 0);
d62a17ae 2708
2709 /* Schedule for processing and unlock node. */
2710 bgp_process(bgp, global_rn, afi, safi);
2711 bgp_unlock_node(global_rn);
2712 }
2713
2714 return 0;
90e60aa7 2715}
2716
2717/*
2718 * Delete (and withdraw) local routes for a VNI - only from the global
2719 * table. Invoked upon router-id change.
2720 */
d62a17ae 2721static int delete_withdraw_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 2722{
d62a17ae 2723 int ret;
2724 struct prefix_evpn p;
2725 struct bgp_node *global_rn;
2726 struct bgp_info *ri;
2727 afi_t afi = AFI_L2VPN;
2728 safi_t safi = SAFI_EVPN;
90e60aa7 2729
d62a17ae 2730 /* Delete and withdraw locally learnt type-2 routes (MACIP)
2731 * for this VNI - from the global table.
2732 */
2733 ret = delete_global_type2_routes(bgp, vpn);
2734 if (ret)
2735 return ret;
90e60aa7 2736
d62a17ae 2737 /* Remove type-3 route for this VNI from global table. */
2738 build_evpn_type3_prefix(&p, vpn->originator_ip);
2739 global_rn = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi,
2740 (struct prefix *)&p, &vpn->prd);
2741 if (global_rn) {
2742 /* Delete route entry in the global EVPN table. */
2743 delete_evpn_route_entry(bgp, vpn, afi, safi, global_rn, &ri);
90e60aa7 2744
d62a17ae 2745 /* Schedule for processing - withdraws to peers happen from
2746 * this table.
2747 */
2748 if (ri)
2749 bgp_process(bgp, global_rn, afi, safi);
2750 bgp_unlock_node(global_rn);
2751 }
90e60aa7 2752
d62a17ae 2753 return 0;
90e60aa7 2754}
2755
2d48ee25 2756/*
2757 * Handle router-id change. Update and advertise local routes corresponding
2758 * to this VNI from peers. Note that this is invoked after updating the
2759 * router-id. The routes in the per-VNI table are used to create routes in
2760 * the global table and schedule them.
2761 */
d62a17ae 2762static void update_router_id_vni(struct hash_backet *backet, struct bgp *bgp)
2d48ee25 2763{
d62a17ae 2764 struct bgpevpn *vpn;
2d48ee25 2765
d62a17ae 2766 vpn = (struct bgpevpn *)backet->data;
2d48ee25 2767
d62a17ae 2768 if (!vpn) {
2769 zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__);
2770 return;
2771 }
2d48ee25 2772
d62a17ae 2773 /* Skip VNIs with configured RD. */
2774 if (is_rd_configured(vpn))
2775 return;
2d48ee25 2776
d62a17ae 2777 bgp_evpn_derive_auto_rd(bgp, vpn);
2778 update_advertise_vni_routes(bgp, vpn);
2d48ee25 2779}
2780
2781/*
2782 * Handle router-id change. Delete and withdraw local routes corresponding
2783 * to this VNI from peers. Note that this is invoked prior to updating
2784 * the router-id and is done only on the global route table, the routes
2785 * are needed in the per-VNI table to re-advertise with new router id.
2786 */
d62a17ae 2787static void withdraw_router_id_vni(struct hash_backet *backet, struct bgp *bgp)
2d48ee25 2788{
d62a17ae 2789 struct bgpevpn *vpn;
2d48ee25 2790
d62a17ae 2791 vpn = (struct bgpevpn *)backet->data;
2d48ee25 2792
d62a17ae 2793 if (!vpn) {
2794 zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__);
2795 return;
2796 }
2d48ee25 2797
d62a17ae 2798 /* Skip VNIs with configured RD. */
2799 if (is_rd_configured(vpn))
2800 return;
2d48ee25 2801
d62a17ae 2802 delete_withdraw_vni_routes(bgp, vpn);
2d48ee25 2803}
2804
128ea8ab 2805/*
2806 * Process received EVPN type-2 route (advertise or withdraw).
2807 */
d62a17ae 2808static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
2809 struct attr *attr, u_char *pfx, int psize,
2810 u_int32_t addpath_id)
2811{
2812 struct prefix_rd prd;
2813 struct prefix_evpn p;
2814 u_char ipaddr_len;
2815 u_char macaddr_len;
b57ba6d2
MK
2816 mpls_label_t label[BGP_MAX_LABELS]; /* holds the VNI(s) as in packet */
2817 u_int32_t num_labels = 0;
d62a17ae 2818 int ret;
2819
2820 /* Type-2 route should be either 33, 37 or 49 bytes or an
2821 * additional 3 bytes if there is a second label (VNI):
2822 * RD (8), ESI (10), Eth Tag (4), MAC Addr Len (1),
2823 * MAC Addr (6), IP len (1), IP (0, 4 or 16),
2824 * MPLS Lbl1 (3), MPLS Lbl2 (0 or 3)
2825 */
2826 if (psize != 33 && psize != 37 && psize != 49 && psize != 36
2827 && psize != 40 && psize != 52) {
2828 zlog_err("%u:%s - Rx EVPN Type-2 NLRI with invalid length %d",
2829 peer->bgp->vrf_id, peer->host, psize);
2830 return -1;
2831 }
2832
2833 /* Make prefix_rd */
2834 prd.family = AF_UNSPEC;
2835 prd.prefixlen = 64;
2836 memcpy(&prd.val, pfx, 8);
2837 pfx += 8;
2838
2839 /* Make EVPN prefix. */
2840 memset(&p, 0, sizeof(struct prefix_evpn));
b03b8898 2841 p.family = AF_EVPN;
d62a17ae 2842 p.prefixlen = EVPN_TYPE_2_ROUTE_PREFIXLEN;
2843 p.prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
2844
2845 /* Skip over Ethernet Seg Identifier for now. */
2846 pfx += 10;
2847
2848 /* Skip over Ethernet Tag for now. */
2849 pfx += 4;
2850
2851 /* Get the MAC Addr len */
2852 macaddr_len = *pfx++;
2853
2854 /* Get the MAC Addr */
28328ea9
DS
2855 if (macaddr_len == (ETH_ALEN * 8)) {
2856 memcpy(&p.prefix.mac.octet, pfx, ETH_ALEN);
2857 pfx += ETH_ALEN;
d62a17ae 2858 } else {
2859 zlog_err(
2860 "%u:%s - Rx EVPN Type-2 NLRI with unsupported MAC address length %d",
2861 peer->bgp->vrf_id, peer->host, macaddr_len);
2862 return -1;
2863 }
2864
2865
2866 /* Get the IP. */
2867 ipaddr_len = *pfx++;
2868 if (ipaddr_len != 0 && ipaddr_len != IPV4_MAX_BITLEN
2869 && ipaddr_len != IPV6_MAX_BITLEN) {
2870 zlog_err(
2871 "%u:%s - Rx EVPN Type-2 NLRI with unsupported IP address length %d",
2872 peer->bgp->vrf_id, peer->host, ipaddr_len);
2873 return -1;
2874 }
2875
2876 if (ipaddr_len) {
2877 ipaddr_len /= 8; /* Convert to bytes. */
2878 p.prefix.ip.ipa_type = (ipaddr_len == IPV4_MAX_BYTELEN)
2879 ? IPADDR_V4
2880 : IPADDR_V6;
2881 memcpy(&p.prefix.ip.ip.addr, pfx, ipaddr_len);
2882 }
2883 pfx += ipaddr_len;
2884
b57ba6d2
MK
2885 /* Get the VNI(s). Stored as bytes here. */
2886 num_labels++;
2887 memset(label, 0, sizeof(label));
2888 memcpy(&label[0], pfx, BGP_LABEL_BYTES);
1b817c78 2889 pfx += BGP_LABEL_BYTES;
b57ba6d2
MK
2890 psize -= (33 + ipaddr_len);
2891 /* Do we have a second VNI? */
2892 if (psize) {
2893 num_labels++;
2894 memcpy(&label[1], pfx, BGP_LABEL_BYTES);
6b11bd8d 2895 /*
2896 * If in future, we are required to access additional fields,
996c9314
LB
2897 * we MUST increment pfx by BGP_LABEL_BYTES in before reading
2898 * the next field
6b11bd8d 2899 */
b57ba6d2 2900 }
d62a17ae 2901
2902 /* Process the route. */
2903 if (attr)
2904 ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
2905 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
b57ba6d2 2906 &prd, &label[0], num_labels, 0, NULL);
d62a17ae 2907 else
2908 ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
2909 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
b57ba6d2 2910 &prd, &label[0], num_labels, NULL);
d62a17ae 2911 return ret;
128ea8ab 2912}
2913
2914/*
2915 * Process received EVPN type-3 route (advertise or withdraw).
2916 */
d62a17ae 2917static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,
2918 struct attr *attr, u_char *pfx, int psize,
2919 u_int32_t addpath_id)
2920{
2921 struct prefix_rd prd;
2922 struct prefix_evpn p;
2923 u_char ipaddr_len;
2924 int ret;
2925
2926 /* Type-3 route should be either 17 or 29 bytes: RD (8), Eth Tag (4),
2927 * IP len (1) and IP (4 or 16).
2928 */
2929 if (psize != 17 && psize != 29) {
2930 zlog_err("%u:%s - Rx EVPN Type-3 NLRI with invalid length %d",
2931 peer->bgp->vrf_id, peer->host, psize);
2932 return -1;
2933 }
2934
7fd077aa 2935 /* If PMSI is present, log if it is anything other than IR.
2936 * Note: We just simply ignore the values as it is not clear if
2937 * doing anything else is better.
2938 */
2939 if (attr &&
2940 (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) {
2941 if (attr->pmsi_tnl_type != PMSI_TNLTYPE_INGR_REPL) {
d0be47e8 2942 zlog_warn("%u:%s - Rx EVPN Type-3 NLRI with unsupported PTA %d",
7fd077aa 2943 peer->bgp->vrf_id, peer->host,
2944 attr->pmsi_tnl_type);
2945 }
2946 }
2947
d62a17ae 2948 /* Make prefix_rd */
2949 prd.family = AF_UNSPEC;
2950 prd.prefixlen = 64;
2951 memcpy(&prd.val, pfx, 8);
2952 pfx += 8;
2953
2954 /* Make EVPN prefix. */
2955 memset(&p, 0, sizeof(struct prefix_evpn));
b03b8898 2956 p.family = AF_EVPN;
d62a17ae 2957 p.prefixlen = EVPN_TYPE_3_ROUTE_PREFIXLEN;
2958 p.prefix.route_type = BGP_EVPN_IMET_ROUTE;
2959
2960 /* Skip over Ethernet Tag for now. */
2961 pfx += 4;
2962
2963 /* Get the IP. */
2964 ipaddr_len = *pfx++;
2965 if (ipaddr_len == IPV4_MAX_BITLEN) {
2966 p.prefix.ip.ipa_type = IPADDR_V4;
2967 memcpy(&p.prefix.ip.ip.addr, pfx, IPV4_MAX_BYTELEN);
2968 } else {
2969 zlog_err(
2970 "%u:%s - Rx EVPN Type-3 NLRI with unsupported IP address length %d",
2971 peer->bgp->vrf_id, peer->host, ipaddr_len);
2972 return -1;
2973 }
2974
2975 /* Process the route. */
2976 if (attr)
2977 ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
2978 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
b57ba6d2 2979 &prd, NULL, 0, 0, NULL);
d62a17ae 2980 else
2981 ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
2982 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
b57ba6d2 2983 &prd, NULL, 0, NULL);
d62a17ae 2984 return ret;
128ea8ab 2985}
2986
2987/*
2988 * Process received EVPN type-5 route (advertise or withdraw).
2989 */
d62a17ae 2990static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
2991 struct attr *attr, u_char *pfx, int psize,
2992 u_int32_t addpath_id, int withdraw)
2993{
2994 struct prefix_rd prd;
2995 struct prefix_evpn p;
2996 struct bgp_route_evpn evpn;
2997 u_char ippfx_len;
2998 u_int32_t eth_tag;
b57ba6d2 2999 mpls_label_t label; /* holds the VNI as in the packet */
d62a17ae 3000 int ret;
3001
3002 /* Type-5 route should be 34 or 58 bytes:
3003 * RD (8), ESI (10), Eth Tag (4), IP len (1), IP (4 or 16),
3004 * GW (4 or 16) and VNI (3).
3005 * Note that the IP and GW should both be IPv4 or both IPv6.
3006 */
3007 if (psize != 34 && psize != 58) {
3008 zlog_err("%u:%s - Rx EVPN Type-5 NLRI with invalid length %d",
3009 peer->bgp->vrf_id, peer->host, psize);
3010 return -1;
3011 }
3012
3013 /* Make prefix_rd */
3014 prd.family = AF_UNSPEC;
3015 prd.prefixlen = 64;
3016 memcpy(&prd.val, pfx, 8);
3017 pfx += 8;
3018
3019 /* Make EVPN prefix. */
3020 memset(&p, 0, sizeof(struct prefix_evpn));
b03b8898 3021 p.family = AF_EVPN;
e9fc2840 3022 p.prefixlen = EVPN_TYPE_5_ROUTE_PREFIXLEN;
d62a17ae 3023 p.prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE;
3024
3025 /* Additional information outside of prefix - ESI and GW IP */
3026 memset(&evpn, 0, sizeof(evpn));
3027
3028 /* Fetch ESI */
3029 memcpy(&evpn.eth_s_id.val, pfx, 10);
3030 pfx += 10;
3031
3032 /* Fetch Ethernet Tag. */
3033 memcpy(&eth_tag, pfx, 4);
3034 p.prefix.eth_tag = ntohl(eth_tag);
3035 pfx += 4;
3036
3037 /* Fetch IP prefix length. */
3038 ippfx_len = *pfx++;
3039 if (ippfx_len > IPV6_MAX_BITLEN) {
3040 zlog_err(
3041 "%u:%s - Rx EVPN Type-5 NLRI with invalid IP Prefix length %d",
3042 peer->bgp->vrf_id, peer->host, ippfx_len);
3043 return -1;
3044 }
3045 p.prefix.ip_prefix_length = ippfx_len;
3046
3047 /* Determine IPv4 or IPv6 prefix */
3048 /* Since the address and GW are from the same family, this just becomes
3049 * a simple check on the total size.
3050 */
3051 if (psize == 34) {
3052 SET_IPADDR_V4(&p.prefix.ip);
3053 memcpy(&p.prefix.ip.ipaddr_v4, pfx, 4);
3054 pfx += 4;
3055 memcpy(&evpn.gw_ip.ipv4, pfx, 4);
3056 pfx += 4;
d62a17ae 3057 } else {
3058 SET_IPADDR_V6(&p.prefix.ip);
3059 memcpy(&p.prefix.ip.ipaddr_v6, pfx, 16);
3060 pfx += 16;
3061 memcpy(&evpn.gw_ip.ipv6, pfx, 16);
3062 pfx += 16;
d62a17ae 3063 }
3064
b57ba6d2
MK
3065 /* Get the VNI (in MPLS label field). Stored as bytes here. */
3066 memset(&label, 0, sizeof(label));
3067 memcpy(&label, pfx, BGP_LABEL_BYTES);
6b11bd8d 3068
3069 /*
3070 * If in future, we are required to access additional fields,
996c9314
LB
3071 * we MUST increment pfx by BGP_LABEL_BYTES in before reading the next
3072 * field
6b11bd8d 3073 */
d62a17ae 3074
3075 /* Process the route. */
3076 if (!withdraw)
3077 ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
3078 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
b57ba6d2 3079 &prd, &label, 1, 0, &evpn);
d62a17ae 3080 else
3081 ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
3082 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
b57ba6d2 3083 &prd, &label, 1, &evpn);
d62a17ae 3084
3085 return ret;
3086}
3087
3088static void evpn_mpattr_encode_type5(struct stream *s, struct prefix *p,
996c9314
LB
3089 struct prefix_rd *prd, mpls_label_t *label,
3090 u_int32_t num_labels, struct attr *attr)
d62a17ae 3091{
3092 int len;
3093 char temp[16];
3094 struct evpn_addr *p_evpn_p;
3095
3096 memset(&temp, 0, 16);
b03b8898 3097 if (p->family != AF_EVPN)
d62a17ae 3098 return;
3099 p_evpn_p = &(p->u.prefix_evpn);
3100
e9fc2840 3101 /* len denites the total len of IP and GW-IP in the route
523cafc4 3102 IP and GW-IP have to be both ipv4 or ipv6
3103 */
d62a17ae 3104 if (IS_IPADDR_V4(&p_evpn_p->ip))
e9fc2840 3105 len = 8; /* IP and GWIP are both ipv4 */
d62a17ae 3106 else
e9fc2840 3107 len = 32; /* IP and GWIP are both ipv6 */
d62a17ae 3108 /* Prefix contains RD, ESI, EthTag, IP length, IP, GWIP and VNI */
3109 stream_putc(s, 8 + 10 + 4 + 1 + len + 3);
3110 stream_put(s, prd->val, 8);
0af35d90 3111 if (attr)
d62a17ae 3112 stream_put(s, &(attr->evpn_overlay.eth_s_id), 10);
3113 else
3114 stream_put(s, &temp, 10);
3115 stream_putl(s, p_evpn_p->eth_tag);
3116 stream_putc(s, p_evpn_p->ip_prefix_length);
3117 if (IS_IPADDR_V4(&p_evpn_p->ip))
3118 stream_put_ipv4(s, p_evpn_p->ip.ipaddr_v4.s_addr);
3119 else
3120 stream_put(s, &p_evpn_p->ip.ipaddr_v6, 16);
0af35d90 3121 if (attr) {
d62a17ae 3122 if (IS_IPADDR_V4(&p_evpn_p->ip))
3123 stream_put_ipv4(s,
3124 attr->evpn_overlay.gw_ip.ipv4.s_addr);
3125 else
3126 stream_put(s, &(attr->evpn_overlay.gw_ip.ipv6), 16);
3127 } else {
3128 if (IS_IPADDR_V4(&p_evpn_p->ip))
3129 stream_put_ipv4(s, 0);
3130 else
3131 stream_put(s, &temp, 16);
3132 }
3133
b57ba6d2 3134 if (num_labels)
d62a17ae 3135 stream_put(s, label, 3);
3136 else
3137 stream_put3(s, 0);
128ea8ab 3138}
3139
3140/*
3141 * Cleanup specific VNI upon EVPN (advertise-all-vni) being disabled.
3142 */
d62a17ae 3143static void cleanup_vni_on_disable(struct hash_backet *backet, struct bgp *bgp)
128ea8ab 3144{
d62a17ae 3145 struct bgpevpn *vpn = (struct bgpevpn *)backet->data;
128ea8ab 3146
d62a17ae 3147 /* Remove EVPN routes and schedule for processing. */
3148 delete_routes_for_vni(bgp, vpn);
128ea8ab 3149
d62a17ae 3150 /* Clear "live" flag and see if hash needs to be freed. */
3151 UNSET_FLAG(vpn->flags, VNI_FLAG_LIVE);
3152 if (!is_vni_configured(vpn))
3153 bgp_evpn_free(bgp, vpn);
128ea8ab 3154}
3155
3156/*
3157 * Free a VNI entry; iterator function called during cleanup.
3158 */
d62a17ae 3159static void free_vni_entry(struct hash_backet *backet, struct bgp *bgp)
128ea8ab 3160{
d62a17ae 3161 struct bgpevpn *vpn;
128ea8ab 3162
d62a17ae 3163 vpn = (struct bgpevpn *)backet->data;
3164 delete_all_vni_routes(bgp, vpn);
3165 bgp_evpn_free(bgp, vpn);
128ea8ab 3166}
3167
c581d8b0
MK
3168/*
3169 * Derive AUTO import RT for BGP VRF - L3VNI
3170 */
3171static void evpn_auto_rt_import_add_for_vrf(struct bgp *bgp_vrf)
3172{
10ebe1ab
MK
3173 struct bgp *bgp_def = NULL;
3174
c581d8b0 3175 form_auto_rt(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_import_rtl);
10ebe1ab
MK
3176 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD);
3177
3178 /* Map RT to VRF */
3179 bgp_def = bgp_get_default();
3180 if (!bgp_def)
3181 return;
3182 bgp_evpn_map_vrf_to_its_rts(bgp_vrf);
c581d8b0
MK
3183}
3184
3185/*
3186 * Delete AUTO import RT from BGP VRF - L3VNI
3187 */
3188static void evpn_auto_rt_import_delete_for_vrf(struct bgp *bgp_vrf)
3189{
3190 evpn_rt_delete_auto(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_import_rtl);
3191}
3192
3193/*
3194 * Derive AUTO export RT for BGP VRF - L3VNI
3195 */
3196static void evpn_auto_rt_export_add_for_vrf(struct bgp *bgp_vrf)
3197{
3198 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD);
3199 form_auto_rt(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_export_rtl);
3200}
3201
3202/*
3203 * Delete AUTO export RT from BGP VRF - L3VNI
3204 */
3205static void evpn_auto_rt_export_delete_for_vrf(struct bgp *bgp_vrf)
3206{
3207 evpn_rt_delete_auto(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_export_rtl);
3208}
128ea8ab 3209
f1f8b53c
MK
3210static void bgp_evpn_handle_export_rt_change_for_vrf(struct bgp *bgp_vrf)
3211{
3212 struct bgp *bgp_def = NULL;
3213 struct listnode *node = NULL;
3214 struct bgpevpn *vpn = NULL;
3215
3216 bgp_def = bgp_get_default();
3217 if (!bgp_def)
3218 return;
3219
4992b4ae
MK
3220 /* update all type-5 routes */
3221 update_advertise_vrf_routes(bgp_vrf);
3222
3223 /* update all type-2 routes */
f1f8b53c
MK
3224 for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn))
3225 update_routes_for_vni(bgp_def, vpn);
3226}
3227
128ea8ab 3228/*
3229 * Public functions.
3230 */
3231
5424b7ba 3232/* withdraw type-5 route corresponding to ip prefix */
31310b25 3233void bgp_evpn_withdraw_type5_route(struct bgp *bgp_vrf, struct prefix *p,
5424b7ba
MK
3234 afi_t afi, safi_t safi)
3235{
3236 int ret = 0;
3237 struct prefix_evpn evp;
3238 char buf[PREFIX_STRLEN];
3239
31310b25 3240 build_type5_prefix_from_ip_prefix(&evp, p);
5424b7ba
MK
3241 ret = delete_evpn_type5_route(bgp_vrf, &evp);
3242 if (ret) {
3243 zlog_err(
996c9314
LB
3244 "%u failed to delete type-5 route for prefix %s in vrf %s",
3245 bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf)),
3246 vrf_id_to_name(bgp_vrf->vrf_id));
5424b7ba
MK
3247 }
3248}
3249
342dd0c6 3250/* withdraw all type-5 routes for an address family */
996c9314 3251void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, afi_t afi, safi_t safi)
342dd0c6 3252{
3253 struct bgp_table *table = NULL;
3254 struct bgp_node *rn = NULL;
25f2ca53 3255 struct bgp_info *ri;
342dd0c6 3256
053905d2 3257 table = bgp_vrf->rib[afi][safi];
25f2ca53 3258 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
3259 /* Only care about "selected" routes - non-imported. */
3260 /* TODO: Support for AddPath for EVPN. */
3261 for (ri = rn->info; ri; ri = ri->next) {
996c9314
LB
3262 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)
3263 && (!ri->extra || !ri->extra->parent)) {
25f2ca53 3264 bgp_evpn_withdraw_type5_route(bgp_vrf, &rn->p,
3265 afi, safi);
3266 break;
3267 }
3268 }
3269 }
5424b7ba 3270}
342dd0c6 3271
2f69f6d3 3272/*
3273 * Advertise IP prefix as type-5 route. The afi/safi and src_attr passed
3274 * to this function correspond to those of the source IP prefix (best
3275 * path in the case of the attr. In the case of a local prefix (when we
3276 * are advertising local subnets), the src_attr will be NULL.
3277 */
31310b25 3278void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p,
996c9314
LB
3279 struct attr *src_attr, afi_t afi,
3280 safi_t safi)
5424b7ba
MK
3281{
3282 int ret = 0;
3283 struct prefix_evpn evp;
3284 char buf[PREFIX_STRLEN];
7b1bf203 3285
31310b25 3286 build_type5_prefix_from_ip_prefix(&evp, p);
2f69f6d3 3287 ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr);
3288 if (ret)
996c9314
LB
3289 zlog_err("%u: Failed to create type-5 route for prefix %s",
3290 bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf)));
342dd0c6 3291}
3292
2f69f6d3 3293/* Inject all prefixes of a particular address-family (currently, IPv4 or
3294 * IPv6 unicast) into EVPN as type-5 routes. This is invoked when the
3295 * advertisement is enabled.
3296 */
996c9314
LB
3297void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi,
3298 safi_t safi)
342dd0c6 3299{
3300 struct bgp_table *table = NULL;
3301 struct bgp_node *rn = NULL;
2f69f6d3 3302 struct bgp_info *ri;
342dd0c6 3303
053905d2 3304 table = bgp_vrf->rib[afi][safi];
31310b25 3305 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
2f69f6d3 3306 /* Need to identify the "selected" route entry to use its
25f2ca53 3307 * attribute. Also, we only consider "non-imported" routes.
2f69f6d3 3308 * TODO: Support for AddPath for EVPN.
3309 */
3310 for (ri = rn->info; ri; ri = ri->next) {
996c9314
LB
3311 if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)
3312 && (!ri->extra || !ri->extra->parent)) {
53c84f78
MK
3313
3314 /* apply the route-map */
3315 if (bgp_vrf->adv_cmd_rmap[afi][safi].map) {
3316 int ret = 0;
3317
996c9314
LB
3318 ret = route_map_apply(
3319 bgp_vrf->adv_cmd_rmap[afi][safi]
3320 .map,
3321 &rn->p, RMAP_BGP, ri);
53c84f78
MK
3322 if (ret == RMAP_DENYMATCH)
3323 continue;
3324 }
996c9314
LB
3325 bgp_evpn_advertise_type5_route(
3326 bgp_vrf, &rn->p, ri->attr, afi, safi);
2f69f6d3 3327 break;
3328 }
3329 }
31310b25 3330 }
342dd0c6 3331}
3332
996c9314 3333void evpn_rt_delete_auto(struct bgp *bgp, vni_t vni, struct list *rtl)
c581d8b0
MK
3334{
3335 struct listnode *node, *nnode, *node_to_del;
3336 struct ecommunity *ecom, *ecom_auto;
3337 struct ecommunity_val eval;
3338
3339 encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
3340
3341 ecom_auto = ecommunity_new();
3342 ecommunity_add_val(ecom_auto, &eval);
3343 node_to_del = NULL;
3344
3345 for (ALL_LIST_ELEMENTS(rtl, node, nnode, ecom)) {
3346 if (ecommunity_match(ecom, ecom_auto)) {
3347 ecommunity_free(&ecom);
3348 node_to_del = node;
3349 }
3350 }
3351
3352 if (node_to_del)
3353 list_delete_node(rtl, node_to_del);
3354
3355 ecommunity_free(&ecom_auto);
3356}
3357
3358void bgp_evpn_configure_import_rt_for_vrf(struct bgp *bgp_vrf,
10ebe1ab 3359 struct ecommunity *ecomadd)
c581d8b0 3360{
5ba238b7
MK
3361 /* uninstall routes from vrf */
3362 uninstall_routes_for_vrf(bgp_vrf);
10ebe1ab
MK
3363
3364 /* Cleanup the RT to VRF mapping */
3365 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf);
3366
c581d8b0
MK
3367 /* Remove auto generated RT */
3368 evpn_auto_rt_import_delete_for_vrf(bgp_vrf);
3369
3370 /* Add the newly configured RT to RT list */
3371 listnode_add_sort(bgp_vrf->vrf_import_rtl, ecomadd);
3372 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD);
3373
10ebe1ab
MK
3374 /* map VRF to its RTs */
3375 bgp_evpn_map_vrf_to_its_rts(bgp_vrf);
3376
5ba238b7
MK
3377 /* install routes matching the new VRF */
3378 install_routes_for_vrf(bgp_vrf);
c581d8b0
MK
3379}
3380
3381void bgp_evpn_unconfigure_import_rt_for_vrf(struct bgp *bgp_vrf,
3382 struct ecommunity *ecomdel)
3383{
3384 struct listnode *node = NULL, *nnode = NULL, *node_to_del = NULL;
3385 struct ecommunity *ecom = NULL;
3386
5ba238b7
MK
3387 /* uninstall routes from vrf */
3388 uninstall_routes_for_vrf(bgp_vrf);
10ebe1ab
MK
3389
3390 /* Cleanup the RT to VRF mapping */
3391 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf);
3392
c581d8b0
MK
3393 /* remove the RT from the RT list */
3394 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_import_rtl, node, nnode, ecom)) {
3395 if (ecommunity_match(ecom, ecomdel)) {
3396 ecommunity_free(&ecom);
3397 node_to_del = node;
3398 break;
3399 }
3400 }
3401
3402 if (node_to_del)
3403 list_delete_node(bgp_vrf->vrf_import_rtl, node_to_del);
3404
3405 /* fallback to auto import rt, if this was the last RT */
3406 if (list_isempty(bgp_vrf->vrf_import_rtl)) {
3407 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD);
3408 evpn_auto_rt_import_add_for_vrf(bgp_vrf);
3409 }
3410
10ebe1ab
MK
3411 /* map VRFs to its RTs */
3412 bgp_evpn_map_vrf_to_its_rts(bgp_vrf);
3413
5ba238b7
MK
3414 /* install routes matching this new RT */
3415 install_routes_for_vrf(bgp_vrf);
c581d8b0
MK
3416}
3417
3418void bgp_evpn_configure_export_rt_for_vrf(struct bgp *bgp_vrf,
3419 struct ecommunity *ecomadd)
3420{
3421 /* remove auto-generated RT */
3422 evpn_auto_rt_export_delete_for_vrf(bgp_vrf);
3423
3424 /* Add the new RT to the RT list */
3425 listnode_add_sort(bgp_vrf->vrf_export_rtl, ecomadd);
3426 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD);
3427
f1f8b53c 3428 bgp_evpn_handle_export_rt_change_for_vrf(bgp_vrf);
c581d8b0
MK
3429}
3430
3431void bgp_evpn_unconfigure_export_rt_for_vrf(struct bgp *bgp_vrf,
3432 struct ecommunity *ecomdel)
3433{
3434 struct listnode *node = NULL, *nnode = NULL, *node_to_del = NULL;
3435 struct ecommunity *ecom = NULL;
3436
3437 /* Remove the RT from the RT list */
3438 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_export_rtl, node, nnode, ecom)) {
3439 if (ecommunity_match(ecom, ecomdel)) {
3440 ecommunity_free(&ecom);
3441 node_to_del = node;
3442 break;
3443 }
3444 }
3445
3446 if (node_to_del)
3447 list_delete_node(bgp_vrf->vrf_export_rtl, node_to_del);
3448
3449 /* fall back to auto-generated RT if this was the last RT */
877702e7 3450 if (bgp_vrf->vrf_export_rtl && list_isempty(bgp_vrf->vrf_export_rtl)) {
c581d8b0
MK
3451 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD);
3452 evpn_auto_rt_export_add_for_vrf(bgp_vrf);
3453 }
3454
f1f8b53c 3455 bgp_evpn_handle_export_rt_change_for_vrf(bgp_vrf);
c581d8b0
MK
3456}
3457
2d48ee25 3458/*
3459 * Handle change to BGP router id. This is invoked twice by the change
3460 * handler, first before the router id has been changed and then after
3461 * the router id has been changed. The first invocation will result in
676f83b9 3462 * local routes for all VNIs/VRF being deleted and withdrawn and the next
2d48ee25 3463 * will result in the routes being re-advertised.
3464 */
d62a17ae 3465void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw)
2d48ee25 3466{
676f83b9 3467 if (withdraw) {
3468
3469 /* delete and withdraw all the type-5 routes
523cafc4 3470 stored in the global table for this vrf
3471 */
80b140af 3472 withdraw_router_id_vrf(bgp);
676f83b9 3473
3474 /* delete all the VNI routes (type-2/type-3) routes for all the
523cafc4 3475 * L2-VNIs
3476 */
d62a17ae 3477 hash_iterate(bgp->vnihash,
3478 (void (*)(struct hash_backet *,
3479 void *))withdraw_router_id_vni,
3480 bgp);
676f83b9 3481 } else {
3482
3483 /* advertise all routes in the vrf as type-5 routes with the new
523cafc4 3484 * RD
3485 */
80b140af 3486 update_router_id_vrf(bgp);
676f83b9 3487
3488 /* advertise all the VNI routes (type-2/type-3) routes with the
523cafc4 3489 * new RD
3490 */
d62a17ae 3491 hash_iterate(bgp->vnihash,
3492 (void (*)(struct hash_backet *,
3493 void *))update_router_id_vni,
3494 bgp);
676f83b9 3495 }
2d48ee25 3496}
3497
90e60aa7 3498/*
3499 * Handle change to export RT - update and advertise local routes.
3500 */
d62a17ae 3501int bgp_evpn_handle_export_rt_change(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 3502{
d62a17ae 3503 return update_routes_for_vni(bgp, vpn);
90e60aa7 3504}
3505
996c9314 3506void bgp_evpn_handle_vrf_rd_change(struct bgp *bgp_vrf, int withdraw)
676f83b9 3507{
3508 if (withdraw)
3509 delete_withdraw_vrf_routes(bgp_vrf);
3510 else
3511 update_advertise_vrf_routes(bgp_vrf);
3512}
3513
90e60aa7 3514/*
3515 * Handle change to RD. This is invoked twice by the change handler,
3516 * first before the RD has been changed and then after the RD has
3517 * been changed. The first invocation will result in local routes
3518 * of this VNI being deleted and withdrawn and the next will result
3519 * in the routes being re-advertised.
3520 */
d62a17ae 3521void bgp_evpn_handle_rd_change(struct bgp *bgp, struct bgpevpn *vpn,
3522 int withdraw)
90e60aa7 3523{
d62a17ae 3524 if (withdraw)
3525 delete_withdraw_vni_routes(bgp, vpn);
3526 else
3527 update_advertise_vni_routes(bgp, vpn);
90e60aa7 3528}
3529
3530/*
3531 * Install routes for this VNI. Invoked upon change to Import RT.
3532 */
d62a17ae 3533int bgp_evpn_install_routes(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 3534{
d62a17ae 3535 return install_routes_for_vni(bgp, vpn);
90e60aa7 3536}
3537
3538/*
3539 * Uninstall all routes installed for this VNI. Invoked upon change
3540 * to Import RT.
3541 */
d62a17ae 3542int bgp_evpn_uninstall_routes(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 3543{
d62a17ae 3544 return uninstall_routes_for_vni(bgp, vpn);
90e60aa7 3545}
3546
b16031a2 3547/*
b57ba6d2 3548 * TODO: Hardcoded for a maximum of 2 VNIs right now
b16031a2 3549 */
996c9314
LB
3550char *bgp_evpn_label2str(mpls_label_t *label, u_int32_t num_labels, char *buf,
3551 int len)
b16031a2 3552{
b57ba6d2 3553 vni_t vni1, vni2;
b16031a2 3554
b57ba6d2
MK
3555 vni1 = label2vni(label);
3556 if (num_labels == 2) {
996c9314 3557 vni2 = label2vni(label + 1);
b57ba6d2
MK
3558 snprintf(buf, len, "%u/%u", vni1, vni2);
3559 } else
3560 snprintf(buf, len, "%u", vni1);
d62a17ae 3561 return buf;
b16031a2 3562}
3563
9c92b5f7
MK
3564/*
3565 * Function to convert evpn route to json format.
3566 * NOTE: We don't use prefix2str as the output here is a bit different.
3567 */
57f7feb6 3568void bgp_evpn_route2json(struct prefix_evpn *p, json_object *json)
9c92b5f7 3569{
b682f6de 3570 char buf1[ETHER_ADDR_STRLEN];
3571 char buf2[PREFIX2STR_BUFFER];
9c92b5f7 3572
b682f6de 3573 if (!json)
3574 return;
9c92b5f7 3575
dff8f48d 3576 if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) {
b682f6de 3577 json_object_int_add(json, "routeType", p->prefix.route_type);
3578 json_object_int_add(json, "ethTag", 0);
57f7feb6
MK
3579 json_object_int_add(json, "ipLen",
3580 IS_EVPN_PREFIX_IPADDR_V4(p)
3581 ? IPV4_MAX_BITLEN
3582 : IPV6_MAX_BITLEN);
b682f6de 3583 json_object_string_add(json, "ip",
57f7feb6
MK
3584 inet_ntoa(p->prefix.ip.ipaddr_v4));
3585 } else if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
dff8f48d 3586 if (IS_EVPN_PREFIX_IPADDR_NONE(p)) {
57f7feb6
MK
3587 json_object_int_add(json, "routeType",
3588 p->prefix.route_type);
3589 json_object_int_add(
3590 json, "esi",
3591 0); /* TODO: we don't support esi yet */
3592 json_object_int_add(json, "ethTag", 0);
3593 json_object_int_add(json, "macLen", 8 * ETH_ALEN);
3594 json_object_string_add(json, "mac",
3595 prefix_mac2str(&p->prefix.mac,
3596 buf1,
3597 sizeof(buf1)));
dff8f48d
MK
3598 } else {
3599 u_char family;
3600
57f7feb6
MK
3601 family = IS_EVPN_PREFIX_IPADDR_V4(p) ? AF_INET
3602 : AF_INET6;
dff8f48d 3603
b682f6de 3604 json_object_int_add(json, "routeType",
57f7feb6
MK
3605 p->prefix.route_type);
3606 json_object_int_add(
3607 json, "esi",
3608 0); /* TODO: we don't support esi yet */
b682f6de 3609 json_object_int_add(json, "ethTag", 0);
57f7feb6 3610 json_object_int_add(json, "macLen", 8 * ETH_ALEN);
b682f6de 3611 json_object_string_add(json, "mac",
57f7feb6
MK
3612 prefix_mac2str(&p->prefix.mac,
3613 buf1,
3614 sizeof(buf1)));
b682f6de 3615 json_object_int_add(json, "ipLen",
57f7feb6
MK
3616 IS_EVPN_PREFIX_IPADDR_V4(p)
3617 ? IPV4_MAX_BITLEN
3618 : IPV6_MAX_BITLEN);
3619 json_object_string_add(
3620 json, "ip",
3621 inet_ntop(family, &p->prefix.ip.ip.addr, buf2,
3622 PREFIX2STR_BUFFER));
dff8f48d
MK
3623 }
3624 } else {
3625 /* Currently, this is to cater to other AF_ETHERNET code. */
3626 }
9c92b5f7
MK
3627}
3628
520d5d76 3629/*
3630 * Function to convert evpn route to string.
3631 * NOTE: We don't use prefix2str as the output here is a bit different.
3632 */
d62a17ae 3633char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len)
3634{
3635 char buf1[ETHER_ADDR_STRLEN];
3636 char buf2[PREFIX2STR_BUFFER];
3637
3638 if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) {
3639 snprintf(buf, len, "[%d]:[0]:[%d]:[%s]", p->prefix.route_type,
3640 IS_EVPN_PREFIX_IPADDR_V4(p) ? IPV4_MAX_BITLEN
3641 : IPV6_MAX_BITLEN,
3642 inet_ntoa(p->prefix.ip.ipaddr_v4));
3643 } else if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
3644 if (IS_EVPN_PREFIX_IPADDR_NONE(p))
3645 snprintf(buf, len, "[%d]:[0]:[0]:[%d]:[%s]",
28328ea9 3646 p->prefix.route_type, 8 * ETH_ALEN,
d62a17ae 3647 prefix_mac2str(&p->prefix.mac, buf1,
3648 sizeof(buf1)));
3649 else {
3650 u_char family;
3651
3652 family = IS_EVPN_PREFIX_IPADDR_V4(p) ? AF_INET
3653 : AF_INET6;
3654 snprintf(buf, len, "[%d]:[0]:[0]:[%d]:[%s]:[%d]:[%s]",
28328ea9 3655 p->prefix.route_type, 8 * ETH_ALEN,
d62a17ae 3656 prefix_mac2str(&p->prefix.mac, buf1,
3657 sizeof(buf1)),
3658 family == AF_INET ? IPV4_MAX_BITLEN
3659 : IPV6_MAX_BITLEN,
3660 inet_ntop(family, &p->prefix.ip.ip.addr, buf2,
3661 PREFIX2STR_BUFFER));
3662 }
342dd0c6 3663 } else if (p->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE) {
b3628c70 3664 snprintf(buf, len, "[%d]:[0]:[0]:[%d]:[%s]",
996c9314
LB
3665 p->prefix.route_type, p->prefix.ip_prefix_length,
3666 IS_EVPN_PREFIX_IPADDR_V4(p)
3667 ? inet_ntoa(p->prefix.ip.ipaddr_v4)
3668 : inet6_ntoa(p->prefix.ip.ipaddr_v6));
d62a17ae 3669 } else {
b03b8898 3670 /* For EVPN route types not supported yet. */
f9aa3e55
QY
3671 snprintf(buf, len, "(unsupported route type %d)",
3672 p->prefix.route_type);
d62a17ae 3673 }
3674
3675 return (buf);
520d5d76 3676}
3677
128ea8ab 3678/*
3679 * Encode EVPN prefix in Update (MP_REACH)
3680 */
d62a17ae 3681void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
996c9314
LB
3682 struct prefix_rd *prd, mpls_label_t *label,
3683 u_int32_t num_labels, struct attr *attr,
3684 int addpath_encode, u_int32_t addpath_tx_id)
d62a17ae 3685{
3686 struct prefix_evpn *evp = (struct prefix_evpn *)p;
b57ba6d2 3687 int len, ipa_len = 0;
d62a17ae 3688
3689 if (addpath_encode)
3690 stream_putl(s, addpath_tx_id);
3691
3692 /* Route type */
3693 stream_putc(s, evp->prefix.route_type);
3694
3695 switch (evp->prefix.route_type) {
3696 case BGP_EVPN_MAC_IP_ROUTE:
3697 if (IS_EVPN_PREFIX_IPADDR_V4(evp))
3698 ipa_len = IPV4_MAX_BYTELEN;
3699 else if (IS_EVPN_PREFIX_IPADDR_V6(evp))
3700 ipa_len = IPV6_MAX_BYTELEN;
b57ba6d2
MK
3701 /* RD, ESI, EthTag, MAC+len, IP len, [IP], 1 VNI */
3702 len = 8 + 10 + 4 + 1 + 6 + 1 + ipa_len + 3;
3703 if (ipa_len && num_labels > 1) /* There are 2 VNIs */
3704 len += 3;
3705 stream_putc(s, len);
996c9314
LB
3706 stream_put(s, prd->val, 8); /* RD */
3707 stream_put(s, 0, 10); /* ESI */
3708 stream_putl(s, 0); /* Ethernet Tag ID */
28328ea9 3709 stream_putc(s, 8 * ETH_ALEN); /* Mac Addr Len - bits */
d62a17ae 3710 stream_put(s, evp->prefix.mac.octet, 6); /* Mac Addr */
3711 stream_putc(s, 8 * ipa_len); /* IP address Length */
996c9314 3712 if (ipa_len) /* IP */
b57ba6d2
MK
3713 stream_put(s, &evp->prefix.ip.ip.addr, ipa_len);
3714 /* 1st label is the L2 VNI */
3715 stream_put(s, label, BGP_LABEL_BYTES);
3716 /* Include 2nd label (L3 VNI) if advertising MAC+IP */
3717 if (ipa_len && num_labels > 1)
996c9314 3718 stream_put(s, label + 1, BGP_LABEL_BYTES);
d62a17ae 3719 break;
3720
3721 case BGP_EVPN_IMET_ROUTE:
3722 stream_putc(s, 17); // TODO: length - assumes IPv4 address
3723 stream_put(s, prd->val, 8); /* RD */
3724 stream_putl(s, 0); /* Ethernet Tag ID */
3725 stream_putc(s, IPV4_MAX_BITLEN); /* IP address Length - bits */
3726 /* Originating Router's IP Addr */
3727 stream_put_in_addr(s, &evp->prefix.ip.ipaddr_v4);
3728 break;
3729
3730 case BGP_EVPN_IP_PREFIX_ROUTE:
3731 /* TODO: AddPath support. */
b57ba6d2 3732 evpn_mpattr_encode_type5(s, p, prd, label, num_labels, attr);
d62a17ae 3733 break;
3734
3735 default:
3736 break;
3737 }
3738}
3739
3740int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
3741 struct bgp_nlri *packet, int withdraw)
3742{
3743 u_char *pnt;
3744 u_char *lim;
3745 afi_t afi;
3746 safi_t safi;
3747 u_int32_t addpath_id;
3748 int addpath_encoded;
3749 int psize = 0;
3750 u_char rtype;
3751 u_char rlen;
3752 struct prefix p;
3753
d62a17ae 3754 /* Start processing the NLRI - there may be multiple in the MP_REACH */
3755 pnt = packet->nlri;
3756 lim = pnt + packet->length;
3757 afi = packet->afi;
3758 safi = packet->safi;
3759 addpath_id = 0;
3760
3761 addpath_encoded =
3762 (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
3763 && CHECK_FLAG(peer->af_cap[afi][safi],
3764 PEER_CAP_ADDPATH_AF_TX_RCV));
3765
3766 for (; pnt < lim; pnt += psize) {
3767 /* Clear prefix structure. */
3768 memset(&p, 0, sizeof(struct prefix));
3769
3770 /* Deal with path-id if AddPath is supported. */
3771 if (addpath_encoded) {
3772 /* When packet overflow occurs return immediately. */
3773 if (pnt + BGP_ADDPATH_ID_LEN > lim)
3774 return -1;
3775
3776 addpath_id = ntohl(*((uint32_t *)pnt));
3777 pnt += BGP_ADDPATH_ID_LEN;
3778 }
3779
3780 /* All EVPN NLRI types start with type and length. */
3781 if (pnt + 2 > lim)
3782 return -1;
3783
3784 rtype = *pnt++;
3785 psize = rlen = *pnt++;
3786
3787 /* When packet overflow occur return immediately. */
3788 if (pnt + psize > lim)
3789 return -1;
3790
3791 switch (rtype) {
3792 case BGP_EVPN_MAC_IP_ROUTE:
3793 if (process_type2_route(peer, afi, safi,
3794 withdraw ? NULL : attr, pnt,
3795 psize, addpath_id)) {
3796 zlog_err(
3797 "%u:%s - Error in processing EVPN type-2 NLRI size %d",
3798 peer->bgp->vrf_id, peer->host, psize);
3799 return -1;
3800 }
3801 break;
3802
3803 case BGP_EVPN_IMET_ROUTE:
3804 if (process_type3_route(peer, afi, safi,
3805 withdraw ? NULL : attr, pnt,
3806 psize, addpath_id)) {
3807 zlog_err(
3808 "%u:%s - Error in processing EVPN type-3 NLRI size %d",
3809 peer->bgp->vrf_id, peer->host, psize);
3810 return -1;
3811 }
3812 break;
3813
3814 case BGP_EVPN_IP_PREFIX_ROUTE:
3815 if (process_type5_route(peer, afi, safi, attr, pnt,
3816 psize, addpath_id, withdraw)) {
3817 zlog_err(
3818 "%u:%s - Error in processing EVPN type-5 NLRI size %d",
3819 peer->bgp->vrf_id, peer->host, psize);
3820 return -1;
3821 }
3822 break;
3823
3824 default:
3825 break;
3826 }
3827 }
3828
3829 /* Packet length consistency check. */
3830 if (pnt != lim)
3831 return -1;
3832
3833 return 0;
128ea8ab 3834}
3835
10ebe1ab
MK
3836/*
3837 * Map the RTs (configured or automatically derived) of a VRF to the VRF.
3838 * The mapping will be used during route processing.
3839 * bgp_def: default bgp instance
3840 * bgp_vrf: specific bgp vrf instance on which RT is configured
3841 */
3842void bgp_evpn_map_vrf_to_its_rts(struct bgp *bgp_vrf)
3843{
3844 int i = 0;
3845 struct ecommunity_val *eval = NULL;
3846 struct listnode *node = NULL, *nnode = NULL;
3847 struct ecommunity *ecom = NULL;
3848
3849 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_import_rtl, node, nnode, ecom)) {
3850 for (i = 0; i < ecom->size; i++) {
3851 eval = (struct ecommunity_val *)(ecom->val
3852 + (i
3853 * ECOMMUNITY_SIZE));
3854 map_vrf_to_rt(bgp_vrf, eval);
3855 }
3856 }
3857}
3858
3859/*
3860 * Unmap the RTs (configured or automatically derived) of a VRF from the VRF.
3861 */
3862void bgp_evpn_unmap_vrf_from_its_rts(struct bgp *bgp_vrf)
3863{
3864 int i;
3865 struct ecommunity_val *eval;
3866 struct listnode *node, *nnode;
3867 struct ecommunity *ecom;
3868
3869 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_import_rtl, node, nnode, ecom)) {
3870 for (i = 0; i < ecom->size; i++) {
3871 struct vrf_irt_node *irt;
3872 struct ecommunity_val eval_tmp;
3873
3874 eval = (struct ecommunity_val *)(ecom->val
3875 + (i
3876 * ECOMMUNITY_SIZE));
3877 /* If using "automatic" RT, we only care about the
3878 * local-admin sub-field.
3879 * This is to facilitate using VNI as the RT for EBGP
3880 * peering too.
3881 */
3882 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
3883 if (!CHECK_FLAG(bgp_vrf->vrf_flags,
3884 BGP_VRF_IMPORT_RT_CFGD))
3885 mask_ecom_global_admin(&eval_tmp, eval);
3886
3887 irt = lookup_vrf_import_rt(&eval_tmp);
3888 if (irt)
3889 unmap_vrf_from_rt(bgp_vrf, irt);
3890 }
3891 }
3892}
3893
3894
128ea8ab 3895/*
3896 * Map the RTs (configured or automatically derived) of a VNI to the VNI.
3897 * The mapping will be used during route processing.
3898 */
d62a17ae 3899void bgp_evpn_map_vni_to_its_rts(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 3900{
d62a17ae 3901 int i;
3902 struct ecommunity_val *eval;
3903 struct listnode *node, *nnode;
3904 struct ecommunity *ecom;
128ea8ab 3905
d62a17ae 3906 for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
3907 for (i = 0; i < ecom->size; i++) {
3908 eval = (struct ecommunity_val *)(ecom->val
3909 + (i
3910 * ECOMMUNITY_SIZE));
3911 map_vni_to_rt(bgp, vpn, eval);
3912 }
3913 }
128ea8ab 3914}
3915
3916/*
3917 * Unmap the RTs (configured or automatically derived) of a VNI from the VNI.
3918 */
d62a17ae 3919void bgp_evpn_unmap_vni_from_its_rts(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 3920{
d62a17ae 3921 int i;
3922 struct ecommunity_val *eval;
3923 struct listnode *node, *nnode;
3924 struct ecommunity *ecom;
128ea8ab 3925
d62a17ae 3926 for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
3927 for (i = 0; i < ecom->size; i++) {
3928 struct irt_node *irt;
3929 struct ecommunity_val eval_tmp;
128ea8ab 3930
d62a17ae 3931 eval = (struct ecommunity_val *)(ecom->val
3932 + (i
3933 * ECOMMUNITY_SIZE));
3934 /* If using "automatic" RT, we only care about the
3935 * local-admin sub-field.
3936 * This is to facilitate using VNI as the RT for EBGP
3937 * peering too.
3938 */
3939 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
3940 if (!is_import_rt_configured(vpn))
3941 mask_ecom_global_admin(&eval_tmp, eval);
128ea8ab 3942
d62a17ae 3943 irt = lookup_import_rt(bgp, &eval_tmp);
3944 if (irt)
3945 unmap_vni_from_rt(bgp, vpn, irt);
3946 }
3947 }
128ea8ab 3948}
3949
3950/*
3951 * Derive Import RT automatically for VNI and map VNI to RT.
3952 * The mapping will be used during route processing.
3953 */
d62a17ae 3954void bgp_evpn_derive_auto_rt_import(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 3955{
c581d8b0 3956 form_auto_rt(bgp, vpn->vni, vpn->import_rtl);
d62a17ae 3957 UNSET_FLAG(vpn->flags, VNI_FLAG_IMPRT_CFGD);
128ea8ab 3958
d62a17ae 3959 /* Map RT to VNI */
3960 bgp_evpn_map_vni_to_its_rts(bgp, vpn);
128ea8ab 3961}
3962
3963/*
3964 * Derive Export RT automatically for VNI.
3965 */
d62a17ae 3966void bgp_evpn_derive_auto_rt_export(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 3967{
c581d8b0 3968 form_auto_rt(bgp, vpn->vni, vpn->export_rtl);
d62a17ae 3969 UNSET_FLAG(vpn->flags, VNI_FLAG_EXPRT_CFGD);
128ea8ab 3970}
3971
676f83b9 3972/*
3973 * Derive RD automatically for VNI using passed information - it
3974 * is of the form RouterId:unique-id-for-vni.
3975 */
3976void bgp_evpn_derive_auto_rd_for_vrf(struct bgp *bgp)
3977{
3978 char buf[100];
3979
3980 bgp->vrf_prd.family = AF_UNSPEC;
3981 bgp->vrf_prd.prefixlen = 64;
3982 sprintf(buf, "%s:%hu", inet_ntoa(bgp->router_id), bgp->vrf_rd_id);
a1a5feed 3983 (void)str2prefix_rd(buf, &bgp->vrf_prd);
676f83b9 3984}
3985
128ea8ab 3986/*
3987 * Derive RD automatically for VNI using passed information - it
3988 * is of the form RouterId:unique-id-for-vni.
3989 */
d62a17ae 3990void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 3991{
d62a17ae 3992 char buf[100];
128ea8ab 3993
d62a17ae 3994 vpn->prd.family = AF_UNSPEC;
3995 vpn->prd.prefixlen = 64;
3996 sprintf(buf, "%s:%hu", inet_ntoa(bgp->router_id), vpn->rd_id);
cbb65f5e 3997 (void)str2prefix_rd(buf, &vpn->prd);
d62a17ae 3998 UNSET_FLAG(vpn->flags, VNI_FLAG_RD_CFGD);
128ea8ab 3999}
4000
4001/*
4002 * Lookup VNI.
4003 */
d62a17ae 4004struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni)
128ea8ab 4005{
d62a17ae 4006 struct bgpevpn *vpn;
4007 struct bgpevpn tmp;
128ea8ab 4008
d62a17ae 4009 memset(&tmp, 0, sizeof(struct bgpevpn));
4010 tmp.vni = vni;
4011 vpn = hash_lookup(bgp->vnihash, &tmp);
4012 return vpn;
128ea8ab 4013}
4014
4015/*
4016 * Create a new vpn - invoked upon configuration or zebra notification.
4017 */
d62a17ae 4018struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
29c53922
MK
4019 struct in_addr originator_ip,
4020 vrf_id_t tenant_vrf_id)
128ea8ab 4021{
d62a17ae 4022 struct bgpevpn *vpn;
128ea8ab 4023
d62a17ae 4024 if (!bgp)
4025 return NULL;
128ea8ab 4026
d62a17ae 4027 vpn = XCALLOC(MTYPE_BGP_EVPN, sizeof(struct bgpevpn));
4028 if (!vpn)
4029 return NULL;
128ea8ab 4030
d62a17ae 4031 /* Set values - RD and RT set to defaults. */
4032 vpn->vni = vni;
4033 vpn->originator_ip = originator_ip;
29c53922 4034 vpn->tenant_vrf_id = tenant_vrf_id;
128ea8ab 4035
d62a17ae 4036 /* Initialize route-target import and export lists */
4037 vpn->import_rtl = list_new();
4038 vpn->import_rtl->cmp = (int (*)(void *, void *))evpn_route_target_cmp;
4039 vpn->export_rtl = list_new();
4040 vpn->export_rtl->cmp = (int (*)(void *, void *))evpn_route_target_cmp;
e9eb5f63 4041 bf_assign_index(bm->rd_idspace, vpn->rd_id);
d62a17ae 4042 derive_rd_rt_for_vni(bgp, vpn);
128ea8ab 4043
d62a17ae 4044 /* Initialize EVPN route table. */
4045 vpn->route_table = bgp_table_init(AFI_L2VPN, SAFI_EVPN);
128ea8ab 4046
d62a17ae 4047 /* Add to hash */
4048 if (!hash_get(bgp->vnihash, vpn, hash_alloc_intern)) {
4049 XFREE(MTYPE_BGP_EVPN, vpn);
4050 return NULL;
4051 }
6a8657d0
MK
4052
4053 /* add to l2vni list on corresponding vrf */
4054 bgpevpn_link_to_l3vni(vpn);
4055
d62a17ae 4056 QOBJ_REG(vpn, bgpevpn);
4057 return vpn;
128ea8ab 4058}
4059
4060/*
4061 * Free a given VPN - called in multiple scenarios such as zebra
4062 * notification, configuration being deleted, advertise-all-vni disabled etc.
4063 * This just frees appropriate memory, caller should have taken other
4064 * needed actions.
4065 */
d62a17ae 4066void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 4067{
6a8657d0 4068 bgpevpn_unlink_from_l3vni(vpn);
d62a17ae 4069 bgp_table_unlock(vpn->route_table);
4070 bgp_evpn_unmap_vni_from_its_rts(bgp, vpn);
affe9e99
DS
4071 list_delete_and_null(&vpn->import_rtl);
4072 list_delete_and_null(&vpn->export_rtl);
e9eb5f63 4073 bf_release_index(bm->rd_idspace, vpn->rd_id);
d62a17ae 4074 hash_release(bgp->vnihash, vpn);
4075 QOBJ_UNREG(vpn);
4076 XFREE(MTYPE_BGP_EVPN, vpn);
128ea8ab 4077}
4078
4079/*
4080 * Import route into matching VNI(s).
4081 */
d62a17ae 4082int bgp_evpn_import_route(struct bgp *bgp, afi_t afi, safi_t safi,
4083 struct prefix *p, struct bgp_info *ri)
128ea8ab 4084{
d62a17ae 4085 return install_uninstall_evpn_route(bgp, afi, safi, p, ri, 1);
128ea8ab 4086}
4087
4088/*
4089 * Unimport route from matching VNI(s).
4090 */
d62a17ae 4091int bgp_evpn_unimport_route(struct bgp *bgp, afi_t afi, safi_t safi,
4092 struct prefix *p, struct bgp_info *ri)
128ea8ab 4093{
d62a17ae 4094 return install_uninstall_evpn_route(bgp, afi, safi, p, ri, 0);
128ea8ab 4095}
4096
db0e1937
MK
4097/* filter routes which have martian next hops */
4098int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp)
4099{
0291c246
MK
4100 afi_t afi;
4101 safi_t safi;
4102 struct bgp_node *rd_rn, *rn;
4103 struct bgp_table *table;
4104 struct bgp_info *ri;
db0e1937
MK
4105
4106 afi = AFI_L2VPN;
4107 safi = SAFI_EVPN;
4108
4109 /* Walk entire global routing table and evaluate routes which could be
4110 * imported into this VPN. Note that we cannot just look at the routes
4111 * for the VNI's RD -
4112 * remote routes applicable for this VNI could have any RD.
4113 */
4114 /* EVPN routes are a 2-level table. */
4115 for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
4116 rd_rn = bgp_route_next(rd_rn)) {
4117 table = (struct bgp_table *)(rd_rn->info);
4118 if (!table)
4119 continue;
4120
4121 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
4122
4123 for (ri = rn->info; ri; ri = ri->next) {
4124
4125 /* Consider "valid" remote routes applicable for
4126 * this VNI. */
4127 if (!(ri->type == ZEBRA_ROUTE_BGP
4128 && ri->sub_type == BGP_ROUTE_NORMAL))
4129 continue;
4130
60466a63 4131 if (bgp_nexthop_self(bgp, ri->attr->nexthop)) {
db0e1937
MK
4132
4133 char attr_str[BUFSIZ];
4134 char pbuf[PREFIX_STRLEN];
4135
4136 bgp_dump_attr(ri->attr, attr_str,
4137 BUFSIZ);
4138
4139 if (bgp_debug_update(ri->peer, &rn->p,
4140 NULL, 1))
4141 zlog_debug(
b682f6de 4142 "%u: prefix %s with attr %s - DENIED due to martian or self nexthop",
db0e1937
MK
4143 bgp->vrf_id,
4144 prefix2str(
60466a63 4145 &rn->p, pbuf,
db0e1937
MK
4146 sizeof(pbuf)),
4147 attr_str);
4148
4149 bgp_evpn_unimport_route(bgp, afi, safi,
4150 &rn->p, ri);
4151
60466a63
QY
4152 bgp_rib_remove(rn, ri, ri->peer, afi,
4153 safi);
db0e1937 4154 }
db0e1937
MK
4155 }
4156 }
4157 }
4158
4159 return 0;
4160}
4161
128ea8ab 4162/*
4163 * Handle del of a local MACIP.
4164 */
d62a17ae 4165int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
4166 struct ipaddr *ip)
128ea8ab 4167{
d62a17ae 4168 struct bgpevpn *vpn;
4169 struct prefix_evpn p;
128ea8ab 4170
d62a17ae 4171 if (!bgp->vnihash) {
4172 zlog_err("%u: VNI hash not created", bgp->vrf_id);
4173 return -1;
4174 }
128ea8ab 4175
d62a17ae 4176 /* Lookup VNI hash - should exist. */
4177 vpn = bgp_evpn_lookup_vni(bgp, vni);
4178 if (!vpn || !is_vni_live(vpn)) {
4179 zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP DEL",
4180 bgp->vrf_id, vni, vpn ? "not live" : "not found");
4181 return -1;
4182 }
128ea8ab 4183
d62a17ae 4184 /* Remove EVPN type-2 route and schedule for processing. */
4185 build_evpn_type2_prefix(&p, mac, ip);
4186 delete_evpn_route(bgp, vpn, &p);
128ea8ab 4187
d62a17ae 4188 return 0;
128ea8ab 4189}
4190
4191/*
4192 * Handle add of a local MACIP.
4193 */
d62a17ae 4194int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
1a98c087 4195 struct ipaddr *ip, u_char flags)
128ea8ab 4196{
d62a17ae 4197 struct bgpevpn *vpn;
4198 struct prefix_evpn p;
128ea8ab 4199
d62a17ae 4200 if (!bgp->vnihash) {
4201 zlog_err("%u: VNI hash not created", bgp->vrf_id);
4202 return -1;
4203 }
128ea8ab 4204
d62a17ae 4205 /* Lookup VNI hash - should exist. */
4206 vpn = bgp_evpn_lookup_vni(bgp, vni);
4207 if (!vpn || !is_vni_live(vpn)) {
4208 zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP ADD",
4209 bgp->vrf_id, vni, vpn ? "not live" : "not found");
4210 return -1;
4211 }
128ea8ab 4212
d62a17ae 4213 /* Create EVPN type-2 route and schedule for processing. */
4214 build_evpn_type2_prefix(&p, mac, ip);
1a98c087 4215 if (update_evpn_route(bgp, vpn, &p, flags)) {
d62a17ae 4216 char buf[ETHER_ADDR_STRLEN];
4217 char buf2[INET6_ADDRSTRLEN];
128ea8ab 4218
d62a17ae 4219 zlog_err(
ead40654 4220 "%u:Failed to create Type-2 route, VNI %u %s MAC %s IP %s (flags: 0x%x)",
1a98c087 4221 bgp->vrf_id, vpn->vni,
996c9314
LB
4222 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY)
4223 ? "sticky gateway"
4224 : "",
d62a17ae 4225 prefix_mac2str(mac, buf, sizeof(buf)),
996c9314 4226 ipaddr2str(ip, buf2, sizeof(buf2)), flags);
d62a17ae 4227 return -1;
4228 }
128ea8ab 4229
d62a17ae 4230 return 0;
128ea8ab 4231}
4232
6a8657d0
MK
4233static void link_l2vni_hash_to_l3vni(struct hash_backet *backet,
4234 struct bgp *bgp_vrf)
4235{
4236 struct bgpevpn *vpn = NULL;
4237 struct bgp *bgp_def = NULL;
4238
4239 bgp_def = bgp_get_default();
4240 assert(bgp_def);
4241
4242 vpn = (struct bgpevpn *)backet->data;
4243 if (vpn->tenant_vrf_id == bgp_vrf->vrf_id)
4244 bgpevpn_link_to_l3vni(vpn);
4245}
4246
996c9314
LB
4247int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac,
4248 struct in_addr originator_ip, int filter)
fe1dc5a3
MK
4249{
4250 struct bgp *bgp_vrf = NULL; /* bgp VRF instance */
4251 struct bgp *bgp_def = NULL; /* default bgp instance */
f1f8b53c
MK
4252 struct listnode *node = NULL;
4253 struct bgpevpn *vpn = NULL;
fe1dc5a3
MK
4254 as_t as = 0;
4255
4256 /* get the default instamce - required to get the AS number for VRF
523cafc4 4257 * auto-creatio
4258 */
fe1dc5a3
MK
4259 bgp_def = bgp_get_default();
4260 if (!bgp_def) {
996c9314
LB
4261 zlog_err(
4262 "Cannot process L3VNI %u ADD - default BGP instance not yet created",
4263 l3vni);
fe1dc5a3
MK
4264 return -1;
4265 }
4266 as = bgp_def->as;
4267
4268 /* if the BGP vrf instance doesnt exist - create one */
0b5131c9 4269 bgp_vrf = bgp_lookup_by_name(vrf_id_to_name(vrf_id));
fe1dc5a3
MK
4270 if (!bgp_vrf) {
4271
4272 int ret = 0;
4273
4274 ret = bgp_get(&bgp_vrf, &as, vrf_id_to_name(vrf_id),
4275 BGP_INSTANCE_TYPE_VRF);
4276 switch (ret) {
4277 case BGP_ERR_MULTIPLE_INSTANCE_NOT_SET:
4278 zlog_err("'bgp multiple-instance' not present\n");
4279 return -1;
4280 case BGP_ERR_AS_MISMATCH:
4281 zlog_err("BGP is already running; AS is %u\n", as);
4282 return -1;
4283 case BGP_ERR_INSTANCE_MISMATCH:
4284 zlog_err("BGP instance name and AS number mismatch\n");
4285 return -1;
4286 }
4287
4288 /* mark as auto created */
4289 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_AUTO);
4290 }
4291
4292 /* associate with l3vni */
4293 bgp_vrf->l3vni = l3vni;
4294
4295 /* set the router mac - to be used in mac-ip routes for this vrf */
4296 memcpy(&bgp_vrf->rmac, rmac, sizeof(struct ethaddr));
4297
b67a60d2 4298 /* set the originator ip */
4299 bgp_vrf->originator_ip = originator_ip;
4300
c48d9f5f
MK
4301 /* set the right filter - are we using l3vni only for prefix routes? */
4302 if (filter)
4303 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY);
4304
c581d8b0
MK
4305 /* auto derive RD/RT */
4306 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD))
4307 evpn_auto_rt_import_add_for_vrf(bgp_vrf);
4308 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD))
4309 evpn_auto_rt_export_add_for_vrf(bgp_vrf);
676f83b9 4310 bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf);
fe1dc5a3 4311
6a8657d0
MK
4312 /* link all corresponding l2vnis */
4313 hash_iterate(bgp_def->vnihash,
996c9314
LB
4314 (void (*)(struct hash_backet *,
4315 void *))link_l2vni_hash_to_l3vni,
6a8657d0
MK
4316 bgp_vrf);
4317
c48d9f5f
MK
4318 /* Only update all corresponding type-2 routes if we are advertising two
4319 * labels along with type-2 routes
4320 */
4321 if (!filter)
4322 for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn))
4323 update_routes_for_vni(bgp_def, vpn);
fe1dc5a3 4324
06d2e8f3
MK
4325 /* advertise type-5 routes if needed */
4326 update_advertise_vrf_routes(bgp_vrf);
4327
5ba238b7
MK
4328 /* install all remote routes belonging to this l3vni into correspondng
4329 * vrf */
4330 install_routes_for_vrf(bgp_vrf);
fe1dc5a3
MK
4331
4332 return 0;
4333}
4334
996c9314 4335int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id)
fe1dc5a3
MK
4336{
4337 struct bgp *bgp_vrf = NULL; /* bgp vrf instance */
f1f8b53c
MK
4338 struct bgp *bgp_def = NULL; /* default bgp instance */
4339 struct listnode *node = NULL;
4340 struct bgpevpn *vpn = NULL;
fe1dc5a3
MK
4341
4342 bgp_vrf = bgp_lookup_by_vrf_id(vrf_id);
4343 if (!bgp_vrf) {
996c9314
LB
4344 zlog_err(
4345 "Cannot process L3VNI %u Del - Could not find BGP instance",
4346 l3vni);
fe1dc5a3
MK
4347 return -1;
4348 }
4349
f1f8b53c
MK
4350 bgp_def = bgp_get_default();
4351 if (!bgp_def) {
996c9314
LB
4352 zlog_err(
4353 "Cannot process L3VNI %u Del - Could not find default BGP instance",
4354 l3vni);
f1f8b53c
MK
4355 return -1;
4356 }
4357
1eb88002 4358 /* unimport remote routes from VRF, if it is AUTO vrf bgp_delete will
523cafc4 4359 * take care of uninstalling the routes from zebra
4360 */
1eb88002
MK
4361 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_AUTO))
4362 uninstall_routes_for_vrf(bgp_vrf);
5ba238b7 4363
06d2e8f3
MK
4364 /* delete/withdraw all type-5 routes */
4365 delete_withdraw_vrf_routes(bgp_vrf);
4366
fe1dc5a3
MK
4367 /* remove the l3vni from vrf instance */
4368 bgp_vrf->l3vni = 0;
4369
4370 /* remove the Rmac from the BGP vrf */
4371 memset(&bgp_vrf->rmac, 0, sizeof(struct ethaddr));
4372
c581d8b0 4373 /* delete RD/RT */
23a06e11 4374 if (bgp_vrf->vrf_import_rtl && !list_isempty(bgp_vrf->vrf_import_rtl)) {
10ebe1ab 4375 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf);
5ba238b7 4376 list_delete_all_node(bgp_vrf->vrf_import_rtl);
23a06e11
MK
4377 }
4378 if (bgp_vrf->vrf_export_rtl && !list_isempty(bgp_vrf->vrf_export_rtl)) {
5ba238b7 4379 list_delete_all_node(bgp_vrf->vrf_export_rtl);
23a06e11 4380 }
fe1dc5a3 4381
f1f8b53c 4382 /* update all corresponding local mac-ip routes */
c48d9f5f
MK
4383 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY)) {
4384 for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn)) {
4385 UNSET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS);
4386 update_routes_for_vni(bgp_def, vpn);
4387 }
4388 }
fe1dc5a3
MK
4389
4390 /* Delete the instance if it was autocreated */
4391 if (CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_AUTO))
4392 bgp_delete(bgp_vrf);
4393
4394 return 0;
4395}
4396
128ea8ab 4397/*
4398 * Handle del of a local VNI.
4399 */
d62a17ae 4400int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni)
128ea8ab 4401{
d62a17ae 4402 struct bgpevpn *vpn;
128ea8ab 4403
d62a17ae 4404 if (!bgp->vnihash) {
4405 zlog_err("%u: VNI hash not created", bgp->vrf_id);
4406 return -1;
4407 }
128ea8ab 4408
d62a17ae 4409 /* Locate VNI hash */
4410 vpn = bgp_evpn_lookup_vni(bgp, vni);
4411 if (!vpn) {
4412 zlog_warn("%u: VNI hash entry for VNI %u not found at DEL",
4413 bgp->vrf_id, vni);
4414 return 0;
4415 }
128ea8ab 4416
d62a17ae 4417 /* Remove all local EVPN routes and schedule for processing (to
4418 * withdraw from peers).
4419 */
4420 delete_routes_for_vni(bgp, vpn);
128ea8ab 4421
db0e1937
MK
4422 /*
4423 * tunnel is no longer active, del tunnel ip address from tip_hash
4424 */
4425 bgp_tip_del(bgp, &vpn->originator_ip);
4426
d62a17ae 4427 /* Clear "live" flag and see if hash needs to be freed. */
4428 UNSET_FLAG(vpn->flags, VNI_FLAG_LIVE);
4429 if (!is_vni_configured(vpn))
4430 bgp_evpn_free(bgp, vpn);
128ea8ab 4431
d62a17ae 4432 return 0;
128ea8ab 4433}
4434
4435/*
d1911c26 4436 * Handle add (or update) of a local VNI. The VNI changes we care
4437 * about are for the local-tunnel-ip and the (tenant) VRF.
128ea8ab 4438 */
d62a17ae 4439int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
996c9314 4440 struct in_addr originator_ip, vrf_id_t tenant_vrf_id)
d62a17ae 4441{
4442 struct bgpevpn *vpn;
4443 struct prefix_evpn p;
4444
4445 if (!bgp->vnihash) {
4446 zlog_err("%u: VNI hash not created", bgp->vrf_id);
4447 return -1;
4448 }
4449
4450 /* Lookup VNI. If present and no change, exit. */
4451 vpn = bgp_evpn_lookup_vni(bgp, vni);
ddd16ed5 4452 if (vpn) {
29c53922 4453
d1911c26 4454 if (is_vni_live(vpn)
4455 && IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip)
4456 && vpn->tenant_vrf_id == tenant_vrf_id)
4457 /* Probably some other param has changed that we don't
4458 * care about. */
4459 return 0;
4460
4461 /* Update tenant_vrf_id if it has changed. */
6a8657d0
MK
4462 if (vpn->tenant_vrf_id != tenant_vrf_id) {
4463 bgpevpn_unlink_from_l3vni(vpn);
29c53922 4464 vpn->tenant_vrf_id = tenant_vrf_id;
6a8657d0
MK
4465 bgpevpn_link_to_l3vni(vpn);
4466 }
29c53922 4467
d1911c26 4468 /* If tunnel endpoint IP has changed, update (and delete prior
4469 * type-3 route, if needed.)
4470 */
4471 if (!IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip))
4472 handle_tunnel_ip_change(bgp, vpn, originator_ip);
d62a17ae 4473
d1911c26 4474 /* Update all routes with new endpoint IP and/or export RT
4475 * for VRFs
4476 */
4477 if (is_vni_live(vpn))
4478 update_routes_for_vni(bgp, vpn);
d62a17ae 4479 }
4480
4481 /* Create or update as appropriate. */
4482 if (!vpn) {
29c53922 4483 vpn = bgp_evpn_new(bgp, vni, originator_ip, tenant_vrf_id);
d62a17ae 4484 if (!vpn) {
4485 zlog_err(
4486 "%u: Failed to allocate VNI entry for VNI %u - at Add",
4487 bgp->vrf_id, vni);
4488 return -1;
4489 }
4490 }
4491
db0e1937 4492 /* if the VNI is live already, there is nothing more to do */
ddd16ed5
MK
4493 if (is_vni_live(vpn))
4494 return 0;
4495
d62a17ae 4496 /* Mark as "live" */
4497 SET_FLAG(vpn->flags, VNI_FLAG_LIVE);
4498
db0e1937
MK
4499 /* tunnel is now active, add tunnel-ip to db */
4500 bgp_tip_add(bgp, &originator_ip);
4501
4502 /* filter routes as nexthop database has changed */
4503 bgp_filter_evpn_routes_upon_martian_nh_change(bgp);
4504
d62a17ae 4505 /* Create EVPN type-3 route and schedule for processing. */
4506 build_evpn_type3_prefix(&p, vpn->originator_ip);
4507 if (update_evpn_route(bgp, vpn, &p, 0)) {
4508 zlog_err("%u: Type3 route creation failure for VNI %u",
4509 bgp->vrf_id, vni);
4510 return -1;
4511 }
4512
4513 /* If we have learnt and retained remote routes (VTEPs, MACs) for this
4514 * VNI,
4515 * install them.
4516 */
4517 install_routes_for_vni(bgp, vpn);
4518
d7d97010
MK
4519 /* If we are advertising gateway mac-ip
4520 It needs to be conveyed again to zebra */
4521 bgp_zebra_advertise_gw_macip(bgp, vpn->advertise_gw_macip, vpn->vni);
4522
d62a17ae 4523 return 0;
b18825eb 4524}
14c1a7bf 4525
7724c0a1 4526/*
4527 * Cleanup EVPN information on disable - Need to delete and withdraw
4528 * EVPN routes from peers.
4529 */
d62a17ae 4530void bgp_evpn_cleanup_on_disable(struct bgp *bgp)
7724c0a1 4531{
9d303b37
DL
4532 hash_iterate(bgp->vnihash, (void (*)(struct hash_backet *,
4533 void *))cleanup_vni_on_disable,
4534 bgp);
7724c0a1 4535}
4536
14c1a7bf 4537/*
4538 * Cleanup EVPN information - invoked at the time of bgpd exit or when the
4539 * BGP instance (default) is being freed.
4540 */
d62a17ae 4541void bgp_evpn_cleanup(struct bgp *bgp)
14c1a7bf 4542{
d62a17ae 4543 if (bgp->vnihash)
9d303b37
DL
4544 hash_iterate(bgp->vnihash, (void (*)(struct hash_backet *,
4545 void *))free_vni_entry,
4546 bgp);
d62a17ae 4547 if (bgp->import_rt_hash)
4548 hash_free(bgp->import_rt_hash);
4549 bgp->import_rt_hash = NULL;
10ebe1ab
MK
4550 if (bgp->vrf_import_rt_hash)
4551 hash_free(bgp->vrf_import_rt_hash);
4552 bgp->vrf_import_rt_hash = NULL;
d62a17ae 4553 if (bgp->vnihash)
4554 hash_free(bgp->vnihash);
4555 bgp->vnihash = NULL;
c581d8b0 4556 if (bgp->vrf_import_rtl)
bb7a24ab 4557 list_delete_and_null(&bgp->vrf_import_rtl);
c581d8b0 4558 if (bgp->vrf_export_rtl)
bb7a24ab 4559 list_delete_and_null(&bgp->vrf_export_rtl);
6a8657d0 4560 if (bgp->l2vnis)
bb7a24ab 4561 list_delete_and_null(&bgp->l2vnis);
676f83b9 4562 bf_release_index(bm->rd_idspace, bgp->vrf_rd_id);
14c1a7bf 4563}
4564
4565/*
4566 * Initialization for EVPN
4567 * Create
4568 * VNI hash table
4569 * hash for RT to VNI
676f83b9 4570 * assign a unique rd id for auto derivation of vrf_prd
14c1a7bf 4571 */
d62a17ae 4572void bgp_evpn_init(struct bgp *bgp)
4573{
4574 bgp->vnihash =
4575 hash_create(vni_hash_key_make, vni_hash_cmp, "BGP VNI Hash");
4576 bgp->import_rt_hash =
4577 hash_create(import_rt_hash_key_make, import_rt_hash_cmp,
4578 "BGP Import RT Hash");
10ebe1ab
MK
4579 bgp->vrf_import_rt_hash =
4580 hash_create(vrf_import_rt_hash_key_make, vrf_import_rt_hash_cmp,
4581 "BGP VRF Import RT Hash");
c581d8b0
MK
4582 bgp->vrf_import_rtl = list_new();
4583 bgp->vrf_import_rtl->cmp =
4584 (int (*)(void *, void *))evpn_route_target_cmp;
4585
4586 bgp->vrf_export_rtl = list_new();
4587 bgp->vrf_export_rtl->cmp =
4588 (int (*)(void *, void *))evpn_route_target_cmp;
6a8657d0 4589 bgp->l2vnis = list_new();
996c9314 4590 bgp->l2vnis->cmp = (int (*)(void *, void *))vni_hash_cmp;
676f83b9 4591 bf_assign_index(bm->rd_idspace, bgp->vrf_rd_id);
14c1a7bf 4592}
10ebe1ab
MK
4593
4594void bgp_evpn_vrf_delete(struct bgp *bgp_vrf)
4595{
4596 bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf);
4597}