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