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