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