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