]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_evpn.c
bgpd: handle export rt change for vrf
[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
95/*
96 * Make import route target hash key.
97 */
d62a17ae 98static unsigned int import_rt_hash_key_make(void *p)
14c1a7bf 99{
d62a17ae 100 struct irt_node *irt = p;
101 char *pnt = irt->rt.val;
102 unsigned int key = 0;
103 int c = 0;
14c1a7bf 104
d62a17ae 105 key += pnt[c];
106 key += pnt[c + 1];
107 key += pnt[c + 2];
108 key += pnt[c + 3];
109 key += pnt[c + 4];
110 key += pnt[c + 5];
111 key += pnt[c + 6];
112 key += pnt[c + 7];
14c1a7bf 113
d62a17ae 114 return (key);
14c1a7bf 115}
116
117/*
118 * Comparison function for import rt hash
119 */
d62a17ae 120static int import_rt_hash_cmp(const void *p1, const void *p2)
14c1a7bf 121{
d62a17ae 122 const struct irt_node *irt1 = p1;
123 const struct irt_node *irt2 = p2;
14c1a7bf 124
d62a17ae 125 if (irt1 == NULL && irt2 == NULL)
126 return 1;
14c1a7bf 127
d62a17ae 128 if (irt1 == NULL || irt2 == NULL)
129 return 0;
14c1a7bf 130
d62a17ae 131 return (memcmp(irt1->rt.val, irt2->rt.val, ECOMMUNITY_SIZE) == 0);
14c1a7bf 132}
133
7724c0a1 134/*
128ea8ab 135 * Create a new import_rt
136 */
d62a17ae 137static struct irt_node *import_rt_new(struct bgp *bgp,
138 struct ecommunity_val *rt)
128ea8ab 139{
d62a17ae 140 struct irt_node *irt;
128ea8ab 141
d62a17ae 142 if (!bgp)
143 return NULL;
128ea8ab 144
d62a17ae 145 irt = XCALLOC(MTYPE_BGP_EVPN_IMPORT_RT, sizeof(struct irt_node));
146 if (!irt)
147 return NULL;
128ea8ab 148
d62a17ae 149 irt->rt = *rt;
150 irt->vnis = list_new();
128ea8ab 151
d62a17ae 152 /* Add to hash */
153 if (!hash_get(bgp->import_rt_hash, irt, hash_alloc_intern)) {
154 XFREE(MTYPE_BGP_EVPN_IMPORT_RT, irt);
155 return NULL;
156 }
128ea8ab 157
d62a17ae 158 return irt;
128ea8ab 159}
160
161/*
162 * Free the import rt node
7724c0a1 163 */
d62a17ae 164static void import_rt_free(struct bgp *bgp, struct irt_node *irt)
7724c0a1 165{
d62a17ae 166 hash_release(bgp->import_rt_hash, irt);
167 XFREE(MTYPE_BGP_EVPN_IMPORT_RT, irt);
7724c0a1 168}
169
14c1a7bf 170/*
128ea8ab 171 * Function to lookup Import RT node - used to map a RT to set of
172 * VNIs importing routes with that RT.
173 */
d62a17ae 174static struct irt_node *lookup_import_rt(struct bgp *bgp,
175 struct ecommunity_val *rt)
128ea8ab 176{
d62a17ae 177 struct irt_node *irt;
178 struct irt_node tmp;
128ea8ab 179
d62a17ae 180 memset(&tmp, 0, sizeof(struct irt_node));
181 memcpy(&tmp.rt, rt, ECOMMUNITY_SIZE);
182 irt = hash_lookup(bgp->import_rt_hash, &tmp);
183 return irt;
128ea8ab 184}
185
186/*
187 * Is specified VNI present on the RT's list of "importing" VNIs?
188 */
d62a17ae 189static int is_vni_present_in_irt_vnis(struct list *vnis, struct bgpevpn *vpn)
128ea8ab 190{
d62a17ae 191 struct listnode *node, *nnode;
192 struct bgpevpn *tmp_vpn;
128ea8ab 193
d62a17ae 194 for (ALL_LIST_ELEMENTS(vnis, node, nnode, tmp_vpn)) {
195 if (tmp_vpn == vpn)
196 return 1;
197 }
128ea8ab 198
d62a17ae 199 return 0;
128ea8ab 200}
201
202/*
203 * Compare Route Targets.
204 */
d62a17ae 205static int evpn_route_target_cmp(struct ecommunity *ecom1,
206 struct ecommunity *ecom2)
128ea8ab 207{
d62a17ae 208 if (ecom1 && !ecom2)
209 return -1;
128ea8ab 210
d62a17ae 211 if (!ecom1 && ecom2)
212 return 1;
128ea8ab 213
d62a17ae 214 if (!ecom1 && !ecom2)
215 return 0;
128ea8ab 216
d62a17ae 217 if (ecom1->str && !ecom2->str)
218 return -1;
128ea8ab 219
d62a17ae 220 if (!ecom1->str && ecom2->str)
221 return 1;
128ea8ab 222
d62a17ae 223 if (!ecom1->str && !ecom2->str)
224 return 0;
128ea8ab 225
d62a17ae 226 return strcmp(ecom1->str, ecom2->str);
128ea8ab 227}
228
229/*
230 * Mask off global-admin field of specified extended community (RT),
231 * just retain the local-admin field.
232 */
d62a17ae 233static inline void mask_ecom_global_admin(struct ecommunity_val *dst,
234 struct ecommunity_val *src)
128ea8ab 235{
d62a17ae 236 u_char type;
128ea8ab 237
d62a17ae 238 type = src->val[0];
239 dst->val[0] = 0;
240 if (type == ECOMMUNITY_ENCODE_AS) {
241 dst->val[2] = dst->val[3] = 0;
242 } else if (type == ECOMMUNITY_ENCODE_AS4
243 || type == ECOMMUNITY_ENCODE_IP) {
244 dst->val[2] = dst->val[3] = 0;
245 dst->val[4] = dst->val[5] = 0;
246 }
128ea8ab 247}
248
249/*
250 * Map one RT to specified VNI.
14c1a7bf 251 */
d62a17ae 252static void map_vni_to_rt(struct bgp *bgp, struct bgpevpn *vpn,
253 struct ecommunity_val *eval)
128ea8ab 254{
d62a17ae 255 struct irt_node *irt;
256 struct ecommunity_val eval_tmp;
128ea8ab 257
d62a17ae 258 /* If using "automatic" RT, we only care about the local-admin
259 * sub-field.
260 * This is to facilitate using VNI as the RT for EBGP peering too.
261 */
262 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
263 if (!is_import_rt_configured(vpn))
264 mask_ecom_global_admin(&eval_tmp, eval);
128ea8ab 265
d62a17ae 266 irt = lookup_import_rt(bgp, &eval_tmp);
267 if (irt && irt->vnis)
268 if (is_vni_present_in_irt_vnis(irt->vnis, vpn))
269 /* Already mapped. */
270 return;
128ea8ab 271
d62a17ae 272 if (!irt) {
273 irt = import_rt_new(bgp, &eval_tmp);
274 assert(irt);
275 }
128ea8ab 276
d62a17ae 277 /* Add VNI to the hash list for this RT. */
278 listnode_add(irt->vnis, vpn);
128ea8ab 279}
280
281/*
282 * Unmap specified VNI from specified RT. If there are no other
283 * VNIs for this RT, then the RT hash is deleted.
284 */
d62a17ae 285static void unmap_vni_from_rt(struct bgp *bgp, struct bgpevpn *vpn,
286 struct irt_node *irt)
14c1a7bf 287{
d62a17ae 288 /* Delete VNI from hash list for this RT. */
289 listnode_delete(irt->vnis, vpn);
290 if (!listnode_head(irt->vnis)) {
acdf5e25 291 list_delete_and_null(&irt->vnis);
d62a17ae 292 import_rt_free(bgp, irt);
293 }
14c1a7bf 294}
295
128ea8ab 296/*
297 * Create RT extended community automatically from passed information:
298 * of the form AS:VNI.
299 * NOTE: We use only the lower 16 bits of the AS. This is sufficient as
300 * the need is to get a RT value that will be unique across different
301 * VNIs but the same across routers (in the same AS) for a particular
302 * VNI.
303 */
c581d8b0 304static void form_auto_rt(struct bgp *bgp, vni_t vni, struct list *rtl)
128ea8ab 305{
d62a17ae 306 struct ecommunity_val eval;
307 struct ecommunity *ecomadd;
128ea8ab 308
c581d8b0 309 encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
128ea8ab 310
d62a17ae 311 ecomadd = ecommunity_new();
312 ecommunity_add_val(ecomadd, &eval);
313 listnode_add_sort(rtl, ecomadd);
128ea8ab 314}
14c1a7bf 315
316/*
128ea8ab 317 * Derive RD and RT for a VNI automatically. Invoked at the time of
318 * creation of a VNI.
319 */
d62a17ae 320static void derive_rd_rt_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 321{
d62a17ae 322 bgp_evpn_derive_auto_rd(bgp, vpn);
323 bgp_evpn_derive_auto_rt_import(bgp, vpn);
324 bgp_evpn_derive_auto_rt_export(bgp, vpn);
128ea8ab 325}
326
327/*
328 * Add (update) or delete MACIP from zebra.
14c1a7bf 329 */
d62a17ae 330static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
331 struct prefix_evpn *p,
332 struct in_addr remote_vtep_ip, int add,
333 u_char sticky)
334{
335 struct stream *s;
336 int ipa_len;
337 char buf1[ETHER_ADDR_STRLEN];
338 char buf2[INET6_ADDRSTRLEN];
339 char buf3[INET6_ADDRSTRLEN];
340
341 /* Check socket. */
342 if (!zclient || zclient->sock < 0)
343 return 0;
344
345 /* Don't try to register if Zebra doesn't know of this instance. */
346 if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
347 return 0;
348
349 s = zclient->obuf;
350 stream_reset(s);
351
421bb26a
MK
352 zclient_create_header(s, add ? ZEBRA_REMOTE_MACIP_ADD
353 : ZEBRA_REMOTE_MACIP_DEL,
354 bgp->vrf_id);
d62a17ae 355 stream_putl(s, vpn->vni);
28328ea9 356 stream_put(s, &p->prefix.mac.octet, ETH_ALEN); /* Mac Addr */
d62a17ae 357 /* IP address length and IP address, if any. */
358 if (IS_EVPN_PREFIX_IPADDR_NONE(p))
359 stream_putl(s, 0);
360 else {
361 ipa_len = IS_EVPN_PREFIX_IPADDR_V4(p) ? IPV4_MAX_BYTELEN
362 : IPV6_MAX_BYTELEN;
363 stream_putl(s, ipa_len);
364 stream_put(s, &p->prefix.ip.ip.addr, ipa_len);
365 }
366 stream_put_in_addr(s, &remote_vtep_ip);
367
368 /* TX MAC sticky status */
369 if (add)
370 stream_putc(s, sticky);
371
372 stream_putw_at(s, 0, stream_get_endp(s));
373
374 if (bgp_debug_zebra(NULL))
375 zlog_debug("Tx %s MACIP, VNI %u %sMAC %s IP %s remote VTEP %s",
376 add ? "ADD" : "DEL", vpn->vni,
377 sticky ? "sticky " : "",
378 prefix_mac2str(&p->prefix.mac, buf1, sizeof(buf1)),
379 ipaddr2str(&p->prefix.ip, buf3, sizeof(buf3)),
380 inet_ntop(AF_INET, &remote_vtep_ip, buf2,
381 sizeof(buf2)));
382
383 return zclient_send_message(zclient);
7ef5a232 384}
b18825eb 385
128ea8ab 386/*
387 * Add (update) or delete remote VTEP from zebra.
388 */
d62a17ae 389static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
390 struct prefix_evpn *p, int add)
128ea8ab 391{
d62a17ae 392 struct stream *s;
128ea8ab 393
d62a17ae 394 /* Check socket. */
395 if (!zclient || zclient->sock < 0)
396 return 0;
128ea8ab 397
d62a17ae 398 /* Don't try to register if Zebra doesn't know of this instance. */
399 if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
400 return 0;
128ea8ab 401
d62a17ae 402 s = zclient->obuf;
403 stream_reset(s);
128ea8ab 404
421bb26a
MK
405 zclient_create_header(s, add ? ZEBRA_REMOTE_VTEP_ADD
406 : ZEBRA_REMOTE_VTEP_DEL,
407 bgp->vrf_id);
d62a17ae 408 stream_putl(s, vpn->vni);
409 if (IS_EVPN_PREFIX_IPADDR_V4(p))
410 stream_put_in_addr(s, &p->prefix.ip.ipaddr_v4);
411 else if (IS_EVPN_PREFIX_IPADDR_V6(p)) {
412 zlog_err(
413 "Bad remote IP when trying to %s remote VTEP for VNI %u",
414 add ? "ADD" : "DEL", vpn->vni);
415 return -1;
416 }
128ea8ab 417
d62a17ae 418 stream_putw_at(s, 0, stream_get_endp(s));
128ea8ab 419
d62a17ae 420 if (bgp_debug_zebra(NULL))
421 zlog_debug("Tx %s Remote VTEP, VNI %u remote VTEP %s",
422 add ? "ADD" : "DEL", vpn->vni,
423 inet_ntoa(p->prefix.ip.ipaddr_v4));
128ea8ab 424
d62a17ae 425 return zclient_send_message(zclient);
128ea8ab 426}
427
428/*
429 * Build extended communities for EVPN route. RT and ENCAP are
430 * applicable to all routes.
431 */
d62a17ae 432static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr)
128ea8ab 433{
d62a17ae 434 struct ecommunity ecom_encap;
435 struct ecommunity ecom_sticky;
436 struct ecommunity_val eval;
437 struct ecommunity_val eval_sticky;
438 bgp_encap_types tnl_type;
439 struct listnode *node, *nnode;
440 struct ecommunity *ecom;
441 u_int32_t seqnum;
7a3e76f1 442 struct list *vrf_export_rtl = NULL;
128ea8ab 443
d62a17ae 444 /* Encap */
445 tnl_type = BGP_ENCAP_TYPE_VXLAN;
446 memset(&ecom_encap, 0, sizeof(ecom_encap));
447 encode_encap_extcomm(tnl_type, &eval);
448 ecom_encap.size = 1;
449 ecom_encap.val = (u_int8_t *)eval.val;
128ea8ab 450
d62a17ae 451 /* Add Encap */
452 attr->ecommunity = ecommunity_dup(&ecom_encap);
128ea8ab 453
7a3e76f1 454 /* Add the export RTs for L2VNI */
d62a17ae 455 for (ALL_LIST_ELEMENTS(vpn->export_rtl, node, nnode, ecom))
456 attr->ecommunity = ecommunity_merge(attr->ecommunity, ecom);
128ea8ab 457
7a3e76f1
MK
458 /* Add the export RTs for L3VNI */
459 vrf_export_rtl = bgpevpn_get_vrf_export_rtl(vpn);
f1f8b53c
MK
460 if (vrf_export_rtl) {
461 for (ALL_LIST_ELEMENTS(vrf_export_rtl, node, nnode, ecom))
462 attr->ecommunity = ecommunity_merge(attr->ecommunity,
463 ecom);
464 }
7a3e76f1 465
d62a17ae 466 if (attr->sticky) {
467 seqnum = 0;
468 memset(&ecom_sticky, 0, sizeof(ecom_sticky));
469 encode_mac_mobility_extcomm(1, seqnum, &eval_sticky);
470 ecom_sticky.size = 1;
471 ecom_sticky.val = (u_int8_t *)eval_sticky.val;
472 attr->ecommunity =
473 ecommunity_merge(attr->ecommunity, &ecom_sticky);
474 }
c85c03c7 475
d62a17ae 476 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
128ea8ab 477}
478
479/*
480 * Add MAC mobility extended community to attribute.
481 */
d62a17ae 482static void add_mac_mobility_to_attr(u_int32_t seq_num, struct attr *attr)
483{
484 struct ecommunity ecom_tmp;
485 struct ecommunity_val eval;
421bb26a 486 u_int8_t *ecom_val_ptr;
d62a17ae 487 int i;
488 u_int8_t *pnt;
489 int type = 0;
490 int sub_type = 0;
491
492 /* Build MM */
493 encode_mac_mobility_extcomm(0, seq_num, &eval);
494
495 /* Find current MM ecommunity */
421bb26a 496 ecom_val_ptr = NULL;
d62a17ae 497
498 if (attr->ecommunity) {
499 for (i = 0; i < attr->ecommunity->size; i++) {
500 pnt = attr->ecommunity->val + (i * 8);
501 type = *pnt++;
502 sub_type = *pnt++;
503
504 if (type == ECOMMUNITY_ENCODE_EVPN
505 && sub_type
506 == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY) {
421bb26a
MK
507 ecom_val_ptr =
508 (u_int8_t *)(attr->ecommunity->val
509 + (i * 8));
d62a17ae 510 break;
511 }
512 }
513 }
514
515 /* Update the existing MM ecommunity */
421bb26a
MK
516 if (ecom_val_ptr) {
517 memcpy(ecom_val_ptr, eval.val, sizeof(char) * ECOMMUNITY_SIZE);
d62a17ae 518 }
519 /* Add MM to existing */
520 else {
521 memset(&ecom_tmp, 0, sizeof(ecom_tmp));
522 ecom_tmp.size = 1;
523 ecom_tmp.val = (u_int8_t *)eval.val;
524
525 attr->ecommunity =
526 ecommunity_merge(attr->ecommunity, &ecom_tmp);
527 }
128ea8ab 528}
529
530/* Install EVPN route into zebra. */
d62a17ae 531static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn,
532 struct prefix_evpn *p,
533 struct in_addr remote_vtep_ip, u_char sticky)
128ea8ab 534{
d62a17ae 535 int ret;
128ea8ab 536
d62a17ae 537 if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
538 ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip,
539 1, sticky);
540 else
541 ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 1);
128ea8ab 542
d62a17ae 543 return ret;
128ea8ab 544}
545
546/* Uninstall EVPN route from zebra. */
d62a17ae 547static int evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn,
548 struct prefix_evpn *p,
549 struct in_addr remote_vtep_ip)
128ea8ab 550{
d62a17ae 551 int ret;
128ea8ab 552
d62a17ae 553 if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
554 ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip,
555 0, 0);
556 else
557 ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 0);
128ea8ab 558
d62a17ae 559 return ret;
128ea8ab 560}
561
562/*
563 * Due to MAC mobility, the prior "local" best route has been supplanted
564 * by a "remote" best route. The prior route has to be deleted and withdrawn
565 * from peers.
566 */
d62a17ae 567static void evpn_delete_old_local_route(struct bgp *bgp, struct bgpevpn *vpn,
568 struct bgp_node *rn,
569 struct bgp_info *old_local)
128ea8ab 570{
d62a17ae 571 struct bgp_node *global_rn;
572 struct bgp_info *ri;
573 afi_t afi = AFI_L2VPN;
574 safi_t safi = SAFI_EVPN;
128ea8ab 575
d62a17ae 576 /* Locate route node in the global EVPN routing table. Note that
577 * this table is a 2-level tree (RD-level + Prefix-level) similar to
578 * L3VPN routes.
579 */
580 global_rn = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi,
581 (struct prefix *)&rn->p, &vpn->prd);
582 if (global_rn) {
583 /* Delete route entry in the global EVPN table. */
584 delete_evpn_route_entry(bgp, vpn, afi, safi, global_rn, &ri);
128ea8ab 585
d62a17ae 586 /* Schedule for processing - withdraws to peers happen from
587 * this table.
588 */
589 if (ri)
590 bgp_process(bgp, global_rn, afi, safi);
591 bgp_unlock_node(global_rn);
592 }
128ea8ab 593
d62a17ae 594 /* Delete route entry in the VNI route table, caller to remove. */
595 bgp_info_delete(rn, old_local);
128ea8ab 596}
597
598/*
599 * Calculate the best path for an EVPN route. Install/update best path in zebra,
600 * if appropriate.
601 */
d62a17ae 602static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
603 struct bgp_node *rn)
604{
605 struct bgp_info *old_select, *new_select;
606 struct bgp_info_pair old_and_new;
607 afi_t afi = AFI_L2VPN;
608 safi_t safi = SAFI_EVPN;
609 int ret = 0;
610
611 /* Compute the best path. */
612 bgp_best_selection(bgp, rn, &bgp->maxpaths[afi][safi], &old_and_new,
613 afi, safi);
614 old_select = old_and_new.old;
615 new_select = old_and_new.new;
616
617 /* If the best path hasn't changed - see if there is still something to
618 * update
619 * to zebra RIB.
620 */
621 if (old_select && old_select == new_select
622 && old_select->type == ZEBRA_ROUTE_BGP
623 && old_select->sub_type == BGP_ROUTE_NORMAL
624 && !CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR)
625 && !CHECK_FLAG(old_select->flags, BGP_INFO_ATTR_CHANGED)
626 && !bgp->addpath_tx_used[afi][safi]) {
627 if (bgp_zebra_has_route_changed(rn, old_select))
628 ret = evpn_zebra_install(bgp, vpn,
629 (struct prefix_evpn *)&rn->p,
630 old_select->attr->nexthop,
631 old_select->attr->sticky);
632 UNSET_FLAG(old_select->flags, BGP_INFO_MULTIPATH_CHG);
633 bgp_zebra_clear_route_change_flags(rn);
634 return ret;
635 }
636
637 /* If the user did a "clear" this flag will be set */
638 UNSET_FLAG(rn->flags, BGP_NODE_USER_CLEAR);
639
640 /* bestpath has changed; update relevant fields and install or uninstall
641 * into the zebra RIB.
642 */
643 if (old_select || new_select)
644 bgp_bump_version(rn);
645
646 if (old_select)
647 bgp_info_unset_flag(rn, old_select, BGP_INFO_SELECTED);
648 if (new_select) {
649 bgp_info_set_flag(rn, new_select, BGP_INFO_SELECTED);
650 bgp_info_unset_flag(rn, new_select, BGP_INFO_ATTR_CHANGED);
651 UNSET_FLAG(new_select->flags, BGP_INFO_MULTIPATH_CHG);
652 }
653
654 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
655 && new_select->sub_type == BGP_ROUTE_NORMAL) {
656 ret = evpn_zebra_install(bgp, vpn, (struct prefix_evpn *)&rn->p,
657 new_select->attr->nexthop,
658 new_select->attr->sticky);
659 /* If an old best existed and it was a "local" route, the only
660 * reason
661 * it would be supplanted is due to MAC mobility procedures. So,
662 * we
663 * need to do an implicit delete and withdraw that route from
664 * peers.
665 */
666 if (old_select && old_select->peer == bgp->peer_self
667 && old_select->type == ZEBRA_ROUTE_BGP
668 && old_select->sub_type == BGP_ROUTE_STATIC)
669 evpn_delete_old_local_route(bgp, vpn, rn, old_select);
670 } else {
671 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
672 && old_select->sub_type == BGP_ROUTE_NORMAL)
673 ret = evpn_zebra_uninstall(bgp, vpn,
674 (struct prefix_evpn *)&rn->p,
675 old_select->attr->nexthop);
676 }
677
678 /* Clear any route change flags. */
679 bgp_zebra_clear_route_change_flags(rn);
680
681 /* Reap old select bgp_info, if it has been removed */
682 if (old_select && CHECK_FLAG(old_select->flags, BGP_INFO_REMOVED))
683 bgp_info_reap(rn, old_select);
684
685 return ret;
128ea8ab 686}
687
c85c03c7 688
689/*
690 * Return true if the local ri for this rn has sticky set
691 */
d62a17ae 692static int evpn_route_is_sticky(struct bgp *bgp, struct bgp_node *rn)
c85c03c7 693{
d62a17ae 694 struct bgp_info *tmp_ri;
695 struct bgp_info *local_ri;
c85c03c7 696
d62a17ae 697 local_ri = NULL;
698 for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) {
699 if (tmp_ri->peer == bgp->peer_self
700 && tmp_ri->type == ZEBRA_ROUTE_BGP
701 && tmp_ri->sub_type == BGP_ROUTE_STATIC)
702 local_ri = tmp_ri;
703 }
c85c03c7 704
d62a17ae 705 if (!local_ri)
706 return 0;
c85c03c7 707
d62a17ae 708 return local_ri->attr->sticky;
c85c03c7 709}
710
128ea8ab 711/*
712 * Create or update EVPN route entry. This could be in the VNI route table
713 * or the global route table.
714 */
d62a17ae 715static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
716 afi_t afi, safi_t safi, struct bgp_node *rn,
717 struct attr *attr, int add, int vni_table,
1a98c087 718 struct bgp_info **ri, u_char flags)
d62a17ae 719{
720 struct bgp_info *tmp_ri;
721 struct bgp_info *local_ri, *remote_ri;
722 struct attr *attr_new;
723 mpls_label_t label = MPLS_INVALID_LABEL;
724 int route_change = 1;
725 u_char sticky = 0;
726
727 *ri = NULL;
728
729 /* See if this is an update of an existing route, or a new add. Also,
730 * identify if already known from remote, and if so, the one with the
731 * highest sequence number; this is only when adding to the VNI routing
732 * table.
733 */
734 local_ri = remote_ri = NULL;
735 for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next) {
736 if (tmp_ri->peer == bgp->peer_self
737 && tmp_ri->type == ZEBRA_ROUTE_BGP
738 && tmp_ri->sub_type == BGP_ROUTE_STATIC)
739 local_ri = tmp_ri;
740 if (vni_table) {
741 if (tmp_ri->type == ZEBRA_ROUTE_BGP
742 && tmp_ri->sub_type == BGP_ROUTE_NORMAL
743 && CHECK_FLAG(tmp_ri->flags, BGP_INFO_VALID)) {
744 if (!remote_ri)
745 remote_ri = tmp_ri;
746 else if (mac_mobility_seqnum(tmp_ri->attr)
747 > mac_mobility_seqnum(remote_ri->attr))
748 remote_ri = tmp_ri;
749 }
750 }
751 }
752
753 /* If route doesn't exist already, create a new one, if told to.
754 * Otherwise act based on whether the attributes of the route have
755 * changed or not.
756 */
757 if (!local_ri && !add)
758 return 0;
759
760 if (!local_ri) {
761 /* When learnt locally for the first time but already known from
762 * remote, we have to initiate appropriate MAC mobility steps.
763 * This
764 * is applicable when updating the VNI routing table.
1a98c087
MK
765 * We need to skip mobility steps for g/w macs (local mac on g/w
766 * SVI) advertised in EVPN.
767 * This will ensure that local routes are preferred for g/w macs
d62a17ae 768 */
1a98c087 769 if (remote_ri && !CHECK_FLAG(flags, ZEBRA_MAC_TYPE_GW)) {
d62a17ae 770 u_int32_t cur_seqnum;
771
772 /* Add MM extended community to route. */
773 cur_seqnum = mac_mobility_seqnum(remote_ri->attr);
774 add_mac_mobility_to_attr(cur_seqnum + 1, attr);
775 }
776
777 /* Add (or update) attribute to hash. */
778 attr_new = bgp_attr_intern(attr);
779
780 /* Extract MAC mobility sequence number, if any. */
781 attr_new->mm_seqnum =
782 bgp_attr_mac_mobility_seqnum(attr_new, &sticky);
783 attr_new->sticky = sticky;
784
785 /* Create new route with its attribute. */
786 tmp_ri = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0,
787 bgp->peer_self, attr_new, rn);
788 SET_FLAG(tmp_ri->flags, BGP_INFO_VALID);
789 bgp_info_extra_get(tmp_ri);
790
791 /* The VNI goes into the 'label' field of the route */
792 vni2label(vpn->vni, &label);
793
794 memcpy(&tmp_ri->extra->label, &label, BGP_LABEL_BYTES);
795 bgp_info_add(rn, tmp_ri);
796 } else {
797 tmp_ri = local_ri;
798 if (attrhash_cmp(tmp_ri->attr, attr)
799 && !CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED))
800 route_change = 0;
801 else {
802 /* The attribute has changed. */
803 /* Add (or update) attribute to hash. */
804 attr_new = bgp_attr_intern(attr);
805 bgp_info_set_flag(rn, tmp_ri, BGP_INFO_ATTR_CHANGED);
806
807 /* Restore route, if needed. */
808 if (CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED))
809 bgp_info_restore(rn, tmp_ri);
810
811 /* Unintern existing, set to new. */
812 bgp_attr_unintern(&tmp_ri->attr);
813 tmp_ri->attr = attr_new;
814 tmp_ri->uptime = bgp_clock();
815 }
816 }
817
818 /* Return back the route entry. */
819 *ri = tmp_ri;
820 return route_change;
128ea8ab 821}
822
823/*
824 * Create or update EVPN route (of type based on prefix) for specified VNI
825 * and schedule for processing.
826 */
d62a17ae 827static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
1a98c087 828 struct prefix_evpn *p, u_char flags)
128ea8ab 829{
d62a17ae 830 struct bgp_node *rn;
831 struct attr attr;
832 struct attr *attr_new;
833 struct bgp_info *ri;
834 afi_t afi = AFI_L2VPN;
835 safi_t safi = SAFI_EVPN;
836 int route_change;
128ea8ab 837
d62a17ae 838 memset(&attr, 0, sizeof(struct attr));
128ea8ab 839
d62a17ae 840 /* Build path-attribute for this route. */
841 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
842 attr.nexthop = vpn->originator_ip;
843 attr.mp_nexthop_global_in = vpn->originator_ip;
844 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
1a98c087 845 attr.sticky = CHECK_FLAG(flags, ZEBRA_MAC_TYPE_STICKY) ? 1 : 0;
128ea8ab 846
d62a17ae 847 /* Set up RT and ENCAP extended community. */
848 build_evpn_route_extcomm(vpn, &attr);
128ea8ab 849
d62a17ae 850 /* First, create (or fetch) route node within the VNI. */
851 /* NOTE: There is no RD here. */
852 rn = bgp_node_get(vpn->route_table, (struct prefix *)p);
128ea8ab 853
d62a17ae 854 /* Create or update route entry. */
855 route_change = update_evpn_route_entry(bgp, vpn, afi, safi, rn, &attr,
1a98c087 856 1, 1, &ri, flags);
d62a17ae 857 assert(ri);
858 attr_new = ri->attr;
128ea8ab 859
d62a17ae 860 /* Perform route selection; this is just to set the flags correctly
861 * as local route in the VNI always wins.
862 */
863 evpn_route_select_install(bgp, vpn, rn);
864 bgp_unlock_node(rn);
128ea8ab 865
d62a17ae 866 /* If this is a new route or some attribute has changed, export the
867 * route to the global table. The route will be advertised to peers
868 * from there. Note that this table is a 2-level tree (RD-level +
869 * Prefix-level) similar to L3VPN routes.
870 */
871 if (route_change) {
872 struct bgp_info *global_ri;
128ea8ab 873
d62a17ae 874 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
875 (struct prefix *)p, &vpn->prd);
876 update_evpn_route_entry(bgp, vpn, afi, safi, rn, attr_new, 1, 0,
1a98c087 877 &global_ri, flags);
128ea8ab 878
d62a17ae 879 /* Schedule for processing and unlock node. */
880 bgp_process(bgp, rn, afi, safi);
881 bgp_unlock_node(rn);
882 }
128ea8ab 883
d62a17ae 884 /* Unintern temporary. */
885 aspath_unintern(&attr.aspath);
128ea8ab 886
d62a17ae 887 return 0;
128ea8ab 888}
889
890/*
891 * Delete EVPN route entry. This could be in the VNI route table
892 * or the global route table.
893 */
d62a17ae 894static void delete_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
895 afi_t afi, safi_t safi, struct bgp_node *rn,
896 struct bgp_info **ri)
128ea8ab 897{
d62a17ae 898 struct bgp_info *tmp_ri;
128ea8ab 899
d62a17ae 900 *ri = NULL;
128ea8ab 901
d62a17ae 902 /* Now, find matching route. */
903 for (tmp_ri = rn->info; tmp_ri; tmp_ri = tmp_ri->next)
904 if (tmp_ri->peer == bgp->peer_self
905 && tmp_ri->type == ZEBRA_ROUTE_BGP
906 && tmp_ri->sub_type == BGP_ROUTE_STATIC)
907 break;
128ea8ab 908
d62a17ae 909 *ri = tmp_ri;
128ea8ab 910
d62a17ae 911 /* Mark route for delete. */
912 if (tmp_ri)
913 bgp_info_delete(rn, tmp_ri);
128ea8ab 914}
915
916/*
917 * Delete EVPN route (of type based on prefix) for specified VNI and
918 * schedule for processing.
919 */
d62a17ae 920static int delete_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
921 struct prefix_evpn *p)
922{
923 struct bgp_node *rn, *global_rn;
924 struct bgp_info *ri;
925 afi_t afi = AFI_L2VPN;
926 safi_t safi = SAFI_EVPN;
927
928 /* First, locate the route node within the VNI. If it doesn't exist,
929 * there
930 * is nothing further to do.
931 */
932 /* NOTE: There is no RD here. */
933 rn = bgp_node_lookup(vpn->route_table, (struct prefix *)p);
934 if (!rn)
935 return 0;
936
937 /* Next, locate route node in the global EVPN routing table. Note that
938 * this table is a 2-level tree (RD-level + Prefix-level) similar to
939 * L3VPN routes.
940 */
941 global_rn = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi,
942 (struct prefix *)p, &vpn->prd);
943 if (global_rn) {
944 /* Delete route entry in the global EVPN table. */
945 delete_evpn_route_entry(bgp, vpn, afi, safi, global_rn, &ri);
946
947 /* Schedule for processing - withdraws to peers happen from
948 * this table.
949 */
950 if (ri)
951 bgp_process(bgp, global_rn, afi, safi);
952 bgp_unlock_node(global_rn);
953 }
954
955 /* Delete route entry in the VNI route table. This can just be removed.
956 */
957 delete_evpn_route_entry(bgp, vpn, afi, safi, rn, &ri);
958 if (ri)
959 bgp_info_reap(rn, ri);
960 bgp_unlock_node(rn);
961
962 return 0;
128ea8ab 963}
964
965/*
966 * Update all type-2 (MACIP) local routes for this VNI - these should also
967 * be scheduled for advertise to peers.
968 */
d62a17ae 969static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
970{
971 afi_t afi;
972 safi_t safi;
973 struct bgp_node *rn;
974 struct bgp_info *ri;
975 struct attr attr;
976 struct attr attr_sticky;
977 struct attr *attr_new;
978
979 afi = AFI_L2VPN;
980 safi = SAFI_EVPN;
981 memset(&attr, 0, sizeof(struct attr));
982 memset(&attr_sticky, 0, sizeof(struct attr));
983
984 /* Build path-attribute - all type-2 routes for this VNI will share the
985 * same path attribute.
986 */
987 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
988 bgp_attr_default_set(&attr_sticky, BGP_ORIGIN_IGP);
989 attr.nexthop = vpn->originator_ip;
990 attr.mp_nexthop_global_in = vpn->originator_ip;
991 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
992 attr_sticky.nexthop = vpn->originator_ip;
993 attr_sticky.mp_nexthop_global_in = vpn->originator_ip;
994 attr_sticky.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
995 attr_sticky.sticky = 1;
996
997 /* Set up RT, ENCAP and sticky MAC extended community. */
998 build_evpn_route_extcomm(vpn, &attr);
999 build_evpn_route_extcomm(vpn, &attr_sticky);
1000
1001 /* Walk this VNI's route table and update local type-2 routes. For any
1002 * routes updated, update corresponding entry in the global table too.
1003 */
1004 for (rn = bgp_table_top(vpn->route_table); rn;
1005 rn = bgp_route_next(rn)) {
1006 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
1007 struct bgp_node *rd_rn;
1008 struct bgp_info *global_ri;
1009
1010 if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
1011 continue;
1012
1013 if (evpn_route_is_sticky(bgp, rn))
1014 update_evpn_route_entry(bgp, vpn, afi, safi, rn,
1a98c087 1015 &attr_sticky, 0, 1, &ri, 0);
d62a17ae 1016 else
1017 update_evpn_route_entry(bgp, vpn, afi, safi, rn, &attr,
1a98c087 1018 0, 1, &ri, 0);
d62a17ae 1019
1020 /* If a local route exists for this prefix, we need to update
1021 * the global routing table too.
1022 */
1023 if (!ri)
1024 continue;
1025
1026 /* Perform route selection; this is just to set the flags
1027 * correctly
1028 * as local route in the VNI always wins.
1029 */
1030 evpn_route_select_install(bgp, vpn, rn);
1031
1032 attr_new = ri->attr;
1033
1034 /* Update route in global routing table. */
1035 rd_rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
1036 (struct prefix *)evp, &vpn->prd);
1037 assert(rd_rn);
1038 update_evpn_route_entry(bgp, vpn, afi, safi, rd_rn, attr_new, 0,
1a98c087 1039 0, &global_ri, 0);
d62a17ae 1040
1041 /* Schedule for processing and unlock node. */
1042 bgp_process(bgp, rd_rn, afi, safi);
1043 bgp_unlock_node(rd_rn);
1044 }
1045
1046 /* Unintern temporary. */
1047 aspath_unintern(&attr.aspath);
1048 aspath_unintern(&attr_sticky.aspath);
1049
1050 return 0;
128ea8ab 1051}
1052
1053/*
1054 * Delete all type-2 (MACIP) local routes for this VNI - only from the
1055 * global routing table. These are also scheduled for withdraw from peers.
1056 */
d62a17ae 1057static int delete_global_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 1058{
d62a17ae 1059 afi_t afi;
1060 safi_t safi;
1061 struct bgp_node *rdrn, *rn;
1062 struct bgp_table *table;
1063 struct bgp_info *ri;
128ea8ab 1064
d62a17ae 1065 afi = AFI_L2VPN;
1066 safi = SAFI_EVPN;
128ea8ab 1067
d62a17ae 1068 rdrn = bgp_node_lookup(bgp->rib[afi][safi], (struct prefix *)&vpn->prd);
1069 if (rdrn && rdrn->info) {
1070 table = (struct bgp_table *)rdrn->info;
1071 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
1072 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
128ea8ab 1073
d62a17ae 1074 if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
1075 continue;
128ea8ab 1076
d62a17ae 1077 delete_evpn_route_entry(bgp, vpn, afi, safi, rn, &ri);
1078 if (ri)
1079 bgp_process(bgp, rn, afi, safi);
1080 }
1081 }
128ea8ab 1082
d62a17ae 1083 /* Unlock RD node. */
1084 if (rdrn)
1085 bgp_unlock_node(rdrn);
128ea8ab 1086
d62a17ae 1087 return 0;
128ea8ab 1088}
1089
1090/*
1091 * Delete all type-2 (MACIP) local routes for this VNI - from the global
1092 * table as well as the per-VNI route table.
1093 */
d62a17ae 1094static int delete_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 1095{
d62a17ae 1096 afi_t afi;
1097 safi_t safi;
1098 struct bgp_node *rn;
1099 struct bgp_info *ri;
128ea8ab 1100
d62a17ae 1101 afi = AFI_L2VPN;
1102 safi = SAFI_EVPN;
128ea8ab 1103
d62a17ae 1104 /* First, walk the global route table for this VNI's type-2 local
1105 * routes.
1106 * EVPN routes are a 2-level table, first get the RD table.
1107 */
1108 delete_global_type2_routes(bgp, vpn);
128ea8ab 1109
d62a17ae 1110 /* Next, walk this VNI's route table and delete local type-2 routes. */
1111 for (rn = bgp_table_top(vpn->route_table); rn;
1112 rn = bgp_route_next(rn)) {
1113 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
128ea8ab 1114
d62a17ae 1115 if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
1116 continue;
128ea8ab 1117
d62a17ae 1118 delete_evpn_route_entry(bgp, vpn, afi, safi, rn, &ri);
128ea8ab 1119
d62a17ae 1120 /* Route entry in local table gets deleted immediately. */
1121 if (ri)
1122 bgp_info_reap(rn, ri);
1123 }
128ea8ab 1124
d62a17ae 1125 return 0;
128ea8ab 1126}
1127
1128/*
1129 * Delete all routes in the per-VNI route table.
1130 */
d62a17ae 1131static int delete_all_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 1132{
d62a17ae 1133 struct bgp_node *rn;
1134 struct bgp_info *ri, *nextri;
128ea8ab 1135
d62a17ae 1136 /* Walk this VNI's route table and delete all routes. */
1137 for (rn = bgp_table_top(vpn->route_table); rn;
1138 rn = bgp_route_next(rn)) {
1139 for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1);
1140 ri = nextri) {
1141 bgp_info_delete(rn, ri);
1142 bgp_info_reap(rn, ri);
1143 }
1144 }
128ea8ab 1145
d62a17ae 1146 return 0;
128ea8ab 1147}
1148
1149/*
1150 * Update (and advertise) local routes for a VNI. Invoked upon the VNI
1151 * export RT getting modified or change to tunnel IP. Note that these
1152 * situations need the route in the per-VNI table as well as the global
1153 * table to be updated (as attributes change).
1154 */
d62a17ae 1155static int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 1156{
d62a17ae 1157 int ret;
1158 struct prefix_evpn p;
128ea8ab 1159
d62a17ae 1160 /* Update and advertise the type-3 route (only one) followed by the
1161 * locally learnt type-2 routes (MACIP) - for this VNI.
1162 */
1163 build_evpn_type3_prefix(&p, vpn->originator_ip);
1164 ret = update_evpn_route(bgp, vpn, &p, 0);
1165 if (ret)
1166 return ret;
128ea8ab 1167
d62a17ae 1168 return update_all_type2_routes(bgp, vpn);
128ea8ab 1169}
1170
1171/*
1172 * Delete (and withdraw) local routes for specified VNI from the global
1173 * table and per-VNI table. After this, remove all other routes from
1174 * the per-VNI table. Invoked upon the VNI being deleted or EVPN
1175 * (advertise-all-vni) being disabled.
1176 */
d62a17ae 1177static int delete_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 1178{
d62a17ae 1179 int ret;
1180 struct prefix_evpn p;
128ea8ab 1181
d62a17ae 1182 /* Delete and withdraw locally learnt type-2 routes (MACIP)
1183 * followed by type-3 routes (only one) - for this VNI.
1184 */
1185 ret = delete_all_type2_routes(bgp, vpn);
1186 if (ret)
1187 return ret;
128ea8ab 1188
d62a17ae 1189 build_evpn_type3_prefix(&p, vpn->originator_ip);
1190 ret = delete_evpn_route(bgp, vpn, &p);
1191 if (ret)
1192 return ret;
128ea8ab 1193
d62a17ae 1194 /* Delete all routes from the per-VNI table. */
1195 return delete_all_vni_routes(bgp, vpn);
128ea8ab 1196}
1197
1198/*
1199 * There is a tunnel endpoint IP address change for this VNI,
1200 * need to re-advertise routes with the new nexthop.
1201 */
d62a17ae 1202static int handle_tunnel_ip_change(struct bgp *bgp, struct bgpevpn *vpn,
1203 struct in_addr originator_ip)
128ea8ab 1204{
d62a17ae 1205 struct prefix_evpn p;
128ea8ab 1206
ddd16ed5
MK
1207 /* If VNI is not live, we only need to update the originator ip */
1208 if (!is_vni_live(vpn)) {
1209 vpn->originator_ip = originator_ip;
1210 return 0;
1211 }
1212
db0e1937
MK
1213 /* Update the tunnel-ip hash */
1214 bgp_tip_del(bgp, &vpn->originator_ip);
1215 bgp_tip_add(bgp, &originator_ip);
1216
1217 /* filter routes as martian nexthop db has changed */
1218 bgp_filter_evpn_routes_upon_martian_nh_change(bgp);
1219
d62a17ae 1220 /* Need to withdraw type-3 route as the originator IP is part
1221 * of the key.
1222 */
1223 build_evpn_type3_prefix(&p, vpn->originator_ip);
1224 delete_evpn_route(bgp, vpn, &p);
128ea8ab 1225
d62a17ae 1226 /* Update the tunnel IP and re-advertise all routes for this VNI. */
1227 vpn->originator_ip = originator_ip;
1228 return update_routes_for_vni(bgp, vpn);
128ea8ab 1229}
1230
1231/*
1232 * Install route entry into the VNI routing table and invoke route selection.
1233 */
d62a17ae 1234static int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
1235 struct prefix_evpn *p,
1236 struct bgp_info *parent_ri)
1237{
1238 struct bgp_node *rn;
1239 struct bgp_info *ri;
1240 struct attr *attr_new;
1241 int ret;
1242
1243 /* Create (or fetch) route within the VNI. */
1244 /* NOTE: There is no RD here. */
1245 rn = bgp_node_get(vpn->route_table, (struct prefix *)p);
1246
1247 /* Check if route entry is already present. */
1248 for (ri = rn->info; ri; ri = ri->next)
1249 if (ri->extra
1250 && (struct bgp_info *)ri->extra->parent == parent_ri)
1251 break;
1252
1253 if (!ri) {
1254 /* Add (or update) attribute to hash. */
1255 attr_new = bgp_attr_intern(parent_ri->attr);
1256
1257 /* Create new route with its attribute. */
1258 ri = info_make(parent_ri->type, parent_ri->sub_type, 0,
1259 parent_ri->peer, attr_new, rn);
1260 SET_FLAG(ri->flags, BGP_INFO_VALID);
1261 bgp_info_extra_get(ri);
1262 ri->extra->parent = parent_ri;
1263 if (parent_ri->extra)
1264 memcpy(&ri->extra->label, &parent_ri->extra->label,
1265 BGP_LABEL_BYTES);
1266 bgp_info_add(rn, ri);
1267 } else {
1268 if (attrhash_cmp(ri->attr, parent_ri->attr)
1269 && !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
1270 bgp_unlock_node(rn);
1271 return 0;
1272 }
1273 /* The attribute has changed. */
1274 /* Add (or update) attribute to hash. */
1275 attr_new = bgp_attr_intern(parent_ri->attr);
1276
1277 /* Restore route, if needed. */
1278 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
1279 bgp_info_restore(rn, ri);
1280
1281 /* Mark if nexthop has changed. */
1282 if (!IPV4_ADDR_SAME(&ri->attr->nexthop, &attr_new->nexthop))
1283 SET_FLAG(ri->flags, BGP_INFO_IGP_CHANGED);
1284
1285 /* Unintern existing, set to new. */
1286 bgp_attr_unintern(&ri->attr);
1287 ri->attr = attr_new;
1288 ri->uptime = bgp_clock();
1289 }
1290
1291 /* Perform route selection and update zebra, if required. */
1292 ret = evpn_route_select_install(bgp, vpn, rn);
1293
1294 return ret;
128ea8ab 1295}
1296
1297/*
1298 * Uninstall route entry from the VNI routing table and send message
1299 * to zebra, if appropriate.
1300 */
d62a17ae 1301static int uninstall_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
1302 struct prefix_evpn *p,
1303 struct bgp_info *parent_ri)
128ea8ab 1304{
d62a17ae 1305 struct bgp_node *rn;
1306 struct bgp_info *ri;
1307 int ret;
128ea8ab 1308
d62a17ae 1309 /* Locate route within the VNI. */
1310 /* NOTE: There is no RD here. */
1311 rn = bgp_node_lookup(vpn->route_table, (struct prefix *)p);
1312 if (!rn)
1313 return 0;
128ea8ab 1314
d62a17ae 1315 /* Find matching route entry. */
1316 for (ri = rn->info; ri; ri = ri->next)
1317 if (ri->extra
1318 && (struct bgp_info *)ri->extra->parent == parent_ri)
1319 break;
128ea8ab 1320
d62a17ae 1321 if (!ri)
1322 return 0;
128ea8ab 1323
d62a17ae 1324 /* Mark entry for deletion */
1325 bgp_info_delete(rn, ri);
128ea8ab 1326
d62a17ae 1327 /* Perform route selection and update zebra, if required. */
1328 ret = evpn_route_select_install(bgp, vpn, rn);
128ea8ab 1329
d62a17ae 1330 /* Unlock route node. */
1331 bgp_unlock_node(rn);
128ea8ab 1332
d62a17ae 1333 return ret;
128ea8ab 1334}
1335
1336/*
1337 * Given a route entry and a VNI, see if this route entry should be
1338 * imported into the VNI i.e., RTs match.
1339 */
d62a17ae 1340static int is_route_matching_for_vni(struct bgp *bgp, struct bgpevpn *vpn,
1341 struct bgp_info *ri)
1342{
1343 struct attr *attr = ri->attr;
1344 struct ecommunity *ecom;
1345 int i;
1346
1347 assert(attr);
1348 /* Route should have valid RT to be even considered. */
1349 if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
1350 return 0;
1351
1352 ecom = attr->ecommunity;
1353 if (!ecom || !ecom->size)
1354 return 0;
1355
1356 /* For each extended community RT, see if it matches this VNI. If any RT
1357 * matches, we're done.
1358 */
1359 for (i = 0; i < ecom->size; i++) {
1360 u_char *pnt;
1361 u_char type, sub_type;
1362 struct ecommunity_val *eval;
1363 struct ecommunity_val eval_tmp;
1364 struct irt_node *irt;
1365
1366 /* Only deal with RTs */
1367 pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
1368 eval = (struct ecommunity_val *)(ecom->val
1369 + (i * ECOMMUNITY_SIZE));
1370 type = *pnt++;
1371 sub_type = *pnt++;
1372 if (sub_type != ECOMMUNITY_ROUTE_TARGET)
1373 continue;
1374
1375 /* See if this RT matches specified VNIs import RTs */
1376 irt = lookup_import_rt(bgp, eval);
1377 if (irt && irt->vnis)
1378 if (is_vni_present_in_irt_vnis(irt->vnis, vpn))
1379 return 1;
1380
1381 /* Also check for non-exact match. In this, we mask out the AS
1382 * and
1383 * only check on the local-admin sub-field. This is to
1384 * facilitate using
1385 * VNI as the RT for EBGP peering too.
1386 */
1387 irt = NULL;
1388 if (type == ECOMMUNITY_ENCODE_AS
1389 || type == ECOMMUNITY_ENCODE_AS4
1390 || type == ECOMMUNITY_ENCODE_IP) {
1391 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
1392 mask_ecom_global_admin(&eval_tmp, eval);
1393 irt = lookup_import_rt(bgp, &eval_tmp);
1394 }
1395 if (irt && irt->vnis)
1396 if (is_vni_present_in_irt_vnis(irt->vnis, vpn))
1397 return 1;
1398 }
1399
1400 return 0;
128ea8ab 1401}
1402
1403/*
1404 * Install or uninstall routes of specified type that are appropriate for this
1405 * particular VNI.
1406 */
d62a17ae 1407static int install_uninstall_routes_for_vni(struct bgp *bgp,
1408 struct bgpevpn *vpn,
1409 bgp_evpn_route_type rtype,
1410 int install)
1411{
0291c246
MK
1412 afi_t afi;
1413 safi_t safi;
1414 struct bgp_node *rd_rn, *rn;
1415 struct bgp_table *table;
1416 struct bgp_info *ri;
1417 int ret;
d62a17ae 1418
1419 afi = AFI_L2VPN;
1420 safi = SAFI_EVPN;
1421
1422 /* Walk entire global routing table and evaluate routes which could be
1423 * imported into this VPN. Note that we cannot just look at the routes
1424 * for
1425 * the VNI's RD - remote routes applicable for this VNI could have any
1426 * RD.
1427 */
1428 /* EVPN routes are a 2-level table. */
1429 for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
1430 rd_rn = bgp_route_next(rd_rn)) {
1431 table = (struct bgp_table *)(rd_rn->info);
1432 if (!table)
1433 continue;
1434
1435 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
1436 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
1437
1438 if (evp->prefix.route_type != rtype)
1439 continue;
1440
1441 for (ri = rn->info; ri; ri = ri->next) {
1442 /* Consider "valid" remote routes applicable for
1443 * this VNI. */
1444 if (!(CHECK_FLAG(ri->flags, BGP_INFO_VALID)
1445 && ri->type == ZEBRA_ROUTE_BGP
1446 && ri->sub_type == BGP_ROUTE_NORMAL))
1447 continue;
1448
1449 if (is_route_matching_for_vni(bgp, vpn, ri)) {
1450 if (install)
1451 ret = install_evpn_route_entry(
60466a63 1452 bgp, vpn, evp, ri);
d62a17ae 1453 else
1454 ret = uninstall_evpn_route_entry(
1455 bgp, vpn, evp, ri);
1456
1457 if (ret) {
1458 zlog_err(
1459 "%u: Failed to %s EVPN %s route in VNI %u",
1460 bgp->vrf_id,
1461 install ? "install"
1462 : "uninstall",
1463 rtype == BGP_EVPN_MAC_IP_ROUTE
1464 ? "MACIP"
1465 : "IMET",
1466 vpn->vni);
1467 return ret;
1468 }
1469 }
1470 }
1471 }
1472 }
1473
1474 return 0;
128ea8ab 1475}
1476
1477/*
1478 * Install any existing remote routes applicable for this VNI into its
1479 * routing table. This is invoked when a VNI becomes "live" or its Import
1480 * RT is changed.
1481 */
d62a17ae 1482static int install_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 1483{
d62a17ae 1484 int ret;
128ea8ab 1485
d62a17ae 1486 /* Install type-3 routes followed by type-2 routes - the ones applicable
1487 * for this VNI.
1488 */
1489 ret = install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_IMET_ROUTE,
1490 1);
1491 if (ret)
1492 return ret;
128ea8ab 1493
d62a17ae 1494 return install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_MAC_IP_ROUTE,
1495 1);
128ea8ab 1496}
1497
90e60aa7 1498/*
1499 * Uninstall any existing remote routes for this VNI. One scenario in which
1500 * this is invoked is upon an import RT change.
1501 */
d62a17ae 1502static int uninstall_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 1503{
d62a17ae 1504 int ret;
90e60aa7 1505
d62a17ae 1506 /* Uninstall type-2 routes followed by type-3 routes - the ones
1507 * applicable
1508 * for this VNI.
1509 */
1510 ret = install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_MAC_IP_ROUTE,
1511 0);
1512 if (ret)
1513 return ret;
90e60aa7 1514
d62a17ae 1515 return install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_IMET_ROUTE,
1516 0);
90e60aa7 1517}
1518
128ea8ab 1519/*
1520 * Install or uninstall route in matching VNIs (list).
1521 */
d62a17ae 1522static int install_uninstall_route_in_vnis(struct bgp *bgp, afi_t afi,
1523 safi_t safi, struct prefix_evpn *evp,
1524 struct bgp_info *ri,
1525 struct list *vnis, int install)
128ea8ab 1526{
d62a17ae 1527 struct bgpevpn *vpn;
1528 struct listnode *node, *nnode;
128ea8ab 1529
d62a17ae 1530 for (ALL_LIST_ELEMENTS(vnis, node, nnode, vpn)) {
1531 int ret;
128ea8ab 1532
d62a17ae 1533 if (!is_vni_live(vpn))
1534 continue;
128ea8ab 1535
d62a17ae 1536 if (install)
1537 ret = install_evpn_route_entry(bgp, vpn, evp, ri);
1538 else
1539 ret = uninstall_evpn_route_entry(bgp, vpn, evp, ri);
128ea8ab 1540
d62a17ae 1541 if (ret) {
1542 zlog_err("%u: Failed to %s EVPN %s route in VNI %u",
1543 bgp->vrf_id, install ? "install" : "uninstall",
1544 evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
1545 ? "MACIP"
1546 : "IMET",
1547 vpn->vni);
1548 return ret;
1549 }
1550 }
128ea8ab 1551
d62a17ae 1552 return 0;
128ea8ab 1553}
1554
1555/*
1556 * Install or uninstall route for appropriate VNIs.
1557 */
d62a17ae 1558static int install_uninstall_evpn_route(struct bgp *bgp, afi_t afi, safi_t safi,
1559 struct prefix *p, struct bgp_info *ri,
1560 int import)
1561{
1562 struct prefix_evpn *evp = (struct prefix_evpn *)p;
1563 struct attr *attr = ri->attr;
1564 struct ecommunity *ecom;
1565 int i;
1566
1567 assert(attr);
1568
1569 /* Only type-2 and type-3 routes go into a L2 VNI. */
1570 if (!(evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
1571 || evp->prefix.route_type == BGP_EVPN_IMET_ROUTE))
1572 return 0;
1573
1574 /* If we don't have Route Target, nothing much to do. */
1575 if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
1576 return 0;
1577
1578 ecom = attr->ecommunity;
1579 if (!ecom || !ecom->size)
1580 return -1;
1581
1582 /* For each extended community RT, see which VNIs match and import
1583 * the route into matching VNIs.
1584 */
1585 for (i = 0; i < ecom->size; i++) {
1586 u_char *pnt;
1587 u_char type, sub_type;
1588 struct ecommunity_val *eval;
1589 struct ecommunity_val eval_tmp;
1590 struct irt_node *irt;
1591
1592 /* Only deal with RTs */
1593 pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
1594 eval = (struct ecommunity_val *)(ecom->val
1595 + (i * ECOMMUNITY_SIZE));
1596 type = *pnt++;
1597 sub_type = *pnt++;
1598 if (sub_type != ECOMMUNITY_ROUTE_TARGET)
1599 continue;
1600
1601 /* Are we interested in this RT? */
1602 irt = lookup_import_rt(bgp, eval);
1603 if (irt && irt->vnis)
1604 install_uninstall_route_in_vnis(bgp, afi, safi, evp, ri,
1605 irt->vnis, import);
1606
1607 /* Also check for non-exact match. In this, we mask out the AS
1608 * and
1609 * only check on the local-admin sub-field. This is to
1610 * facilitate using
1611 * VNI as the RT for EBGP peering too.
1612 */
1613 irt = NULL;
1614 if (type == ECOMMUNITY_ENCODE_AS
1615 || type == ECOMMUNITY_ENCODE_AS4
1616 || type == ECOMMUNITY_ENCODE_IP) {
1617 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
1618 mask_ecom_global_admin(&eval_tmp, eval);
1619 irt = lookup_import_rt(bgp, &eval_tmp);
1620 }
1621 if (irt && irt->vnis)
1622 install_uninstall_route_in_vnis(bgp, afi, safi, evp, ri,
1623 irt->vnis, import);
1624 }
1625
1626 return 0;
128ea8ab 1627}
1628
90e60aa7 1629/*
1630 * Update and advertise local routes for a VNI. Invoked upon router-id
1631 * change. Note that the processing is done only on the global route table
1632 * using routes that already exist in the per-VNI table.
1633 */
d62a17ae 1634static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
1635{
1636 struct prefix_evpn p;
1637 struct bgp_node *rn, *global_rn;
1638 struct bgp_info *ri, *global_ri;
1639 struct attr *attr;
1640 afi_t afi = AFI_L2VPN;
1641 safi_t safi = SAFI_EVPN;
1642
1643 /* Locate type-3 route for VNI in the per-VNI table and use its
1644 * attributes to create and advertise the type-3 route for this VNI
1645 * in the global table.
1646 */
1647 build_evpn_type3_prefix(&p, vpn->originator_ip);
1648 rn = bgp_node_lookup(vpn->route_table, (struct prefix *)&p);
1649 if (!rn) /* unexpected */
1650 return 0;
1651 for (ri = rn->info; ri; ri = ri->next)
1652 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
1653 && ri->sub_type == BGP_ROUTE_STATIC)
1654 break;
1655 if (!ri) /* unexpected */
1656 return 0;
1657 attr = ri->attr;
1658
1659 global_rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
1660 (struct prefix *)&p, &vpn->prd);
1a98c087
MK
1661 update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1, 0, &ri,
1662 0);
d62a17ae 1663
1664 /* Schedule for processing and unlock node. */
1665 bgp_process(bgp, global_rn, afi, safi);
1666 bgp_unlock_node(global_rn);
1667
1668 /* Now, walk this VNI's route table and use the route and its attribute
1669 * to create and schedule route in global table.
1670 */
1671 for (rn = bgp_table_top(vpn->route_table); rn;
1672 rn = bgp_route_next(rn)) {
1673 struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
1674
1675 /* Identify MAC-IP local routes. */
1676 if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
1677 continue;
1678
1679 for (ri = rn->info; ri; ri = ri->next)
1680 if (ri->peer == bgp->peer_self
1681 && ri->type == ZEBRA_ROUTE_BGP
1682 && ri->sub_type == BGP_ROUTE_STATIC)
1683 break;
1684 if (!ri)
1685 continue;
1686
1687 /* Create route in global routing table using this route entry's
1688 * attribute.
1689 */
1690 attr = ri->attr;
1691 global_rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
1692 (struct prefix *)evp, &vpn->prd);
1693 assert(global_rn);
1694 update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, attr, 1,
1a98c087 1695 0, &global_ri, 0);
d62a17ae 1696
1697 /* Schedule for processing and unlock node. */
1698 bgp_process(bgp, global_rn, afi, safi);
1699 bgp_unlock_node(global_rn);
1700 }
1701
1702 return 0;
90e60aa7 1703}
1704
1705/*
1706 * Delete (and withdraw) local routes for a VNI - only from the global
1707 * table. Invoked upon router-id change.
1708 */
d62a17ae 1709static int delete_withdraw_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 1710{
d62a17ae 1711 int ret;
1712 struct prefix_evpn p;
1713 struct bgp_node *global_rn;
1714 struct bgp_info *ri;
1715 afi_t afi = AFI_L2VPN;
1716 safi_t safi = SAFI_EVPN;
90e60aa7 1717
d62a17ae 1718 /* Delete and withdraw locally learnt type-2 routes (MACIP)
1719 * for this VNI - from the global table.
1720 */
1721 ret = delete_global_type2_routes(bgp, vpn);
1722 if (ret)
1723 return ret;
90e60aa7 1724
d62a17ae 1725 /* Remove type-3 route for this VNI from global table. */
1726 build_evpn_type3_prefix(&p, vpn->originator_ip);
1727 global_rn = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi,
1728 (struct prefix *)&p, &vpn->prd);
1729 if (global_rn) {
1730 /* Delete route entry in the global EVPN table. */
1731 delete_evpn_route_entry(bgp, vpn, afi, safi, global_rn, &ri);
90e60aa7 1732
d62a17ae 1733 /* Schedule for processing - withdraws to peers happen from
1734 * this table.
1735 */
1736 if (ri)
1737 bgp_process(bgp, global_rn, afi, safi);
1738 bgp_unlock_node(global_rn);
1739 }
90e60aa7 1740
d62a17ae 1741 return 0;
90e60aa7 1742}
1743
2d48ee25 1744/*
1745 * Handle router-id change. Update and advertise local routes corresponding
1746 * to this VNI from peers. Note that this is invoked after updating the
1747 * router-id. The routes in the per-VNI table are used to create routes in
1748 * the global table and schedule them.
1749 */
d62a17ae 1750static void update_router_id_vni(struct hash_backet *backet, struct bgp *bgp)
2d48ee25 1751{
d62a17ae 1752 struct bgpevpn *vpn;
2d48ee25 1753
d62a17ae 1754 vpn = (struct bgpevpn *)backet->data;
2d48ee25 1755
d62a17ae 1756 if (!vpn) {
1757 zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__);
1758 return;
1759 }
2d48ee25 1760
d62a17ae 1761 /* Skip VNIs with configured RD. */
1762 if (is_rd_configured(vpn))
1763 return;
2d48ee25 1764
d62a17ae 1765 bgp_evpn_derive_auto_rd(bgp, vpn);
1766 update_advertise_vni_routes(bgp, vpn);
2d48ee25 1767}
1768
1769/*
1770 * Handle router-id change. Delete and withdraw local routes corresponding
1771 * to this VNI from peers. Note that this is invoked prior to updating
1772 * the router-id and is done only on the global route table, the routes
1773 * are needed in the per-VNI table to re-advertise with new router id.
1774 */
d62a17ae 1775static void withdraw_router_id_vni(struct hash_backet *backet, struct bgp *bgp)
2d48ee25 1776{
d62a17ae 1777 struct bgpevpn *vpn;
2d48ee25 1778
d62a17ae 1779 vpn = (struct bgpevpn *)backet->data;
2d48ee25 1780
d62a17ae 1781 if (!vpn) {
1782 zlog_warn("%s: VNI hash entry for VNI not found", __FUNCTION__);
1783 return;
1784 }
2d48ee25 1785
d62a17ae 1786 /* Skip VNIs with configured RD. */
1787 if (is_rd_configured(vpn))
1788 return;
2d48ee25 1789
d62a17ae 1790 delete_withdraw_vni_routes(bgp, vpn);
2d48ee25 1791}
1792
128ea8ab 1793/*
1794 * Process received EVPN type-2 route (advertise or withdraw).
1795 */
d62a17ae 1796static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
1797 struct attr *attr, u_char *pfx, int psize,
1798 u_int32_t addpath_id)
1799{
1800 struct prefix_rd prd;
1801 struct prefix_evpn p;
1802 u_char ipaddr_len;
1803 u_char macaddr_len;
1804 mpls_label_t *label_pnt;
1805 int ret;
1806
1807 /* Type-2 route should be either 33, 37 or 49 bytes or an
1808 * additional 3 bytes if there is a second label (VNI):
1809 * RD (8), ESI (10), Eth Tag (4), MAC Addr Len (1),
1810 * MAC Addr (6), IP len (1), IP (0, 4 or 16),
1811 * MPLS Lbl1 (3), MPLS Lbl2 (0 or 3)
1812 */
1813 if (psize != 33 && psize != 37 && psize != 49 && psize != 36
1814 && psize != 40 && psize != 52) {
1815 zlog_err("%u:%s - Rx EVPN Type-2 NLRI with invalid length %d",
1816 peer->bgp->vrf_id, peer->host, psize);
1817 return -1;
1818 }
1819
1820 /* Make prefix_rd */
1821 prd.family = AF_UNSPEC;
1822 prd.prefixlen = 64;
1823 memcpy(&prd.val, pfx, 8);
1824 pfx += 8;
1825
1826 /* Make EVPN prefix. */
1827 memset(&p, 0, sizeof(struct prefix_evpn));
b03b8898 1828 p.family = AF_EVPN;
d62a17ae 1829 p.prefixlen = EVPN_TYPE_2_ROUTE_PREFIXLEN;
1830 p.prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
1831
1832 /* Skip over Ethernet Seg Identifier for now. */
1833 pfx += 10;
1834
1835 /* Skip over Ethernet Tag for now. */
1836 pfx += 4;
1837
1838 /* Get the MAC Addr len */
1839 macaddr_len = *pfx++;
1840
1841 /* Get the MAC Addr */
28328ea9
DS
1842 if (macaddr_len == (ETH_ALEN * 8)) {
1843 memcpy(&p.prefix.mac.octet, pfx, ETH_ALEN);
1844 pfx += ETH_ALEN;
d62a17ae 1845 } else {
1846 zlog_err(
1847 "%u:%s - Rx EVPN Type-2 NLRI with unsupported MAC address length %d",
1848 peer->bgp->vrf_id, peer->host, macaddr_len);
1849 return -1;
1850 }
1851
1852
1853 /* Get the IP. */
1854 ipaddr_len = *pfx++;
1855 if (ipaddr_len != 0 && ipaddr_len != IPV4_MAX_BITLEN
1856 && ipaddr_len != IPV6_MAX_BITLEN) {
1857 zlog_err(
1858 "%u:%s - Rx EVPN Type-2 NLRI with unsupported IP address length %d",
1859 peer->bgp->vrf_id, peer->host, ipaddr_len);
1860 return -1;
1861 }
1862
1863 if (ipaddr_len) {
1864 ipaddr_len /= 8; /* Convert to bytes. */
1865 p.prefix.ip.ipa_type = (ipaddr_len == IPV4_MAX_BYTELEN)
1866 ? IPADDR_V4
1867 : IPADDR_V6;
1868 memcpy(&p.prefix.ip.ip.addr, pfx, ipaddr_len);
1869 }
1870 pfx += ipaddr_len;
1871
1872 /* Get the VNI (in MPLS label field). */
1873 /* Note: We ignore the second VNI, if any. */
1874 label_pnt = (mpls_label_t *)pfx;
1875
1876 /* Process the route. */
1877 if (attr)
1878 ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
1879 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
1880 &prd, label_pnt, 0, NULL);
1881 else
1882 ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
1883 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
1884 &prd, label_pnt, NULL);
1885 return ret;
128ea8ab 1886}
1887
1888/*
1889 * Process received EVPN type-3 route (advertise or withdraw).
1890 */
d62a17ae 1891static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,
1892 struct attr *attr, u_char *pfx, int psize,
1893 u_int32_t addpath_id)
1894{
1895 struct prefix_rd prd;
1896 struct prefix_evpn p;
1897 u_char ipaddr_len;
1898 int ret;
1899
1900 /* Type-3 route should be either 17 or 29 bytes: RD (8), Eth Tag (4),
1901 * IP len (1) and IP (4 or 16).
1902 */
1903 if (psize != 17 && psize != 29) {
1904 zlog_err("%u:%s - Rx EVPN Type-3 NLRI with invalid length %d",
1905 peer->bgp->vrf_id, peer->host, psize);
1906 return -1;
1907 }
1908
1909 /* Make prefix_rd */
1910 prd.family = AF_UNSPEC;
1911 prd.prefixlen = 64;
1912 memcpy(&prd.val, pfx, 8);
1913 pfx += 8;
1914
1915 /* Make EVPN prefix. */
1916 memset(&p, 0, sizeof(struct prefix_evpn));
b03b8898 1917 p.family = AF_EVPN;
d62a17ae 1918 p.prefixlen = EVPN_TYPE_3_ROUTE_PREFIXLEN;
1919 p.prefix.route_type = BGP_EVPN_IMET_ROUTE;
1920
1921 /* Skip over Ethernet Tag for now. */
1922 pfx += 4;
1923
1924 /* Get the IP. */
1925 ipaddr_len = *pfx++;
1926 if (ipaddr_len == IPV4_MAX_BITLEN) {
1927 p.prefix.ip.ipa_type = IPADDR_V4;
1928 memcpy(&p.prefix.ip.ip.addr, pfx, IPV4_MAX_BYTELEN);
1929 } else {
1930 zlog_err(
1931 "%u:%s - Rx EVPN Type-3 NLRI with unsupported IP address length %d",
1932 peer->bgp->vrf_id, peer->host, ipaddr_len);
1933 return -1;
1934 }
1935
1936 /* Process the route. */
1937 if (attr)
1938 ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
1939 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
1940 &prd, NULL, 0, NULL);
1941 else
1942 ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
1943 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
1944 &prd, NULL, NULL);
1945 return ret;
128ea8ab 1946}
1947
1948/*
1949 * Process received EVPN type-5 route (advertise or withdraw).
1950 */
d62a17ae 1951static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
1952 struct attr *attr, u_char *pfx, int psize,
1953 u_int32_t addpath_id, int withdraw)
1954{
1955 struct prefix_rd prd;
1956 struct prefix_evpn p;
1957 struct bgp_route_evpn evpn;
1958 u_char ippfx_len;
1959 u_int32_t eth_tag;
1960 mpls_label_t *label_pnt;
1961 int ret;
1962
1963 /* Type-5 route should be 34 or 58 bytes:
1964 * RD (8), ESI (10), Eth Tag (4), IP len (1), IP (4 or 16),
1965 * GW (4 or 16) and VNI (3).
1966 * Note that the IP and GW should both be IPv4 or both IPv6.
1967 */
1968 if (psize != 34 && psize != 58) {
1969 zlog_err("%u:%s - Rx EVPN Type-5 NLRI with invalid length %d",
1970 peer->bgp->vrf_id, peer->host, psize);
1971 return -1;
1972 }
1973
1974 /* Make prefix_rd */
1975 prd.family = AF_UNSPEC;
1976 prd.prefixlen = 64;
1977 memcpy(&prd.val, pfx, 8);
1978 pfx += 8;
1979
1980 /* Make EVPN prefix. */
1981 memset(&p, 0, sizeof(struct prefix_evpn));
b03b8898 1982 p.family = AF_EVPN;
d62a17ae 1983 p.prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE;
1984
1985 /* Additional information outside of prefix - ESI and GW IP */
1986 memset(&evpn, 0, sizeof(evpn));
1987
1988 /* Fetch ESI */
1989 memcpy(&evpn.eth_s_id.val, pfx, 10);
1990 pfx += 10;
1991
1992 /* Fetch Ethernet Tag. */
1993 memcpy(&eth_tag, pfx, 4);
1994 p.prefix.eth_tag = ntohl(eth_tag);
1995 pfx += 4;
1996
1997 /* Fetch IP prefix length. */
1998 ippfx_len = *pfx++;
1999 if (ippfx_len > IPV6_MAX_BITLEN) {
2000 zlog_err(
2001 "%u:%s - Rx EVPN Type-5 NLRI with invalid IP Prefix length %d",
2002 peer->bgp->vrf_id, peer->host, ippfx_len);
2003 return -1;
2004 }
2005 p.prefix.ip_prefix_length = ippfx_len;
2006
2007 /* Determine IPv4 or IPv6 prefix */
2008 /* Since the address and GW are from the same family, this just becomes
2009 * a simple check on the total size.
2010 */
2011 if (psize == 34) {
2012 SET_IPADDR_V4(&p.prefix.ip);
2013 memcpy(&p.prefix.ip.ipaddr_v4, pfx, 4);
2014 pfx += 4;
2015 memcpy(&evpn.gw_ip.ipv4, pfx, 4);
2016 pfx += 4;
2017 p.prefixlen = PREFIX_LEN_ROUTE_TYPE_5_IPV4;
2018 } else {
2019 SET_IPADDR_V6(&p.prefix.ip);
2020 memcpy(&p.prefix.ip.ipaddr_v6, pfx, 16);
2021 pfx += 16;
2022 memcpy(&evpn.gw_ip.ipv6, pfx, 16);
2023 pfx += 16;
2024 p.prefixlen = PREFIX_LEN_ROUTE_TYPE_5_IPV6;
2025 }
2026
2027 label_pnt = (mpls_label_t *)pfx;
2028
2029 /* Process the route. */
2030 if (!withdraw)
2031 ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
2032 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
2033 &prd, label_pnt, 0, &evpn);
2034 else
2035 ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
2036 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
2037 &prd, label_pnt, &evpn);
2038
2039 return ret;
2040}
2041
2042static void evpn_mpattr_encode_type5(struct stream *s, struct prefix *p,
2043 struct prefix_rd *prd, mpls_label_t *label,
2044 struct attr *attr)
2045{
2046 int len;
2047 char temp[16];
2048 struct evpn_addr *p_evpn_p;
2049
2050 memset(&temp, 0, 16);
b03b8898 2051 if (p->family != AF_EVPN)
d62a17ae 2052 return;
2053 p_evpn_p = &(p->u.prefix_evpn);
2054
2055 if (IS_IPADDR_V4(&p_evpn_p->ip))
2056 len = 8; /* ipv4 */
2057 else
2058 len = 32; /* ipv6 */
d62a17ae 2059 /* Prefix contains RD, ESI, EthTag, IP length, IP, GWIP and VNI */
2060 stream_putc(s, 8 + 10 + 4 + 1 + len + 3);
2061 stream_put(s, prd->val, 8);
0af35d90 2062 if (attr)
d62a17ae 2063 stream_put(s, &(attr->evpn_overlay.eth_s_id), 10);
2064 else
2065 stream_put(s, &temp, 10);
2066 stream_putl(s, p_evpn_p->eth_tag);
2067 stream_putc(s, p_evpn_p->ip_prefix_length);
2068 if (IS_IPADDR_V4(&p_evpn_p->ip))
2069 stream_put_ipv4(s, p_evpn_p->ip.ipaddr_v4.s_addr);
2070 else
2071 stream_put(s, &p_evpn_p->ip.ipaddr_v6, 16);
0af35d90 2072 if (attr) {
d62a17ae 2073 if (IS_IPADDR_V4(&p_evpn_p->ip))
2074 stream_put_ipv4(s,
2075 attr->evpn_overlay.gw_ip.ipv4.s_addr);
2076 else
2077 stream_put(s, &(attr->evpn_overlay.gw_ip.ipv6), 16);
2078 } else {
2079 if (IS_IPADDR_V4(&p_evpn_p->ip))
2080 stream_put_ipv4(s, 0);
2081 else
2082 stream_put(s, &temp, 16);
2083 }
2084
2085 if (label)
2086 stream_put(s, label, 3);
2087 else
2088 stream_put3(s, 0);
128ea8ab 2089}
2090
2091/*
2092 * Cleanup specific VNI upon EVPN (advertise-all-vni) being disabled.
2093 */
d62a17ae 2094static void cleanup_vni_on_disable(struct hash_backet *backet, struct bgp *bgp)
128ea8ab 2095{
d62a17ae 2096 struct bgpevpn *vpn = (struct bgpevpn *)backet->data;
128ea8ab 2097
d62a17ae 2098 /* Remove EVPN routes and schedule for processing. */
2099 delete_routes_for_vni(bgp, vpn);
128ea8ab 2100
d62a17ae 2101 /* Clear "live" flag and see if hash needs to be freed. */
2102 UNSET_FLAG(vpn->flags, VNI_FLAG_LIVE);
2103 if (!is_vni_configured(vpn))
2104 bgp_evpn_free(bgp, vpn);
128ea8ab 2105}
2106
2107/*
2108 * Free a VNI entry; iterator function called during cleanup.
2109 */
d62a17ae 2110static void free_vni_entry(struct hash_backet *backet, struct bgp *bgp)
128ea8ab 2111{
d62a17ae 2112 struct bgpevpn *vpn;
128ea8ab 2113
d62a17ae 2114 vpn = (struct bgpevpn *)backet->data;
2115 delete_all_vni_routes(bgp, vpn);
2116 bgp_evpn_free(bgp, vpn);
128ea8ab 2117}
2118
c581d8b0
MK
2119/*
2120 * Derive AUTO import RT for BGP VRF - L3VNI
2121 */
2122static void evpn_auto_rt_import_add_for_vrf(struct bgp *bgp_vrf)
2123{
2124 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD);
2125 form_auto_rt(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_import_rtl);
2126}
2127
2128/*
2129 * Delete AUTO import RT from BGP VRF - L3VNI
2130 */
2131static void evpn_auto_rt_import_delete_for_vrf(struct bgp *bgp_vrf)
2132{
2133 evpn_rt_delete_auto(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_import_rtl);
2134}
2135
2136/*
2137 * Derive AUTO export RT for BGP VRF - L3VNI
2138 */
2139static void evpn_auto_rt_export_add_for_vrf(struct bgp *bgp_vrf)
2140{
2141 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD);
2142 form_auto_rt(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_export_rtl);
2143}
2144
2145/*
2146 * Delete AUTO export RT from BGP VRF - L3VNI
2147 */
2148static void evpn_auto_rt_export_delete_for_vrf(struct bgp *bgp_vrf)
2149{
2150 evpn_rt_delete_auto(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_export_rtl);
2151}
128ea8ab 2152
f1f8b53c
MK
2153static void bgp_evpn_handle_export_rt_change_for_vrf(struct bgp *bgp_vrf)
2154{
2155 struct bgp *bgp_def = NULL;
2156 struct listnode *node = NULL;
2157 struct bgpevpn *vpn = NULL;
2158
2159 bgp_def = bgp_get_default();
2160 if (!bgp_def)
2161 return;
2162
2163 for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn))
2164 update_routes_for_vni(bgp_def, vpn);
2165}
2166
128ea8ab 2167/*
2168 * Public functions.
2169 */
2170
c581d8b0
MK
2171void evpn_rt_delete_auto(struct bgp *bgp, vni_t vni,
2172 struct list *rtl)
2173{
2174 struct listnode *node, *nnode, *node_to_del;
2175 struct ecommunity *ecom, *ecom_auto;
2176 struct ecommunity_val eval;
2177
2178 encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
2179
2180 ecom_auto = ecommunity_new();
2181 ecommunity_add_val(ecom_auto, &eval);
2182 node_to_del = NULL;
2183
2184 for (ALL_LIST_ELEMENTS(rtl, node, nnode, ecom)) {
2185 if (ecommunity_match(ecom, ecom_auto)) {
2186 ecommunity_free(&ecom);
2187 node_to_del = node;
2188 }
2189 }
2190
2191 if (node_to_del)
2192 list_delete_node(rtl, node_to_del);
2193
2194 ecommunity_free(&ecom_auto);
2195}
2196
2197void bgp_evpn_configure_import_rt_for_vrf(struct bgp *bgp_vrf,
2198 struct ecommunity *ecomadd)
2199{
2200 /* Remove auto generated RT */
2201 evpn_auto_rt_import_delete_for_vrf(bgp_vrf);
2202
2203 /* Add the newly configured RT to RT list */
2204 listnode_add_sort(bgp_vrf->vrf_import_rtl, ecomadd);
2205 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD);
2206
2207 //TODO_MITESH: handle RT change (uninstall old routes and install new
2208 //routes matching this RT)
2209}
2210
2211void bgp_evpn_unconfigure_import_rt_for_vrf(struct bgp *bgp_vrf,
2212 struct ecommunity *ecomdel)
2213{
2214 struct listnode *node = NULL, *nnode = NULL, *node_to_del = NULL;
2215 struct ecommunity *ecom = NULL;
2216
2217 /* remove the RT from the RT list */
2218 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_import_rtl, node, nnode, ecom)) {
2219 if (ecommunity_match(ecom, ecomdel)) {
2220 ecommunity_free(&ecom);
2221 node_to_del = node;
2222 break;
2223 }
2224 }
2225
2226 if (node_to_del)
2227 list_delete_node(bgp_vrf->vrf_import_rtl, node_to_del);
2228
2229 /* fallback to auto import rt, if this was the last RT */
2230 if (list_isempty(bgp_vrf->vrf_import_rtl)) {
2231 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD);
2232 evpn_auto_rt_import_add_for_vrf(bgp_vrf);
2233 }
2234
2235 //TODO_MITESH: handle import RT change
2236 //uninstall old routes, install new routes matching this RT
2237}
2238
2239void bgp_evpn_configure_export_rt_for_vrf(struct bgp *bgp_vrf,
2240 struct ecommunity *ecomadd)
2241{
2242 /* remove auto-generated RT */
2243 evpn_auto_rt_export_delete_for_vrf(bgp_vrf);
2244
2245 /* Add the new RT to the RT list */
2246 listnode_add_sort(bgp_vrf->vrf_export_rtl, ecomadd);
2247 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD);
2248
f1f8b53c
MK
2249 bgp_evpn_handle_export_rt_change_for_vrf(bgp_vrf);
2250
c581d8b0
MK
2251}
2252
2253void bgp_evpn_unconfigure_export_rt_for_vrf(struct bgp *bgp_vrf,
2254 struct ecommunity *ecomdel)
2255{
2256 struct listnode *node = NULL, *nnode = NULL, *node_to_del = NULL;
2257 struct ecommunity *ecom = NULL;
2258
2259 /* Remove the RT from the RT list */
2260 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_export_rtl, node, nnode, ecom)) {
2261 if (ecommunity_match(ecom, ecomdel)) {
2262 ecommunity_free(&ecom);
2263 node_to_del = node;
2264 break;
2265 }
2266 }
2267
2268 if (node_to_del)
2269 list_delete_node(bgp_vrf->vrf_export_rtl, node_to_del);
2270
2271 /* fall back to auto-generated RT if this was the last RT */
2272 if (list_isempty(bgp_vrf->vrf_export_rtl)) {
2273 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD);
2274 evpn_auto_rt_export_add_for_vrf(bgp_vrf);
2275 }
2276
f1f8b53c 2277 bgp_evpn_handle_export_rt_change_for_vrf(bgp_vrf);
c581d8b0
MK
2278}
2279
2d48ee25 2280/*
2281 * Handle change to BGP router id. This is invoked twice by the change
2282 * handler, first before the router id has been changed and then after
2283 * the router id has been changed. The first invocation will result in
2284 * local routes for all VNIs being deleted and withdrawn and the next
2285 * will result in the routes being re-advertised.
2286 */
d62a17ae 2287void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw)
2d48ee25 2288{
d62a17ae 2289 if (withdraw)
2290 hash_iterate(bgp->vnihash,
2291 (void (*)(struct hash_backet *,
2292 void *))withdraw_router_id_vni,
2293 bgp);
2294 else
2295 hash_iterate(bgp->vnihash,
2296 (void (*)(struct hash_backet *,
2297 void *))update_router_id_vni,
2298 bgp);
2d48ee25 2299}
2300
90e60aa7 2301/*
2302 * Handle change to export RT - update and advertise local routes.
2303 */
d62a17ae 2304int bgp_evpn_handle_export_rt_change(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 2305{
d62a17ae 2306 return update_routes_for_vni(bgp, vpn);
90e60aa7 2307}
2308
2309/*
2310 * Handle change to RD. This is invoked twice by the change handler,
2311 * first before the RD has been changed and then after the RD has
2312 * been changed. The first invocation will result in local routes
2313 * of this VNI being deleted and withdrawn and the next will result
2314 * in the routes being re-advertised.
2315 */
d62a17ae 2316void bgp_evpn_handle_rd_change(struct bgp *bgp, struct bgpevpn *vpn,
2317 int withdraw)
90e60aa7 2318{
d62a17ae 2319 if (withdraw)
2320 delete_withdraw_vni_routes(bgp, vpn);
2321 else
2322 update_advertise_vni_routes(bgp, vpn);
90e60aa7 2323}
2324
2325/*
2326 * Install routes for this VNI. Invoked upon change to Import RT.
2327 */
d62a17ae 2328int bgp_evpn_install_routes(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 2329{
d62a17ae 2330 return install_routes_for_vni(bgp, vpn);
90e60aa7 2331}
2332
2333/*
2334 * Uninstall all routes installed for this VNI. Invoked upon change
2335 * to Import RT.
2336 */
d62a17ae 2337int bgp_evpn_uninstall_routes(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 2338{
d62a17ae 2339 return uninstall_routes_for_vni(bgp, vpn);
90e60aa7 2340}
2341
b16031a2 2342/*
2343 * Function to display "tag" in route as a VNI.
2344 */
d62a17ae 2345char *bgp_evpn_label2str(mpls_label_t *label, char *buf, int len)
b16031a2 2346{
d62a17ae 2347 vni_t vni;
b16031a2 2348
d62a17ae 2349 vni = label2vni(label);
2350 snprintf(buf, len, "%u", vni);
2351 return buf;
b16031a2 2352}
2353
9c92b5f7
MK
2354/*
2355 * Function to convert evpn route to json format.
2356 * NOTE: We don't use prefix2str as the output here is a bit different.
2357 */
57f7feb6 2358void bgp_evpn_route2json(struct prefix_evpn *p, json_object *json)
9c92b5f7 2359{
b682f6de 2360 char buf1[ETHER_ADDR_STRLEN];
2361 char buf2[PREFIX2STR_BUFFER];
9c92b5f7 2362
b682f6de 2363 if (!json)
2364 return;
9c92b5f7 2365
dff8f48d 2366 if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) {
b682f6de 2367 json_object_int_add(json, "routeType", p->prefix.route_type);
2368 json_object_int_add(json, "ethTag", 0);
57f7feb6
MK
2369 json_object_int_add(json, "ipLen",
2370 IS_EVPN_PREFIX_IPADDR_V4(p)
2371 ? IPV4_MAX_BITLEN
2372 : IPV6_MAX_BITLEN);
b682f6de 2373 json_object_string_add(json, "ip",
57f7feb6
MK
2374 inet_ntoa(p->prefix.ip.ipaddr_v4));
2375 } else if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
dff8f48d 2376 if (IS_EVPN_PREFIX_IPADDR_NONE(p)) {
57f7feb6
MK
2377 json_object_int_add(json, "routeType",
2378 p->prefix.route_type);
2379 json_object_int_add(
2380 json, "esi",
2381 0); /* TODO: we don't support esi yet */
2382 json_object_int_add(json, "ethTag", 0);
2383 json_object_int_add(json, "macLen", 8 * ETH_ALEN);
2384 json_object_string_add(json, "mac",
2385 prefix_mac2str(&p->prefix.mac,
2386 buf1,
2387 sizeof(buf1)));
dff8f48d
MK
2388 } else {
2389 u_char family;
2390
57f7feb6
MK
2391 family = IS_EVPN_PREFIX_IPADDR_V4(p) ? AF_INET
2392 : AF_INET6;
dff8f48d 2393
b682f6de 2394 json_object_int_add(json, "routeType",
57f7feb6
MK
2395 p->prefix.route_type);
2396 json_object_int_add(
2397 json, "esi",
2398 0); /* TODO: we don't support esi yet */
b682f6de 2399 json_object_int_add(json, "ethTag", 0);
57f7feb6 2400 json_object_int_add(json, "macLen", 8 * ETH_ALEN);
b682f6de 2401 json_object_string_add(json, "mac",
57f7feb6
MK
2402 prefix_mac2str(&p->prefix.mac,
2403 buf1,
2404 sizeof(buf1)));
b682f6de 2405 json_object_int_add(json, "ipLen",
57f7feb6
MK
2406 IS_EVPN_PREFIX_IPADDR_V4(p)
2407 ? IPV4_MAX_BITLEN
2408 : IPV6_MAX_BITLEN);
2409 json_object_string_add(
2410 json, "ip",
2411 inet_ntop(family, &p->prefix.ip.ip.addr, buf2,
2412 PREFIX2STR_BUFFER));
dff8f48d
MK
2413 }
2414 } else {
2415 /* Currently, this is to cater to other AF_ETHERNET code. */
2416 }
9c92b5f7
MK
2417}
2418
520d5d76 2419/*
2420 * Function to convert evpn route to string.
2421 * NOTE: We don't use prefix2str as the output here is a bit different.
2422 */
d62a17ae 2423char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len)
2424{
2425 char buf1[ETHER_ADDR_STRLEN];
2426 char buf2[PREFIX2STR_BUFFER];
2427
2428 if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) {
2429 snprintf(buf, len, "[%d]:[0]:[%d]:[%s]", p->prefix.route_type,
2430 IS_EVPN_PREFIX_IPADDR_V4(p) ? IPV4_MAX_BITLEN
2431 : IPV6_MAX_BITLEN,
2432 inet_ntoa(p->prefix.ip.ipaddr_v4));
2433 } else if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
2434 if (IS_EVPN_PREFIX_IPADDR_NONE(p))
2435 snprintf(buf, len, "[%d]:[0]:[0]:[%d]:[%s]",
28328ea9 2436 p->prefix.route_type, 8 * ETH_ALEN,
d62a17ae 2437 prefix_mac2str(&p->prefix.mac, buf1,
2438 sizeof(buf1)));
2439 else {
2440 u_char family;
2441
2442 family = IS_EVPN_PREFIX_IPADDR_V4(p) ? AF_INET
2443 : AF_INET6;
2444 snprintf(buf, len, "[%d]:[0]:[0]:[%d]:[%s]:[%d]:[%s]",
28328ea9 2445 p->prefix.route_type, 8 * ETH_ALEN,
d62a17ae 2446 prefix_mac2str(&p->prefix.mac, buf1,
2447 sizeof(buf1)),
2448 family == AF_INET ? IPV4_MAX_BITLEN
2449 : IPV6_MAX_BITLEN,
2450 inet_ntop(family, &p->prefix.ip.ip.addr, buf2,
2451 PREFIX2STR_BUFFER));
2452 }
2453 } else {
b03b8898 2454 /* For EVPN route types not supported yet. */
f9aa3e55
QY
2455 snprintf(buf, len, "(unsupported route type %d)",
2456 p->prefix.route_type);
d62a17ae 2457 }
2458
2459 return (buf);
520d5d76 2460}
2461
128ea8ab 2462/*
2463 * Encode EVPN prefix in Update (MP_REACH)
2464 */
d62a17ae 2465void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
2466 struct prefix_rd *prd, mpls_label_t *label,
2467 struct attr *attr, int addpath_encode,
2468 u_int32_t addpath_tx_id)
2469{
2470 struct prefix_evpn *evp = (struct prefix_evpn *)p;
2471 int ipa_len = 0;
2472
2473 if (addpath_encode)
2474 stream_putl(s, addpath_tx_id);
2475
2476 /* Route type */
2477 stream_putc(s, evp->prefix.route_type);
2478
2479 switch (evp->prefix.route_type) {
2480 case BGP_EVPN_MAC_IP_ROUTE:
2481 if (IS_EVPN_PREFIX_IPADDR_V4(evp))
2482 ipa_len = IPV4_MAX_BYTELEN;
2483 else if (IS_EVPN_PREFIX_IPADDR_V6(evp))
2484 ipa_len = IPV6_MAX_BYTELEN;
2485 stream_putc(s, 33 + ipa_len); // 1 VNI
2486 stream_put(s, prd->val, 8); /* RD */
2487 stream_put(s, 0, 10); /* ESI */
2488 stream_putl(s, 0); /* Ethernet Tag ID */
28328ea9 2489 stream_putc(s, 8 * ETH_ALEN); /* Mac Addr Len - bits */
d62a17ae 2490 stream_put(s, evp->prefix.mac.octet, 6); /* Mac Addr */
2491 stream_putc(s, 8 * ipa_len); /* IP address Length */
2492 if (ipa_len)
2493 stream_put(s, &evp->prefix.ip.ip.addr,
2494 ipa_len); /* IP */
2495 stream_put(s, label,
2496 BGP_LABEL_BYTES); /* VNI is contained in 'tag' */
2497 break;
2498
2499 case BGP_EVPN_IMET_ROUTE:
2500 stream_putc(s, 17); // TODO: length - assumes IPv4 address
2501 stream_put(s, prd->val, 8); /* RD */
2502 stream_putl(s, 0); /* Ethernet Tag ID */
2503 stream_putc(s, IPV4_MAX_BITLEN); /* IP address Length - bits */
2504 /* Originating Router's IP Addr */
2505 stream_put_in_addr(s, &evp->prefix.ip.ipaddr_v4);
2506 break;
2507
2508 case BGP_EVPN_IP_PREFIX_ROUTE:
2509 /* TODO: AddPath support. */
2510 evpn_mpattr_encode_type5(s, p, prd, label, attr);
2511 break;
2512
2513 default:
2514 break;
2515 }
2516}
2517
2518int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
2519 struct bgp_nlri *packet, int withdraw)
2520{
2521 u_char *pnt;
2522 u_char *lim;
2523 afi_t afi;
2524 safi_t safi;
2525 u_int32_t addpath_id;
2526 int addpath_encoded;
2527 int psize = 0;
2528 u_char rtype;
2529 u_char rlen;
2530 struct prefix p;
2531
2532 /* Check peer status. */
2533 if (peer->status != Established) {
2534 zlog_err("%u:%s - EVPN update received in state %d",
2535 peer->bgp->vrf_id, peer->host, peer->status);
2536 return -1;
2537 }
2538
2539 /* Start processing the NLRI - there may be multiple in the MP_REACH */
2540 pnt = packet->nlri;
2541 lim = pnt + packet->length;
2542 afi = packet->afi;
2543 safi = packet->safi;
2544 addpath_id = 0;
2545
2546 addpath_encoded =
2547 (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
2548 && CHECK_FLAG(peer->af_cap[afi][safi],
2549 PEER_CAP_ADDPATH_AF_TX_RCV));
2550
2551 for (; pnt < lim; pnt += psize) {
2552 /* Clear prefix structure. */
2553 memset(&p, 0, sizeof(struct prefix));
2554
2555 /* Deal with path-id if AddPath is supported. */
2556 if (addpath_encoded) {
2557 /* When packet overflow occurs return immediately. */
2558 if (pnt + BGP_ADDPATH_ID_LEN > lim)
2559 return -1;
2560
2561 addpath_id = ntohl(*((uint32_t *)pnt));
2562 pnt += BGP_ADDPATH_ID_LEN;
2563 }
2564
2565 /* All EVPN NLRI types start with type and length. */
2566 if (pnt + 2 > lim)
2567 return -1;
2568
2569 rtype = *pnt++;
2570 psize = rlen = *pnt++;
2571
2572 /* When packet overflow occur return immediately. */
2573 if (pnt + psize > lim)
2574 return -1;
2575
2576 switch (rtype) {
2577 case BGP_EVPN_MAC_IP_ROUTE:
2578 if (process_type2_route(peer, afi, safi,
2579 withdraw ? NULL : attr, pnt,
2580 psize, addpath_id)) {
2581 zlog_err(
2582 "%u:%s - Error in processing EVPN type-2 NLRI size %d",
2583 peer->bgp->vrf_id, peer->host, psize);
2584 return -1;
2585 }
2586 break;
2587
2588 case BGP_EVPN_IMET_ROUTE:
2589 if (process_type3_route(peer, afi, safi,
2590 withdraw ? NULL : attr, pnt,
2591 psize, addpath_id)) {
2592 zlog_err(
2593 "%u:%s - Error in processing EVPN type-3 NLRI size %d",
2594 peer->bgp->vrf_id, peer->host, psize);
2595 return -1;
2596 }
2597 break;
2598
2599 case BGP_EVPN_IP_PREFIX_ROUTE:
2600 if (process_type5_route(peer, afi, safi, attr, pnt,
2601 psize, addpath_id, withdraw)) {
2602 zlog_err(
2603 "%u:%s - Error in processing EVPN type-5 NLRI size %d",
2604 peer->bgp->vrf_id, peer->host, psize);
2605 return -1;
2606 }
2607 break;
2608
2609 default:
2610 break;
2611 }
2612 }
2613
2614 /* Packet length consistency check. */
2615 if (pnt != lim)
2616 return -1;
2617
2618 return 0;
128ea8ab 2619}
2620
2621
2622/*
2623 * Map the RTs (configured or automatically derived) of a VNI to the VNI.
2624 * The mapping will be used during route processing.
2625 */
d62a17ae 2626void bgp_evpn_map_vni_to_its_rts(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 2627{
d62a17ae 2628 int i;
2629 struct ecommunity_val *eval;
2630 struct listnode *node, *nnode;
2631 struct ecommunity *ecom;
128ea8ab 2632
d62a17ae 2633 for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
2634 for (i = 0; i < ecom->size; i++) {
2635 eval = (struct ecommunity_val *)(ecom->val
2636 + (i
2637 * ECOMMUNITY_SIZE));
2638 map_vni_to_rt(bgp, vpn, eval);
2639 }
2640 }
128ea8ab 2641}
2642
2643/*
2644 * Unmap the RTs (configured or automatically derived) of a VNI from the VNI.
2645 */
d62a17ae 2646void bgp_evpn_unmap_vni_from_its_rts(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 2647{
d62a17ae 2648 int i;
2649 struct ecommunity_val *eval;
2650 struct listnode *node, *nnode;
2651 struct ecommunity *ecom;
128ea8ab 2652
d62a17ae 2653 for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
2654 for (i = 0; i < ecom->size; i++) {
2655 struct irt_node *irt;
2656 struct ecommunity_val eval_tmp;
128ea8ab 2657
d62a17ae 2658 eval = (struct ecommunity_val *)(ecom->val
2659 + (i
2660 * ECOMMUNITY_SIZE));
2661 /* If using "automatic" RT, we only care about the
2662 * local-admin sub-field.
2663 * This is to facilitate using VNI as the RT for EBGP
2664 * peering too.
2665 */
2666 memcpy(&eval_tmp, eval, ECOMMUNITY_SIZE);
2667 if (!is_import_rt_configured(vpn))
2668 mask_ecom_global_admin(&eval_tmp, eval);
128ea8ab 2669
d62a17ae 2670 irt = lookup_import_rt(bgp, &eval_tmp);
2671 if (irt)
2672 unmap_vni_from_rt(bgp, vpn, irt);
2673 }
2674 }
128ea8ab 2675}
2676
2677/*
2678 * Derive Import RT automatically for VNI and map VNI to RT.
2679 * The mapping will be used during route processing.
2680 */
d62a17ae 2681void bgp_evpn_derive_auto_rt_import(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 2682{
c581d8b0 2683 form_auto_rt(bgp, vpn->vni, vpn->import_rtl);
d62a17ae 2684 UNSET_FLAG(vpn->flags, VNI_FLAG_IMPRT_CFGD);
128ea8ab 2685
d62a17ae 2686 /* Map RT to VNI */
2687 bgp_evpn_map_vni_to_its_rts(bgp, vpn);
128ea8ab 2688}
2689
2690/*
2691 * Derive Export RT automatically for VNI.
2692 */
d62a17ae 2693void bgp_evpn_derive_auto_rt_export(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 2694{
c581d8b0 2695 form_auto_rt(bgp, vpn->vni, vpn->export_rtl);
d62a17ae 2696 UNSET_FLAG(vpn->flags, VNI_FLAG_EXPRT_CFGD);
128ea8ab 2697}
2698
2699/*
2700 * Derive RD automatically for VNI using passed information - it
2701 * is of the form RouterId:unique-id-for-vni.
2702 */
d62a17ae 2703void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 2704{
d62a17ae 2705 char buf[100];
128ea8ab 2706
d62a17ae 2707 vpn->prd.family = AF_UNSPEC;
2708 vpn->prd.prefixlen = 64;
2709 sprintf(buf, "%s:%hu", inet_ntoa(bgp->router_id), vpn->rd_id);
cbb65f5e 2710 (void)str2prefix_rd(buf, &vpn->prd);
d62a17ae 2711 UNSET_FLAG(vpn->flags, VNI_FLAG_RD_CFGD);
128ea8ab 2712}
2713
2714/*
2715 * Lookup VNI.
2716 */
d62a17ae 2717struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni)
128ea8ab 2718{
d62a17ae 2719 struct bgpevpn *vpn;
2720 struct bgpevpn tmp;
128ea8ab 2721
d62a17ae 2722 memset(&tmp, 0, sizeof(struct bgpevpn));
2723 tmp.vni = vni;
2724 vpn = hash_lookup(bgp->vnihash, &tmp);
2725 return vpn;
128ea8ab 2726}
2727
2728/*
2729 * Create a new vpn - invoked upon configuration or zebra notification.
2730 */
d62a17ae 2731struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
29c53922
MK
2732 struct in_addr originator_ip,
2733 vrf_id_t tenant_vrf_id)
128ea8ab 2734{
d62a17ae 2735 struct bgpevpn *vpn;
128ea8ab 2736
d62a17ae 2737 if (!bgp)
2738 return NULL;
128ea8ab 2739
d62a17ae 2740 vpn = XCALLOC(MTYPE_BGP_EVPN, sizeof(struct bgpevpn));
2741 if (!vpn)
2742 return NULL;
128ea8ab 2743
d62a17ae 2744 /* Set values - RD and RT set to defaults. */
2745 vpn->vni = vni;
2746 vpn->originator_ip = originator_ip;
29c53922 2747 vpn->tenant_vrf_id = tenant_vrf_id;
128ea8ab 2748
d62a17ae 2749 /* Initialize route-target import and export lists */
2750 vpn->import_rtl = list_new();
2751 vpn->import_rtl->cmp = (int (*)(void *, void *))evpn_route_target_cmp;
2752 vpn->export_rtl = list_new();
2753 vpn->export_rtl->cmp = (int (*)(void *, void *))evpn_route_target_cmp;
2754 bf_assign_index(bgp->rd_idspace, vpn->rd_id);
2755 derive_rd_rt_for_vni(bgp, vpn);
128ea8ab 2756
d62a17ae 2757 /* Initialize EVPN route table. */
2758 vpn->route_table = bgp_table_init(AFI_L2VPN, SAFI_EVPN);
128ea8ab 2759
d62a17ae 2760 /* Add to hash */
2761 if (!hash_get(bgp->vnihash, vpn, hash_alloc_intern)) {
2762 XFREE(MTYPE_BGP_EVPN, vpn);
2763 return NULL;
2764 }
6a8657d0
MK
2765
2766 /* add to l2vni list on corresponding vrf */
2767 bgpevpn_link_to_l3vni(vpn);
2768
d62a17ae 2769 QOBJ_REG(vpn, bgpevpn);
2770 return vpn;
128ea8ab 2771}
2772
2773/*
2774 * Free a given VPN - called in multiple scenarios such as zebra
2775 * notification, configuration being deleted, advertise-all-vni disabled etc.
2776 * This just frees appropriate memory, caller should have taken other
2777 * needed actions.
2778 */
d62a17ae 2779void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn)
128ea8ab 2780{
6a8657d0 2781 bgpevpn_unlink_from_l3vni(vpn);
d62a17ae 2782 bgp_table_unlock(vpn->route_table);
2783 bgp_evpn_unmap_vni_from_its_rts(bgp, vpn);
affe9e99
DS
2784 list_delete_and_null(&vpn->import_rtl);
2785 list_delete_and_null(&vpn->export_rtl);
d62a17ae 2786 bf_release_index(bgp->rd_idspace, vpn->rd_id);
2787 hash_release(bgp->vnihash, vpn);
2788 QOBJ_UNREG(vpn);
2789 XFREE(MTYPE_BGP_EVPN, vpn);
128ea8ab 2790}
2791
2792/*
2793 * Import route into matching VNI(s).
2794 */
d62a17ae 2795int bgp_evpn_import_route(struct bgp *bgp, afi_t afi, safi_t safi,
2796 struct prefix *p, struct bgp_info *ri)
128ea8ab 2797{
d62a17ae 2798 return install_uninstall_evpn_route(bgp, afi, safi, p, ri, 1);
128ea8ab 2799}
2800
2801/*
2802 * Unimport route from matching VNI(s).
2803 */
d62a17ae 2804int bgp_evpn_unimport_route(struct bgp *bgp, afi_t afi, safi_t safi,
2805 struct prefix *p, struct bgp_info *ri)
128ea8ab 2806{
d62a17ae 2807 return install_uninstall_evpn_route(bgp, afi, safi, p, ri, 0);
128ea8ab 2808}
2809
db0e1937
MK
2810/* filter routes which have martian next hops */
2811int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp)
2812{
0291c246
MK
2813 afi_t afi;
2814 safi_t safi;
2815 struct bgp_node *rd_rn, *rn;
2816 struct bgp_table *table;
2817 struct bgp_info *ri;
db0e1937
MK
2818
2819 afi = AFI_L2VPN;
2820 safi = SAFI_EVPN;
2821
2822 /* Walk entire global routing table and evaluate routes which could be
2823 * imported into this VPN. Note that we cannot just look at the routes
2824 * for the VNI's RD -
2825 * remote routes applicable for this VNI could have any RD.
2826 */
2827 /* EVPN routes are a 2-level table. */
2828 for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
2829 rd_rn = bgp_route_next(rd_rn)) {
2830 table = (struct bgp_table *)(rd_rn->info);
2831 if (!table)
2832 continue;
2833
2834 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
2835
2836 for (ri = rn->info; ri; ri = ri->next) {
2837
2838 /* Consider "valid" remote routes applicable for
2839 * this VNI. */
2840 if (!(ri->type == ZEBRA_ROUTE_BGP
2841 && ri->sub_type == BGP_ROUTE_NORMAL))
2842 continue;
2843
60466a63 2844 if (bgp_nexthop_self(bgp, ri->attr->nexthop)) {
db0e1937
MK
2845
2846 char attr_str[BUFSIZ];
2847 char pbuf[PREFIX_STRLEN];
2848
2849 bgp_dump_attr(ri->attr, attr_str,
2850 BUFSIZ);
2851
2852 if (bgp_debug_update(ri->peer, &rn->p,
2853 NULL, 1))
2854 zlog_debug(
b682f6de 2855 "%u: prefix %s with attr %s - DENIED due to martian or self nexthop",
db0e1937
MK
2856 bgp->vrf_id,
2857 prefix2str(
60466a63 2858 &rn->p, pbuf,
db0e1937
MK
2859 sizeof(pbuf)),
2860 attr_str);
2861
2862 bgp_evpn_unimport_route(bgp, afi, safi,
2863 &rn->p, ri);
2864
60466a63
QY
2865 bgp_rib_remove(rn, ri, ri->peer, afi,
2866 safi);
db0e1937 2867 }
db0e1937
MK
2868 }
2869 }
2870 }
2871
2872 return 0;
2873}
2874
128ea8ab 2875/*
2876 * Handle del of a local MACIP.
2877 */
d62a17ae 2878int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
2879 struct ipaddr *ip)
128ea8ab 2880{
d62a17ae 2881 struct bgpevpn *vpn;
2882 struct prefix_evpn p;
128ea8ab 2883
d62a17ae 2884 if (!bgp->vnihash) {
2885 zlog_err("%u: VNI hash not created", bgp->vrf_id);
2886 return -1;
2887 }
128ea8ab 2888
d62a17ae 2889 /* Lookup VNI hash - should exist. */
2890 vpn = bgp_evpn_lookup_vni(bgp, vni);
2891 if (!vpn || !is_vni_live(vpn)) {
2892 zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP DEL",
2893 bgp->vrf_id, vni, vpn ? "not live" : "not found");
2894 return -1;
2895 }
128ea8ab 2896
d62a17ae 2897 /* Remove EVPN type-2 route and schedule for processing. */
2898 build_evpn_type2_prefix(&p, mac, ip);
2899 delete_evpn_route(bgp, vpn, &p);
128ea8ab 2900
d62a17ae 2901 return 0;
128ea8ab 2902}
2903
2904/*
2905 * Handle add of a local MACIP.
2906 */
d62a17ae 2907int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
1a98c087 2908 struct ipaddr *ip, u_char flags)
128ea8ab 2909{
d62a17ae 2910 struct bgpevpn *vpn;
2911 struct prefix_evpn p;
128ea8ab 2912
d62a17ae 2913 if (!bgp->vnihash) {
2914 zlog_err("%u: VNI hash not created", bgp->vrf_id);
2915 return -1;
2916 }
128ea8ab 2917
d62a17ae 2918 /* Lookup VNI hash - should exist. */
2919 vpn = bgp_evpn_lookup_vni(bgp, vni);
2920 if (!vpn || !is_vni_live(vpn)) {
2921 zlog_warn("%u: VNI hash entry for VNI %u %s at MACIP ADD",
2922 bgp->vrf_id, vni, vpn ? "not live" : "not found");
2923 return -1;
2924 }
128ea8ab 2925
d62a17ae 2926 /* Create EVPN type-2 route and schedule for processing. */
2927 build_evpn_type2_prefix(&p, mac, ip);
1a98c087 2928 if (update_evpn_route(bgp, vpn, &p, flags)) {
d62a17ae 2929 char buf[ETHER_ADDR_STRLEN];
2930 char buf2[INET6_ADDRSTRLEN];
128ea8ab 2931
d62a17ae 2932 zlog_err(
b34fd35d 2933 "%u:Failed to create Type-2 route, VNI %u %s MAC %s IP %s",
1a98c087 2934 bgp->vrf_id, vpn->vni,
b34fd35d 2935 CHECK_FLAG(flags, ZEBRA_MAC_TYPE_STICKY) ? "sticky gateway"
1a98c087 2936 : "",
d62a17ae 2937 prefix_mac2str(mac, buf, sizeof(buf)),
2938 ipaddr2str(ip, buf2, sizeof(buf2)));
2939 return -1;
2940 }
128ea8ab 2941
d62a17ae 2942 return 0;
128ea8ab 2943}
2944
6a8657d0
MK
2945static void link_l2vni_hash_to_l3vni(struct hash_backet *backet,
2946 struct bgp *bgp_vrf)
2947{
2948 struct bgpevpn *vpn = NULL;
2949 struct bgp *bgp_def = NULL;
2950
2951 bgp_def = bgp_get_default();
2952 assert(bgp_def);
2953
2954 vpn = (struct bgpevpn *)backet->data;
2955 if (vpn->tenant_vrf_id == bgp_vrf->vrf_id)
2956 bgpevpn_link_to_l3vni(vpn);
2957}
2958
fe1dc5a3
MK
2959int bgp_evpn_local_l3vni_add(vni_t l3vni,
2960 vrf_id_t vrf_id,
2961 struct ethaddr *rmac)
2962{
2963 struct bgp *bgp_vrf = NULL; /* bgp VRF instance */
2964 struct bgp *bgp_def = NULL; /* default bgp instance */
f1f8b53c
MK
2965 struct listnode *node = NULL;
2966 struct bgpevpn *vpn = NULL;
fe1dc5a3
MK
2967 as_t as = 0;
2968
2969 /* get the default instamce - required to get the AS number for VRF
2970 * auto-creation*/
2971 bgp_def = bgp_get_default();
2972 if (!bgp_def) {
2973 zlog_err("Cannot process L3VNI %u ADD - default BGP instance not yet created",
2974 l3vni);
2975 return -1;
2976 }
2977 as = bgp_def->as;
2978
2979 /* if the BGP vrf instance doesnt exist - create one */
2980 bgp_vrf = bgp_lookup_by_vrf_id(vrf_id);
2981 if (!bgp_vrf) {
2982
2983 int ret = 0;
2984
2985 ret = bgp_get(&bgp_vrf, &as, vrf_id_to_name(vrf_id),
2986 BGP_INSTANCE_TYPE_VRF);
2987 switch (ret) {
2988 case BGP_ERR_MULTIPLE_INSTANCE_NOT_SET:
2989 zlog_err("'bgp multiple-instance' not present\n");
2990 return -1;
2991 case BGP_ERR_AS_MISMATCH:
2992 zlog_err("BGP is already running; AS is %u\n", as);
2993 return -1;
2994 case BGP_ERR_INSTANCE_MISMATCH:
2995 zlog_err("BGP instance name and AS number mismatch\n");
2996 return -1;
2997 }
2998
2999 /* mark as auto created */
3000 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_AUTO);
3001 }
3002
3003 /* associate with l3vni */
3004 bgp_vrf->l3vni = l3vni;
3005
3006 /* set the router mac - to be used in mac-ip routes for this vrf */
3007 memcpy(&bgp_vrf->rmac, rmac, sizeof(struct ethaddr));
3008
c581d8b0
MK
3009 /* auto derive RD/RT */
3010 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD))
3011 evpn_auto_rt_import_add_for_vrf(bgp_vrf);
3012 if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD))
3013 evpn_auto_rt_export_add_for_vrf(bgp_vrf);
fe1dc5a3 3014
6a8657d0
MK
3015 /* link all corresponding l2vnis */
3016 hash_iterate(bgp_def->vnihash,
3017 (void (*)(struct hash_backet *, void *))
3018 link_l2vni_hash_to_l3vni,
3019 bgp_vrf);
3020
f1f8b53c
MK
3021 /* updates all corresponding local mac-ip routes */
3022 for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn))
3023 update_routes_for_vni(bgp_def, vpn);
fe1dc5a3
MK
3024
3025 //TODO_MITESH: import all the remote routes to VRF
3026
3027 return 0;
3028}
3029
3030int bgp_evpn_local_l3vni_del(vni_t l3vni,
3031 vrf_id_t vrf_id)
3032{
3033 struct bgp *bgp_vrf = NULL; /* bgp vrf instance */
f1f8b53c
MK
3034 struct bgp *bgp_def = NULL; /* default bgp instance */
3035 struct listnode *node = NULL;
3036 struct bgpevpn *vpn = NULL;
fe1dc5a3
MK
3037
3038 bgp_vrf = bgp_lookup_by_vrf_id(vrf_id);
3039 if (!bgp_vrf) {
3040 zlog_err("Cannot process L3VNI %u Del - Could not find BGP instance",
3041 l3vni);
3042 return -1;
3043 }
3044
f1f8b53c
MK
3045 bgp_def = bgp_get_default();
3046 if (!bgp_def) {
3047 zlog_err("Cannot process L3VNI %u Del - Could not find default BGP instance",
3048 l3vni);
3049 return -1;
3050 }
3051
fe1dc5a3
MK
3052 /* remove the l3vni from vrf instance */
3053 bgp_vrf->l3vni = 0;
3054
3055 /* remove the Rmac from the BGP vrf */
3056 memset(&bgp_vrf->rmac, 0, sizeof(struct ethaddr));
3057
c581d8b0
MK
3058 /* delete RD/RT */
3059 if (bgp_vrf->vrf_import_rtl && !list_isempty(bgp_vrf->vrf_import_rtl))
3060 list_delete(bgp_vrf->vrf_import_rtl);
3061 if (bgp_vrf->vrf_export_rtl && !list_isempty(bgp_vrf->vrf_export_rtl))
3062 list_delete(bgp_vrf->vrf_export_rtl);
fe1dc5a3 3063
f1f8b53c
MK
3064 /* update all corresponding local mac-ip routes */
3065 for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn))
3066 update_routes_for_vni(bgp_def, vpn);
fe1dc5a3
MK
3067
3068 /* TODO_MITESH: unimport remote routes from VRF */
3069
3070 /* Delete the instance if it was autocreated */
3071 if (CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_AUTO))
3072 bgp_delete(bgp_vrf);
3073
3074 return 0;
3075}
3076
128ea8ab 3077/*
3078 * Handle del of a local VNI.
3079 */
d62a17ae 3080int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni)
128ea8ab 3081{
d62a17ae 3082 struct bgpevpn *vpn;
128ea8ab 3083
d62a17ae 3084 if (!bgp->vnihash) {
3085 zlog_err("%u: VNI hash not created", bgp->vrf_id);
3086 return -1;
3087 }
128ea8ab 3088
d62a17ae 3089 /* Locate VNI hash */
3090 vpn = bgp_evpn_lookup_vni(bgp, vni);
3091 if (!vpn) {
3092 zlog_warn("%u: VNI hash entry for VNI %u not found at DEL",
3093 bgp->vrf_id, vni);
3094 return 0;
3095 }
128ea8ab 3096
d62a17ae 3097 /* Remove all local EVPN routes and schedule for processing (to
3098 * withdraw from peers).
3099 */
3100 delete_routes_for_vni(bgp, vpn);
128ea8ab 3101
db0e1937
MK
3102 /*
3103 * tunnel is no longer active, del tunnel ip address from tip_hash
3104 */
3105 bgp_tip_del(bgp, &vpn->originator_ip);
3106
d62a17ae 3107 /* Clear "live" flag and see if hash needs to be freed. */
3108 UNSET_FLAG(vpn->flags, VNI_FLAG_LIVE);
3109 if (!is_vni_configured(vpn))
3110 bgp_evpn_free(bgp, vpn);
128ea8ab 3111
d62a17ae 3112 return 0;
128ea8ab 3113}
3114
3115/*
3116 * Handle add (or update) of a local VNI. The only VNI change we care
3117 * about is change to local-tunnel-ip.
3118 */
d62a17ae 3119int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
29c53922
MK
3120 struct in_addr originator_ip,
3121 vrf_id_t tenant_vrf_id)
d62a17ae 3122{
3123 struct bgpevpn *vpn;
3124 struct prefix_evpn p;
3125
3126 if (!bgp->vnihash) {
3127 zlog_err("%u: VNI hash not created", bgp->vrf_id);
3128 return -1;
3129 }
3130
3131 /* Lookup VNI. If present and no change, exit. */
3132 vpn = bgp_evpn_lookup_vni(bgp, vni);
ddd16ed5 3133 if (vpn) {
29c53922
MK
3134
3135 /* update tenant_vrf_id if required */
6a8657d0
MK
3136 if (vpn->tenant_vrf_id != tenant_vrf_id) {
3137 bgpevpn_unlink_from_l3vni(vpn);
29c53922 3138 vpn->tenant_vrf_id = tenant_vrf_id;
6a8657d0
MK
3139 bgpevpn_link_to_l3vni(vpn);
3140 }
29c53922 3141
2f1ac16a
MK
3142 if (is_vni_live(vpn)
3143 && IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip))
d62a17ae 3144 /* Probably some other param has changed that we don't
3145 * care about. */
3146 return 0;
3147
3148 /* Local tunnel endpoint IP address has changed */
ddd16ed5 3149 handle_tunnel_ip_change(bgp, vpn, originator_ip);
d62a17ae 3150 }
3151
3152 /* Create or update as appropriate. */
3153 if (!vpn) {
29c53922 3154 vpn = bgp_evpn_new(bgp, vni, originator_ip, tenant_vrf_id);
d62a17ae 3155 if (!vpn) {
3156 zlog_err(
3157 "%u: Failed to allocate VNI entry for VNI %u - at Add",
3158 bgp->vrf_id, vni);
3159 return -1;
3160 }
3161 }
3162
db0e1937 3163 /* if the VNI is live already, there is nothing more to do */
ddd16ed5
MK
3164 if (is_vni_live(vpn))
3165 return 0;
3166
d62a17ae 3167 /* Mark as "live" */
3168 SET_FLAG(vpn->flags, VNI_FLAG_LIVE);
3169
db0e1937
MK
3170 /* tunnel is now active, add tunnel-ip to db */
3171 bgp_tip_add(bgp, &originator_ip);
3172
3173 /* filter routes as nexthop database has changed */
3174 bgp_filter_evpn_routes_upon_martian_nh_change(bgp);
3175
d62a17ae 3176 /* Create EVPN type-3 route and schedule for processing. */
3177 build_evpn_type3_prefix(&p, vpn->originator_ip);
3178 if (update_evpn_route(bgp, vpn, &p, 0)) {
3179 zlog_err("%u: Type3 route creation failure for VNI %u",
3180 bgp->vrf_id, vni);
3181 return -1;
3182 }
3183
3184 /* If we have learnt and retained remote routes (VTEPs, MACs) for this
3185 * VNI,
3186 * install them.
3187 */
3188 install_routes_for_vni(bgp, vpn);
3189
d7d97010
MK
3190 /* If we are advertising gateway mac-ip
3191 It needs to be conveyed again to zebra */
3192 bgp_zebra_advertise_gw_macip(bgp, vpn->advertise_gw_macip, vpn->vni);
3193
d62a17ae 3194 return 0;
b18825eb 3195}
14c1a7bf 3196
7724c0a1 3197/*
3198 * Cleanup EVPN information on disable - Need to delete and withdraw
3199 * EVPN routes from peers.
3200 */
d62a17ae 3201void bgp_evpn_cleanup_on_disable(struct bgp *bgp)
7724c0a1 3202{
9d303b37
DL
3203 hash_iterate(bgp->vnihash, (void (*)(struct hash_backet *,
3204 void *))cleanup_vni_on_disable,
3205 bgp);
7724c0a1 3206}
3207
14c1a7bf 3208/*
3209 * Cleanup EVPN information - invoked at the time of bgpd exit or when the
3210 * BGP instance (default) is being freed.
3211 */
d62a17ae 3212void bgp_evpn_cleanup(struct bgp *bgp)
14c1a7bf 3213{
d62a17ae 3214 if (bgp->vnihash)
9d303b37
DL
3215 hash_iterate(bgp->vnihash, (void (*)(struct hash_backet *,
3216 void *))free_vni_entry,
3217 bgp);
d62a17ae 3218 if (bgp->import_rt_hash)
3219 hash_free(bgp->import_rt_hash);
3220 bgp->import_rt_hash = NULL;
3221 if (bgp->vnihash)
3222 hash_free(bgp->vnihash);
3223 bgp->vnihash = NULL;
c581d8b0
MK
3224 if (bgp->vrf_import_rtl)
3225 list_delete(bgp->vrf_import_rtl);
3226 bgp->vrf_import_rtl = NULL;
3227 if (bgp->vrf_export_rtl)
3228 list_delete(bgp->vrf_export_rtl);
3229 bgp->vrf_export_rtl = NULL;
6a8657d0
MK
3230 if (bgp->l2vnis)
3231 list_delete(bgp->l2vnis);
3232 bgp->l2vnis = NULL;
d62a17ae 3233 bf_free(bgp->rd_idspace);
14c1a7bf 3234}
3235
3236/*
3237 * Initialization for EVPN
3238 * Create
3239 * VNI hash table
3240 * hash for RT to VNI
3241 * unique rd id space for auto derivation of RD for VNIs
3242 */
d62a17ae 3243void bgp_evpn_init(struct bgp *bgp)
3244{
3245 bgp->vnihash =
3246 hash_create(vni_hash_key_make, vni_hash_cmp, "BGP VNI Hash");
3247 bgp->import_rt_hash =
3248 hash_create(import_rt_hash_key_make, import_rt_hash_cmp,
3249 "BGP Import RT Hash");
c581d8b0
MK
3250 bgp->vrf_import_rtl = list_new();
3251 bgp->vrf_import_rtl->cmp =
3252 (int (*)(void *, void *))evpn_route_target_cmp;
3253
3254 bgp->vrf_export_rtl = list_new();
3255 bgp->vrf_export_rtl->cmp =
3256 (int (*)(void *, void *))evpn_route_target_cmp;
6a8657d0
MK
3257 bgp->l2vnis = list_new();
3258 bgp->l2vnis->cmp =
3259 (int (*)(void *, void *))vni_hash_cmp;
d62a17ae 3260 bf_init(bgp->rd_idspace, UINT16_MAX);
3261 /*assign 0th index in the bitfield, so that we start with id 1*/
3262 bf_assign_zero_index(bgp->rd_idspace);
14c1a7bf 3263}