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