]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_mplsvpn.c
Merge pull request #4885 from satheeshkarra/pim_mlag
[mirror_frr.git] / bgpd / bgp_mplsvpn.c
1 /* MPLS-VPN
2 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "command.h"
24 #include "prefix.h"
25 #include "log.h"
26 #include "memory.h"
27 #include "stream.h"
28 #include "queue.h"
29 #include "filter.h"
30 #include "mpls.h"
31 #include "json.h"
32 #include "zclient.h"
33
34 #include "bgpd/bgpd.h"
35 #include "bgpd/bgp_debug.h"
36 #include "bgpd/bgp_errors.h"
37 #include "bgpd/bgp_table.h"
38 #include "bgpd/bgp_route.h"
39 #include "bgpd/bgp_attr.h"
40 #include "bgpd/bgp_label.h"
41 #include "bgpd/bgp_mplsvpn.h"
42 #include "bgpd/bgp_packet.h"
43 #include "bgpd/bgp_vty.h"
44 #include "bgpd/bgp_vpn.h"
45 #include "bgpd/bgp_ecommunity.h"
46 #include "bgpd/bgp_zebra.h"
47 #include "bgpd/bgp_nexthop.h"
48 #include "bgpd/bgp_nht.h"
49 #include "bgpd/bgp_evpn.h"
50
51 #if ENABLE_BGP_VNC
52 #include "bgpd/rfapi/rfapi_backend.h"
53 #endif
54
55 /*
56 * Definitions and external declarations.
57 */
58 extern struct zclient *zclient;
59
60 extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
61 int *index, afi_t *afi)
62 {
63 int ret = 0;
64 if (argv_find(argv, argc, "vpnv4", index)) {
65 ret = 1;
66 if (afi)
67 *afi = AFI_IP;
68 } else if (argv_find(argv, argc, "vpnv6", index)) {
69 ret = 1;
70 if (afi)
71 *afi = AFI_IP6;
72 }
73 return ret;
74 }
75
76 uint32_t decode_label(mpls_label_t *label_pnt)
77 {
78 uint32_t l;
79 uint8_t *pnt = (uint8_t *)label_pnt;
80
81 l = ((uint32_t)*pnt++ << 12);
82 l |= (uint32_t)*pnt++ << 4;
83 l |= (uint32_t)((*pnt & 0xf0) >> 4);
84 return l;
85 }
86
87 void encode_label(mpls_label_t label, mpls_label_t *label_pnt)
88 {
89 uint8_t *pnt = (uint8_t *)label_pnt;
90 if (pnt == NULL)
91 return;
92 if (label == BGP_PREVENT_VRF_2_VRF_LEAK) {
93 *label_pnt = label;
94 return;
95 }
96 *pnt++ = (label >> 12) & 0xff;
97 *pnt++ = (label >> 4) & 0xff;
98 *pnt++ = ((label << 4) + 1) & 0xff; /* S=1 */
99 }
100
101 int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
102 struct bgp_nlri *packet)
103 {
104 uint8_t *pnt;
105 uint8_t *lim;
106 struct prefix p;
107 int psize = 0;
108 int prefixlen;
109 uint16_t type;
110 struct rd_as rd_as;
111 struct rd_ip rd_ip;
112 struct prefix_rd prd = {0};
113 mpls_label_t label = {0};
114 afi_t afi;
115 safi_t safi;
116 int addpath_encoded;
117 uint32_t addpath_id;
118
119 /* Make prefix_rd */
120 prd.family = AF_UNSPEC;
121 prd.prefixlen = 64;
122
123 pnt = packet->nlri;
124 lim = pnt + packet->length;
125 afi = packet->afi;
126 safi = packet->safi;
127 addpath_id = 0;
128
129 addpath_encoded =
130 (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
131 && CHECK_FLAG(peer->af_cap[afi][safi],
132 PEER_CAP_ADDPATH_AF_TX_RCV));
133
134 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
135 for (; pnt < lim; pnt += psize) {
136 /* Clear prefix structure. */
137 memset(&p, 0, sizeof(struct prefix));
138
139 if (addpath_encoded) {
140
141 /* When packet overflow occurs return immediately. */
142 if (pnt + BGP_ADDPATH_ID_LEN > lim)
143 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
144
145 addpath_id = ntohl(*((uint32_t *)pnt));
146 pnt += BGP_ADDPATH_ID_LEN;
147 }
148
149 /* Fetch prefix length. */
150 prefixlen = *pnt++;
151 p.family = afi2family(packet->afi);
152 psize = PSIZE(prefixlen);
153
154 if (prefixlen < VPN_PREFIXLEN_MIN_BYTES * 8) {
155 flog_err(
156 EC_BGP_UPDATE_RCV,
157 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
158 peer->host, prefixlen);
159 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
160 }
161
162 /* sanity check against packet data */
163 if ((pnt + psize) > lim) {
164 flog_err(
165 EC_BGP_UPDATE_RCV,
166 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
167 peer->host, prefixlen, (uint)(lim - pnt));
168 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
169 }
170
171 /* sanity check against storage for the IP address portion */
172 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t)sizeof(p.u)) {
173 flog_err(
174 EC_BGP_UPDATE_RCV,
175 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
176 peer->host,
177 prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
178 sizeof(p.u));
179 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
180 }
181
182 /* Sanity check against max bitlen of the address family */
183 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen(&p)) {
184 flog_err(
185 EC_BGP_UPDATE_RCV,
186 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
187 peer->host,
188 prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
189 p.family, prefix_blen(&p));
190 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
191 }
192
193 /* Copy label to prefix. */
194 memcpy(&label, pnt, BGP_LABEL_BYTES);
195 bgp_set_valid_label(&label);
196
197 /* Copy routing distinguisher to rd. */
198 memcpy(&prd.val, pnt + BGP_LABEL_BYTES, 8);
199
200 /* Decode RD type. */
201 type = decode_rd_type(pnt + BGP_LABEL_BYTES);
202
203 switch (type) {
204 case RD_TYPE_AS:
205 decode_rd_as(pnt + 5, &rd_as);
206 break;
207
208 case RD_TYPE_AS4:
209 decode_rd_as4(pnt + 5, &rd_as);
210 break;
211
212 case RD_TYPE_IP:
213 decode_rd_ip(pnt + 5, &rd_ip);
214 break;
215
216 #if ENABLE_BGP_VNC
217 case RD_TYPE_VNC_ETH:
218 break;
219 #endif
220
221 default:
222 flog_err(EC_BGP_UPDATE_RCV, "Unknown RD type %d", type);
223 break; /* just report */
224 }
225
226 p.prefixlen =
227 prefixlen
228 - VPN_PREFIXLEN_MIN_BYTES * 8; /* exclude label & RD */
229 memcpy(p.u.val, pnt + VPN_PREFIXLEN_MIN_BYTES,
230 psize - VPN_PREFIXLEN_MIN_BYTES);
231
232 if (attr) {
233 bgp_update(peer, &p, addpath_id, attr, packet->afi,
234 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
235 BGP_ROUTE_NORMAL, &prd, &label, 1, 0, NULL);
236 } else {
237 bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
238 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
239 BGP_ROUTE_NORMAL, &prd, &label, 1, NULL);
240 }
241 }
242 /* Packet length consistency check. */
243 if (pnt != lim) {
244 flog_err(
245 EC_BGP_UPDATE_RCV,
246 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
247 peer->host, lim - pnt);
248 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
249 }
250
251 return 0;
252 #undef VPN_PREFIXLEN_MIN_BYTES
253 }
254
255 /*
256 * This function informs zebra of the label this vrf sets on routes
257 * leaked to VPN. Zebra should install this label in the kernel with
258 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
259 *
260 * Sending this vrf-label association is qualified by a) whether vrf->vpn
261 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
262 * are set) and b) whether vpn-policy label is set.
263 *
264 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
265 * for this vrf, which zebra interprets to mean "delete this vrf-label
266 * association."
267 */
268 void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi)
269 {
270 mpls_label_t label = MPLS_LABEL_NONE;
271 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
272
273 if (bgp->vrf_id == VRF_UNKNOWN) {
274 if (debug) {
275 zlog_debug(
276 "%s: vrf %s: afi %s: vrf_id not set, "
277 "can't set zebra vrf label",
278 __func__, bgp->name_pretty, afi2str(afi));
279 }
280 return;
281 }
282
283 if (vpn_leak_to_vpn_active(bgp, afi, NULL)) {
284 label = bgp->vpn_policy[afi].tovpn_label;
285 }
286
287 if (debug) {
288 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
289 __func__, bgp->name_pretty, afi2str(afi), label,
290 bgp->vrf_id);
291 }
292
293 if (label == BGP_PREVENT_VRF_2_VRF_LEAK)
294 label = MPLS_LABEL_NONE;
295 zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
296 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
297 }
298
299 /*
300 * If zebra tells us vrf has become unconfigured, tell zebra not to
301 * use this label to forward to the vrf anymore
302 */
303 void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi)
304 {
305 mpls_label_t label = MPLS_LABEL_NONE;
306 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
307
308 if (bgp->vrf_id == VRF_UNKNOWN) {
309 if (debug) {
310 zlog_debug(
311 "%s: vrf_id not set, can't delete zebra vrf label",
312 __func__);
313 }
314 return;
315 }
316
317 if (debug) {
318 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__,
319 bgp->name_pretty, bgp->vrf_id);
320 }
321
322 zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
323 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
324 }
325
326 int vpn_leak_label_callback(
327 mpls_label_t label,
328 void *labelid,
329 bool allocated)
330 {
331 struct vpn_policy *vp = (struct vpn_policy *)labelid;
332 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
333
334 if (debug)
335 zlog_debug("%s: label=%u, allocated=%d",
336 __func__, label, allocated);
337
338 if (!allocated) {
339 /*
340 * previously-allocated label is now invalid
341 */
342 if (CHECK_FLAG(vp->flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO) &&
343 (vp->tovpn_label != MPLS_LABEL_NONE)) {
344
345 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
346 vp->afi, bgp_get_default(), vp->bgp);
347 vp->tovpn_label = MPLS_LABEL_NONE;
348 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
349 vp->afi, bgp_get_default(), vp->bgp);
350 }
351 return 0;
352 }
353
354 /*
355 * New label allocation
356 */
357 if (!CHECK_FLAG(vp->flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) {
358
359 /*
360 * not currently configured for auto label, reject allocation
361 */
362 return -1;
363 }
364
365 if (vp->tovpn_label != MPLS_LABEL_NONE) {
366 if (label == vp->tovpn_label) {
367 /* already have same label, accept but do nothing */
368 return 0;
369 }
370 /* Shouldn't happen: different label allocation */
371 flog_err(EC_BGP_LABEL,
372 "%s: %s had label %u but got new assignment %u",
373 __func__, vp->bgp->name_pretty, vp->tovpn_label,
374 label);
375 /* use new one */
376 }
377
378 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
379 vp->afi, bgp_get_default(), vp->bgp);
380 vp->tovpn_label = label;
381 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
382 vp->afi, bgp_get_default(), vp->bgp);
383
384 return 0;
385 }
386
387 static int ecom_intersect(struct ecommunity *e1, struct ecommunity *e2)
388 {
389 int i;
390 int j;
391
392 if (!e1 || !e2)
393 return 0;
394
395 for (i = 0; i < e1->size; ++i) {
396 for (j = 0; j < e2->size; ++j) {
397 if (!memcmp(e1->val + (i * ECOMMUNITY_SIZE),
398 e2->val + (j * ECOMMUNITY_SIZE),
399 ECOMMUNITY_SIZE)) {
400
401 return 1;
402 }
403 }
404 }
405 return 0;
406 }
407
408 static bool labels_same(struct bgp_path_info *bpi, mpls_label_t *label,
409 uint32_t n)
410 {
411 uint32_t i;
412
413 if (!bpi->extra) {
414 if (!n)
415 return true;
416 else
417 return false;
418 }
419
420 if (n != bpi->extra->num_labels)
421 return false;
422
423 for (i = 0; i < n; ++i) {
424 if (label[i] != bpi->extra->label[i])
425 return false;
426 }
427 return true;
428 }
429
430 /*
431 * make encoded route labels match specified encoded label set
432 */
433 static void setlabels(struct bgp_path_info *bpi,
434 mpls_label_t *label, /* array of labels */
435 uint32_t num_labels)
436 {
437 if (num_labels)
438 assert(label);
439 assert(num_labels <= BGP_MAX_LABELS);
440
441 if (!num_labels) {
442 if (bpi->extra)
443 bpi->extra->num_labels = 0;
444 return;
445 }
446
447 struct bgp_path_info_extra *extra = bgp_path_info_extra_get(bpi);
448 uint32_t i;
449
450 for (i = 0; i < num_labels; ++i) {
451 extra->label[i] = label[i];
452 if (!bgp_is_valid_label(&label[i])) {
453 bgp_set_valid_label(&extra->label[i]);
454 }
455 }
456 extra->num_labels = num_labels;
457 }
458
459 /*
460 * returns pointer to new bgp_path_info upon success
461 */
462 static struct bgp_path_info *
463 leak_update(struct bgp *bgp, /* destination bgp instance */
464 struct bgp_node *bn, struct attr *new_attr, /* already interned */
465 afi_t afi, safi_t safi, struct bgp_path_info *source_bpi,
466 mpls_label_t *label, uint32_t num_labels, void *parent,
467 struct bgp *bgp_orig, struct prefix *nexthop_orig,
468 int nexthop_self_flag, int debug)
469 {
470 struct prefix *p = &bn->p;
471 struct bgp_path_info *bpi;
472 struct bgp_path_info *bpi_ultimate;
473 struct bgp_path_info *new;
474 char buf_prefix[PREFIX_STRLEN];
475
476 if (debug) {
477 prefix2str(&bn->p, buf_prefix, sizeof(buf_prefix));
478 zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
479 __func__, bgp->name_pretty, buf_prefix,
480 source_bpi->type, source_bpi->sub_type);
481 }
482
483 /*
484 * Routes that are redistributed into BGP from zebra do not get
485 * nexthop tracking. However, if those routes are subsequently
486 * imported to other RIBs within BGP, the leaked routes do not
487 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
488 * in order to determine if the route we are currently leaking
489 * should have nexthop tracking, we must find the ultimate
490 * parent so we can check its sub_type.
491 *
492 * As of now, source_bpi may at most be a second-generation route
493 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
494 * Using a loop here supports more complex intra-bgp import-export
495 * schemes that could be implemented in the future.
496 *
497 */
498 for (bpi_ultimate = source_bpi;
499 bpi_ultimate->extra && bpi_ultimate->extra->parent;
500 bpi_ultimate = bpi_ultimate->extra->parent)
501 ;
502
503 /*
504 * match parent
505 */
506 for (bpi = bgp_node_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
507 if (bpi->extra && bpi->extra->parent == parent)
508 break;
509 }
510
511 if (bpi) {
512 bool labelssame = labels_same(bpi, label, num_labels);
513
514 if (attrhash_cmp(bpi->attr, new_attr) && labelssame
515 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
516
517 bgp_attr_unintern(&new_attr);
518 if (debug)
519 zlog_debug(
520 "%s: ->%s: %s: Found route, no change",
521 __func__, bgp->name_pretty,
522 buf_prefix);
523 return NULL;
524 }
525
526 /* attr is changed */
527 bgp_path_info_set_flag(bn, bpi, BGP_PATH_ATTR_CHANGED);
528
529 /* Rewrite BGP route information. */
530 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
531 bgp_path_info_restore(bn, bpi);
532 else
533 bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
534 bgp_attr_unintern(&bpi->attr);
535 bpi->attr = new_attr;
536 bpi->uptime = bgp_clock();
537
538 /*
539 * rewrite labels
540 */
541 if (!labelssame)
542 setlabels(bpi, label, num_labels);
543
544 if (nexthop_self_flag)
545 bgp_path_info_set_flag(bn, bpi, BGP_PATH_ANNC_NH_SELF);
546
547 struct bgp *bgp_nexthop = bgp;
548 int nh_valid;
549
550 if (bpi->extra && bpi->extra->bgp_orig)
551 bgp_nexthop = bpi->extra->bgp_orig;
552
553 /*
554 * No nexthop tracking for redistributed routes or for
555 * EVPN-imported routes that get leaked.
556 */
557 if (bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE ||
558 is_pi_family_evpn(bpi_ultimate))
559 nh_valid = 1;
560 else
561 /*
562 * TBD do we need to do anything about the
563 * 'connected' parameter?
564 */
565 nh_valid = bgp_find_or_add_nexthop(bgp, bgp_nexthop,
566 afi, bpi, NULL, 0);
567
568 if (debug)
569 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
570 __func__, (nh_valid ? "" : "not "),
571 bgp_nexthop->name_pretty);
572
573 if (nh_valid)
574 bgp_path_info_set_flag(bn, bpi, BGP_PATH_VALID);
575
576 /* Process change. */
577 bgp_aggregate_increment(bgp, p, bpi, afi, safi);
578 bgp_process(bgp, bn, afi, safi);
579 bgp_unlock_node(bn);
580
581 if (debug)
582 zlog_debug("%s: ->%s: %s Found route, changed attr",
583 __func__, bgp->name_pretty, buf_prefix);
584
585 return bpi;
586 }
587
588 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
589 bgp->peer_self, new_attr, bn);
590
591 if (nexthop_self_flag)
592 bgp_path_info_set_flag(bn, new, BGP_PATH_ANNC_NH_SELF);
593
594 bgp_path_info_extra_get(new);
595
596 if (num_labels)
597 setlabels(new, label, num_labels);
598
599 new->extra->parent = bgp_path_info_lock(parent);
600 bgp_lock_node((struct bgp_node *)((struct bgp_path_info *)parent)->net);
601 if (bgp_orig)
602 new->extra->bgp_orig = bgp_lock(bgp_orig);
603 if (nexthop_orig)
604 new->extra->nexthop_orig = *nexthop_orig;
605
606 /*
607 * nexthop tracking for unicast routes
608 */
609 struct bgp *bgp_nexthop = bgp;
610 int nh_valid;
611
612 if (new->extra->bgp_orig)
613 bgp_nexthop = new->extra->bgp_orig;
614
615 /*
616 * No nexthop tracking for redistributed routes because
617 * their originating protocols will do the tracking and
618 * withdraw those routes if the nexthops become unreachable
619 * This also holds good for EVPN-imported routes that get
620 * leaked.
621 */
622 if (bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE ||
623 is_pi_family_evpn(bpi_ultimate))
624 nh_valid = 1;
625 else
626 /*
627 * TBD do we need to do anything about the
628 * 'connected' parameter?
629 */
630 nh_valid = bgp_find_or_add_nexthop(bgp, bgp_nexthop,
631 afi, new, NULL, 0);
632
633 if (debug)
634 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
635 __func__, (nh_valid ? "" : "not "),
636 bgp_nexthop->name_pretty);
637 if (nh_valid)
638 bgp_path_info_set_flag(bn, new, BGP_PATH_VALID);
639
640 bgp_aggregate_increment(bgp, p, new, afi, safi);
641 bgp_path_info_add(bn, new);
642
643 bgp_unlock_node(bn);
644 bgp_process(bgp, bn, afi, safi);
645
646 if (debug)
647 zlog_debug("%s: ->%s: %s: Added new route", __func__,
648 bgp->name_pretty, buf_prefix);
649
650 return new;
651 }
652
653 /* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
654 void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
655 struct bgp *bgp_vrf, /* from */
656 struct bgp_path_info *path_vrf) /* route */
657 {
658 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
659 struct prefix *p = &path_vrf->net->p;
660 afi_t afi = family2afi(p->family);
661 struct attr static_attr = {0};
662 struct attr *new_attr = NULL;
663 safi_t safi = SAFI_MPLS_VPN;
664 mpls_label_t label_val;
665 mpls_label_t label;
666 struct bgp_node *bn;
667 const char *debugmsg;
668 int nexthop_self_flag = 0;
669
670 if (debug)
671 zlog_debug("%s: from vrf %s", __func__, bgp_vrf->name_pretty);
672
673 if (debug && path_vrf->attr->ecommunity) {
674 char *s = ecommunity_ecom2str(path_vrf->attr->ecommunity,
675 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
676
677 zlog_debug("%s: %s path_vrf->type=%d, EC{%s}", __func__,
678 bgp_vrf->name, path_vrf->type, s);
679 XFREE(MTYPE_ECOMMUNITY_STR, s);
680 }
681
682 if (!bgp_vpn)
683 return;
684
685 if (!afi) {
686 if (debug)
687 zlog_debug("%s: can't get afi of prefix", __func__);
688 return;
689 }
690
691 /* Is this route exportable into the VPN table? */
692 if (!is_route_injectable_into_vpn(path_vrf))
693 return;
694
695 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
696 if (debug)
697 zlog_debug("%s: %s skipping: %s", __func__,
698 bgp_vrf->name, debugmsg);
699 return;
700 }
701
702 bgp_attr_dup(&static_attr, path_vrf->attr); /* shallow copy */
703
704 /*
705 * route map handling
706 */
707 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
708 struct bgp_path_info info;
709 route_map_result_t ret;
710
711 memset(&info, 0, sizeof(info));
712 info.peer = bgp_vpn->peer_self;
713 info.attr = &static_attr;
714 ret = route_map_apply(
715 bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN],
716 p, RMAP_BGP, &info);
717 if (RMAP_DENYMATCH == ret) {
718 bgp_attr_flush(&static_attr); /* free any added parts */
719 if (debug)
720 zlog_debug(
721 "%s: vrf %s route map \"%s\" says DENY, returning",
722 __func__, bgp_vrf->name_pretty,
723 bgp_vrf->vpn_policy[afi]
724 .rmap[BGP_VPN_POLICY_DIR_TOVPN]
725 ->name);
726 return;
727 }
728 }
729
730 if (debug && static_attr.ecommunity) {
731 char *s = ecommunity_ecom2str(static_attr.ecommunity,
732 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
733
734 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
735 __func__, s);
736 XFREE(MTYPE_ECOMMUNITY_STR, s);
737 }
738
739 /*
740 * Add the vpn-policy rt-list
741 */
742 struct ecommunity *old_ecom;
743 struct ecommunity *new_ecom;
744
745 old_ecom = static_attr.ecommunity;
746 if (old_ecom) {
747 new_ecom = ecommunity_merge(
748 ecommunity_dup(old_ecom),
749 bgp_vrf->vpn_policy[afi]
750 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
751 if (!old_ecom->refcnt)
752 ecommunity_free(&old_ecom);
753 } else {
754 new_ecom = ecommunity_dup(
755 bgp_vrf->vpn_policy[afi]
756 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
757 }
758 static_attr.ecommunity = new_ecom;
759 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
760
761 if (debug && static_attr.ecommunity) {
762 char *s = ecommunity_ecom2str(static_attr.ecommunity,
763 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
764
765 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
766 __func__, s);
767 XFREE(MTYPE_ECOMMUNITY_STR, s);
768 }
769
770 /* Nexthop */
771 /* if policy nexthop not set, use 0 */
772 if (CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
773 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
774 struct prefix *nexthop =
775 &bgp_vrf->vpn_policy[afi].tovpn_nexthop;
776
777 switch (nexthop->family) {
778 case AF_INET:
779 /* prevent mp_nexthop_global_in <- self in bgp_route.c
780 */
781 static_attr.nexthop.s_addr = nexthop->u.prefix4.s_addr;
782
783 static_attr.mp_nexthop_global_in = nexthop->u.prefix4;
784 static_attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
785 break;
786
787 case AF_INET6:
788 static_attr.mp_nexthop_global = nexthop->u.prefix6;
789 static_attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
790 break;
791
792 default:
793 assert(0);
794 }
795 } else {
796 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
797 BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
798 if (afi == AFI_IP) {
799 /*
800 * For ipv4, copy to multiprotocol
801 * nexthop field
802 */
803 static_attr.mp_nexthop_global_in =
804 static_attr.nexthop;
805 static_attr.mp_nexthop_len =
806 BGP_ATTR_NHLEN_IPV4;
807 /*
808 * XXX Leave static_attr.nexthop
809 * intact for NHT
810 */
811 static_attr.flag &=
812 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
813 }
814 } else {
815 /* Update based on next-hop family to account for
816 * RFC 5549 (BGP unnumbered) scenario. Note that
817 * specific action is only needed for the case of
818 * IPv4 nexthops as the attr has been copied
819 * otherwise.
820 */
821 if (afi == AFI_IP
822 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf->attr)) {
823 static_attr.mp_nexthop_global_in.s_addr =
824 static_attr.nexthop.s_addr;
825 static_attr.mp_nexthop_len =
826 BGP_ATTR_NHLEN_IPV4;
827 static_attr.flag |=
828 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
829 }
830 }
831 nexthop_self_flag = 1;
832 }
833
834 label_val = bgp_vrf->vpn_policy[afi].tovpn_label;
835 if (label_val == MPLS_LABEL_NONE) {
836 encode_label(MPLS_LABEL_IMPLICIT_NULL, &label);
837 } else {
838 encode_label(label_val, &label);
839 }
840
841 /* Set originator ID to "me" */
842 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID));
843 static_attr.originator_id = bgp_vpn->router_id;
844
845
846 new_attr = bgp_attr_intern(
847 &static_attr); /* hashed refcounted everything */
848 bgp_attr_flush(&static_attr); /* free locally-allocated parts */
849
850 if (debug && new_attr->ecommunity) {
851 char *s = ecommunity_ecom2str(new_attr->ecommunity,
852 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
853
854 zlog_debug("%s: new_attr->ecommunity{%s}", __func__, s);
855 XFREE(MTYPE_ECOMMUNITY_STR, s);
856 }
857
858 /* Now new_attr is an allocated interned attr */
859
860 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
861 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
862
863 struct bgp_path_info *new_info;
864
865 new_info = leak_update(bgp_vpn, bn, new_attr, afi, safi, path_vrf,
866 &label, 1, path_vrf, bgp_vrf, NULL,
867 nexthop_self_flag, debug);
868
869 /*
870 * Routes actually installed in the vpn RIB must also be
871 * offered to all vrfs (because now they originate from
872 * the vpn RIB).
873 *
874 * Acceptance into other vrfs depends on rt-lists.
875 * Originating vrf will not accept the looped back route
876 * because of loop checking.
877 */
878 if (new_info)
879 vpn_leak_to_vrf_update(bgp_vrf, new_info);
880 }
881
882 void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
883 struct bgp *bgp_vrf, /* from */
884 struct bgp_path_info *path_vrf) /* route */
885 {
886 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
887 struct prefix *p = &path_vrf->net->p;
888 afi_t afi = family2afi(p->family);
889 safi_t safi = SAFI_MPLS_VPN;
890 struct bgp_path_info *bpi;
891 struct bgp_node *bn;
892 const char *debugmsg;
893 char buf_prefix[PREFIX_STRLEN];
894
895 if (debug) {
896 prefix2str(p, buf_prefix, sizeof(buf_prefix));
897 zlog_debug(
898 "%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
899 __func__, bgp_vrf->name_pretty, buf_prefix,
900 path_vrf->type, path_vrf->sub_type);
901 }
902
903 if (!bgp_vpn)
904 return;
905
906 if (!afi) {
907 if (debug)
908 zlog_debug("%s: can't get afi of prefix", __func__);
909 return;
910 }
911
912 /* Is this route exportable into the VPN table? */
913 if (!is_route_injectable_into_vpn(path_vrf))
914 return;
915
916 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
917 if (debug)
918 zlog_debug("%s: skipping: %s", __func__, debugmsg);
919 return;
920 }
921
922 if (debug)
923 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__, path_vrf);
924
925 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
926 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
927
928 if (!bn)
929 return;
930 /*
931 * vrf -> vpn
932 * match original bpi imported from
933 */
934 for (bpi = bgp_node_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
935 if (bpi->extra && bpi->extra->parent == path_vrf) {
936 break;
937 }
938 }
939
940 if (bpi) {
941 /* withdraw from looped vrfs as well */
942 vpn_leak_to_vrf_withdraw(bgp_vpn, bpi);
943
944 bgp_aggregate_decrement(bgp_vpn, p, bpi, afi, safi);
945 bgp_path_info_delete(bn, bpi);
946 bgp_process(bgp_vpn, bn, afi, safi);
947 }
948 bgp_unlock_node(bn);
949 }
950
951 void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
952 struct bgp *bgp_vrf, /* from */
953 afi_t afi)
954 {
955 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
956 struct bgp_node *prn;
957 safi_t safi = SAFI_MPLS_VPN;
958
959 /*
960 * Walk vpn table, delete bpi with bgp_orig == bgp_vrf
961 */
962 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
963 prn = bgp_route_next(prn)) {
964
965 struct bgp_table *table;
966 struct bgp_node *bn;
967 struct bgp_path_info *bpi;
968
969 /* This is the per-RD table of prefixes */
970 table = bgp_node_get_bgp_table_info(prn);
971
972 if (!table)
973 continue;
974
975 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
976
977 char buf[PREFIX2STR_BUFFER];
978
979 bpi = bgp_node_get_bgp_path_info(bn);
980 if (debug && bpi) {
981 zlog_debug(
982 "%s: looking at prefix %s", __func__,
983 prefix2str(&bn->p, buf, sizeof(buf)));
984 }
985
986 for (; bpi; bpi = bpi->next) {
987 if (debug)
988 zlog_debug("%s: type %d, sub_type %d",
989 __func__, bpi->type,
990 bpi->sub_type);
991 if (bpi->sub_type != BGP_ROUTE_IMPORTED)
992 continue;
993 if (!bpi->extra)
994 continue;
995 if ((struct bgp *)bpi->extra->bgp_orig
996 == bgp_vrf) {
997 /* delete route */
998 if (debug)
999 zlog_debug("%s: deleting it",
1000 __func__);
1001 bgp_aggregate_decrement(bgp_vpn, &bn->p,
1002 bpi, afi, safi);
1003 bgp_path_info_delete(bn, bpi);
1004 bgp_process(bgp_vpn, bn, afi, safi);
1005 }
1006 }
1007 }
1008 }
1009 }
1010
1011 void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn, /* to */
1012 struct bgp *bgp_vrf, /* from */
1013 afi_t afi)
1014 {
1015 struct bgp_node *bn;
1016 struct bgp_path_info *bpi;
1017 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
1018
1019 if (debug)
1020 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__, afi,
1021 bgp_vrf->name_pretty);
1022
1023 for (bn = bgp_table_top(bgp_vrf->rib[afi][SAFI_UNICAST]); bn;
1024 bn = bgp_route_next(bn)) {
1025
1026 if (debug)
1027 zlog_debug("%s: node=%p", __func__, bn);
1028
1029 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
1030 bpi = bpi->next) {
1031 if (debug)
1032 zlog_debug(
1033 "%s: calling vpn_leak_from_vrf_update",
1034 __func__);
1035 vpn_leak_from_vrf_update(bgp_vpn, bgp_vrf, bpi);
1036 }
1037 }
1038 }
1039
1040 static void
1041 vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
1042 struct bgp *bgp_vpn, /* from */
1043 struct bgp_path_info *path_vpn) /* route */
1044 {
1045 struct prefix *p = &path_vpn->net->p;
1046 afi_t afi = family2afi(p->family);
1047
1048 struct attr static_attr = {0};
1049 struct attr *new_attr = NULL;
1050 struct bgp_node *bn;
1051 safi_t safi = SAFI_UNICAST;
1052 const char *debugmsg;
1053 struct prefix nexthop_orig;
1054 mpls_label_t *pLabels = NULL;
1055 uint32_t num_labels = 0;
1056 int nexthop_self_flag = 1;
1057 struct bgp_path_info *bpi_ultimate = NULL;
1058 int origin_local = 0;
1059 struct bgp *src_vrf;
1060
1061 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1062
1063 if (!vpn_leak_from_vpn_active(bgp_vrf, afi, &debugmsg)) {
1064 if (debug)
1065 zlog_debug("%s: skipping: %s", __func__, debugmsg);
1066 return;
1067 }
1068
1069 /* Check for intersection of route targets */
1070 if (!ecom_intersect(
1071 bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1072 path_vpn->attr->ecommunity)) {
1073
1074 return;
1075 }
1076
1077 if (debug) {
1078 char buf_prefix[PREFIX_STRLEN];
1079
1080 prefix2str(p, buf_prefix, sizeof(buf_prefix));
1081 zlog_debug("%s: updating %s to vrf %s", __func__,
1082 buf_prefix, bgp_vrf->name_pretty);
1083 }
1084
1085 bgp_attr_dup(&static_attr, path_vpn->attr); /* shallow copy */
1086
1087 /*
1088 * Nexthop: stash and clear
1089 *
1090 * Nexthop is valid in context of VPN core, but not in destination vrf.
1091 * Stash it for later label resolution by vrf ingress path and then
1092 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1093 */
1094 uint8_t nhfamily = NEXTHOP_FAMILY(path_vpn->attr->mp_nexthop_len);
1095
1096 memset(&nexthop_orig, 0, sizeof(nexthop_orig));
1097 nexthop_orig.family = nhfamily;
1098
1099 switch (nhfamily) {
1100 case AF_INET:
1101 /* save */
1102 nexthop_orig.u.prefix4 = path_vpn->attr->mp_nexthop_global_in;
1103 nexthop_orig.prefixlen = 32;
1104
1105 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1106 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1107 static_attr.nexthop.s_addr =
1108 nexthop_orig.u.prefix4.s_addr;
1109
1110 static_attr.mp_nexthop_global_in =
1111 path_vpn->attr->mp_nexthop_global_in;
1112 static_attr.mp_nexthop_len =
1113 path_vpn->attr->mp_nexthop_len;
1114 }
1115 static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
1116 break;
1117 case AF_INET6:
1118 /* save */
1119 nexthop_orig.u.prefix6 = path_vpn->attr->mp_nexthop_global;
1120 nexthop_orig.prefixlen = 128;
1121
1122 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1123 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1124 static_attr.mp_nexthop_global = nexthop_orig.u.prefix6;
1125 }
1126 break;
1127 }
1128
1129 /*
1130 * route map handling
1131 */
1132 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
1133 struct bgp_path_info info;
1134 route_map_result_t ret;
1135
1136 memset(&info, 0, sizeof(info));
1137 info.peer = bgp_vrf->peer_self;
1138 info.attr = &static_attr;
1139 info.extra = path_vpn->extra; /* Used for source-vrf filter */
1140 ret = route_map_apply(bgp_vrf->vpn_policy[afi]
1141 .rmap[BGP_VPN_POLICY_DIR_FROMVPN],
1142 p, RMAP_BGP, &info);
1143 if (RMAP_DENYMATCH == ret) {
1144 bgp_attr_flush(&static_attr); /* free any added parts */
1145 if (debug)
1146 zlog_debug(
1147 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
1148 __func__, bgp_vrf->name_pretty,
1149 bgp_vrf->vpn_policy[afi]
1150 .rmap[BGP_VPN_POLICY_DIR_FROMVPN]
1151 ->name);
1152 return;
1153 }
1154 /*
1155 * if route-map changed nexthop, don't nexthop-self on output
1156 */
1157 if (!CHECK_FLAG(static_attr.rmap_change_flags,
1158 BATTR_RMAP_NEXTHOP_UNCHANGED))
1159 nexthop_self_flag = 0;
1160 }
1161
1162 new_attr = bgp_attr_intern(&static_attr);
1163 bgp_attr_flush(&static_attr);
1164
1165 bn = bgp_afi_node_get(bgp_vrf->rib[afi][safi], afi, safi, p, NULL);
1166
1167 /*
1168 * ensure labels are copied
1169 *
1170 * However, there is a special case: if the route originated in
1171 * another local VRF (as opposed to arriving via VPN), then the
1172 * nexthop is reached by hairpinning through this router (me)
1173 * using IP forwarding only (no LSP). Therefore, the route
1174 * imported to the VRF should not have labels attached. Note
1175 * that nexthop tracking is also involved: eliminating the
1176 * labels for these routes enables the non-labeled nexthops
1177 * from the originating VRF to be considered valid for this route.
1178 */
1179 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1180 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1181 /* work back to original route */
1182 for (bpi_ultimate = path_vpn;
1183 bpi_ultimate->extra && bpi_ultimate->extra->parent;
1184 bpi_ultimate = bpi_ultimate->extra->parent)
1185 ;
1186
1187 /*
1188 * if original route was unicast,
1189 * then it did not arrive over vpn
1190 */
1191 if (bpi_ultimate->net) {
1192 struct bgp_table *table;
1193
1194 table = bgp_node_table(bpi_ultimate->net);
1195 if (table && (table->safi == SAFI_UNICAST))
1196 origin_local = 1;
1197 }
1198
1199 /* copy labels */
1200 if (!origin_local && path_vpn->extra
1201 && path_vpn->extra->num_labels) {
1202 num_labels = path_vpn->extra->num_labels;
1203 if (num_labels > BGP_MAX_LABELS)
1204 num_labels = BGP_MAX_LABELS;
1205 pLabels = path_vpn->extra->label;
1206 }
1207 }
1208
1209 if (debug) {
1210 char buf_prefix[PREFIX_STRLEN];
1211 prefix2str(p, buf_prefix, sizeof(buf_prefix));
1212 zlog_debug("%s: pfx %s: num_labels %d", __func__, buf_prefix,
1213 num_labels);
1214 }
1215
1216 /*
1217 * For VRF-2-VRF route-leaking,
1218 * the source will be the originating VRF.
1219 */
1220 if (path_vpn->extra && path_vpn->extra->bgp_orig)
1221 src_vrf = path_vpn->extra->bgp_orig;
1222 else
1223 src_vrf = bgp_vpn;
1224
1225 leak_update(bgp_vrf, bn, new_attr, afi, safi, path_vpn, pLabels,
1226 num_labels, path_vpn, /* parent */
1227 src_vrf, &nexthop_orig, nexthop_self_flag, debug);
1228 }
1229
1230 void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
1231 struct bgp_path_info *path_vpn) /* route */
1232 {
1233 struct listnode *mnode, *mnnode;
1234 struct bgp *bgp;
1235
1236 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1237
1238 if (debug)
1239 zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
1240
1241 /* Loop over VRFs */
1242 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
1243
1244 if (!path_vpn->extra
1245 || path_vpn->extra->bgp_orig != bgp) { /* no loop */
1246 vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, path_vpn);
1247 }
1248 }
1249 }
1250
1251 void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
1252 struct bgp_path_info *path_vpn) /* route */
1253 {
1254 struct prefix *p;
1255 afi_t afi;
1256 safi_t safi = SAFI_UNICAST;
1257 struct bgp *bgp;
1258 struct listnode *mnode, *mnnode;
1259 struct bgp_node *bn;
1260 struct bgp_path_info *bpi;
1261 const char *debugmsg;
1262 char buf_prefix[PREFIX_STRLEN];
1263
1264 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1265
1266 if (debug) {
1267 prefix2str(&path_vpn->net->p, buf_prefix, sizeof(buf_prefix));
1268 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d", __func__,
1269 buf_prefix, path_vpn->type, path_vpn->sub_type);
1270 }
1271
1272 if (debug)
1273 zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
1274
1275 if (!path_vpn->net) {
1276 #if ENABLE_BGP_VNC
1277 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
1278 if (path_vpn->type == ZEBRA_ROUTE_BGP
1279 && path_vpn->sub_type == BGP_ROUTE_RFP) {
1280
1281 return;
1282 }
1283 #endif
1284 if (debug)
1285 zlog_debug(
1286 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
1287 __func__);
1288 return;
1289 }
1290
1291 p = &path_vpn->net->p;
1292 afi = family2afi(p->family);
1293
1294 /* Loop over VRFs */
1295 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
1296 if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
1297 if (debug)
1298 zlog_debug("%s: skipping: %s", __func__,
1299 debugmsg);
1300 continue;
1301 }
1302
1303 /* Check for intersection of route targets */
1304 if (!ecom_intersect(bgp->vpn_policy[afi]
1305 .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1306 path_vpn->attr->ecommunity)) {
1307
1308 continue;
1309 }
1310
1311 if (debug)
1312 zlog_debug("%s: withdrawing from vrf %s", __func__,
1313 bgp->name_pretty);
1314
1315 bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
1316
1317 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
1318 bpi = bpi->next) {
1319 if (bpi->extra
1320 && (struct bgp_path_info *)bpi->extra->parent
1321 == path_vpn) {
1322 break;
1323 }
1324 }
1325
1326 if (bpi) {
1327 if (debug)
1328 zlog_debug("%s: deleting bpi %p", __func__,
1329 bpi);
1330 bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
1331 bgp_path_info_delete(bn, bpi);
1332 bgp_process(bgp, bn, afi, safi);
1333 }
1334 bgp_unlock_node(bn);
1335 }
1336 }
1337
1338 void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
1339 afi_t afi)
1340 {
1341 struct bgp_node *bn;
1342 struct bgp_path_info *bpi;
1343 safi_t safi = SAFI_UNICAST;
1344 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1345
1346 if (debug)
1347 zlog_debug("%s: entry", __func__);
1348 /*
1349 * Walk vrf table, delete bpi with bgp_orig in a different vrf
1350 */
1351 for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
1352 bn = bgp_route_next(bn)) {
1353
1354 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
1355 bpi = bpi->next) {
1356 if (bpi->extra
1357 && bpi->extra->bgp_orig != bgp_vrf
1358 && bpi->extra->parent
1359 && is_pi_family_vpn(bpi->extra->parent)) {
1360
1361 /* delete route */
1362 bgp_aggregate_decrement(bgp_vrf, &bn->p, bpi,
1363 afi, safi);
1364 bgp_path_info_delete(bn, bpi);
1365 bgp_process(bgp_vrf, bn, afi, safi);
1366 }
1367 }
1368 }
1369 }
1370
1371 void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
1372 struct bgp *bgp_vpn, /* from */
1373 afi_t afi)
1374 {
1375 struct prefix_rd prd;
1376 struct bgp_node *prn;
1377 safi_t safi = SAFI_MPLS_VPN;
1378
1379 assert(bgp_vpn);
1380
1381 /*
1382 * Walk vpn table
1383 */
1384 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
1385 prn = bgp_route_next(prn)) {
1386
1387 struct bgp_table *table;
1388 struct bgp_node *bn;
1389 struct bgp_path_info *bpi;
1390
1391 memset(&prd, 0, sizeof(prd));
1392 prd.family = AF_UNSPEC;
1393 prd.prefixlen = 64;
1394 memcpy(prd.val, prn->p.u.val, 8);
1395
1396 /* This is the per-RD table of prefixes */
1397 table = bgp_node_get_bgp_table_info(prn);
1398
1399 if (!table)
1400 continue;
1401
1402 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
1403
1404 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
1405 bpi = bpi->next) {
1406
1407 if (bpi->extra
1408 && bpi->extra->bgp_orig == bgp_vrf)
1409 continue;
1410
1411 vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
1412 bpi);
1413 }
1414 }
1415 }
1416 }
1417
1418 /*
1419 * This function is called for definition/deletion/change to a route-map
1420 */
1421 static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
1422 {
1423 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1424 afi_t afi;
1425 struct route_map *rmap;
1426
1427 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1428 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
1429
1430 return;
1431 }
1432
1433 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
1434
1435 for (afi = 0; afi < AFI_MAX; ++afi) {
1436
1437 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
1438 && !strcmp(rmap_name,
1439 bgp->vpn_policy[afi]
1440 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
1441
1442 if (debug)
1443 zlog_debug(
1444 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1445 __func__, rmap_name, bgp->as,
1446 afi2str(afi));
1447
1448 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1449 bgp_get_default(), bgp);
1450 if (debug)
1451 zlog_debug("%s: after vpn_leak_prechange",
1452 __func__);
1453
1454 /* in case of definition/deletion */
1455 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN] =
1456 rmap;
1457
1458 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1459 bgp_get_default(), bgp);
1460
1461 if (debug)
1462 zlog_debug("%s: after vpn_leak_postchange",
1463 __func__);
1464 }
1465
1466 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]
1467 && !strcmp(rmap_name,
1468 bgp->vpn_policy[afi]
1469 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN])) {
1470
1471 if (debug) {
1472 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1473 __func__, rmap_name, bgp->as,
1474 afi2str(afi));
1475 }
1476
1477 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1478 bgp_get_default(), bgp);
1479
1480 /* in case of definition/deletion */
1481 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
1482 rmap;
1483
1484 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1485 bgp_get_default(), bgp);
1486 }
1487 }
1488 }
1489
1490 /* This API is used during router-id change, reflect VPNs
1491 * auto RD and RT values and readvertise routes to VPN table.
1492 */
1493 void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
1494 bool is_config)
1495 {
1496 afi_t afi;
1497 int debug;
1498 char *vname;
1499 const char *export_name;
1500 char buf[RD_ADDRSTRLEN];
1501 struct bgp *bgp_import;
1502 struct listnode *node;
1503 struct ecommunity *ecom;
1504 vpn_policy_direction_t idir, edir;
1505
1506 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1507 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
1508 return;
1509
1510 export_name = bgp->name ? bgp->name : VRF_DEFAULT_NAME;
1511 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
1512 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
1513
1514 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1515 edir = BGP_VPN_POLICY_DIR_TOVPN;
1516
1517 for (afi = 0; afi < AFI_MAX; ++afi) {
1518 if (!vpn_leak_to_vpn_active(bgp, afi, NULL))
1519 continue;
1520
1521 if (withdraw) {
1522 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
1523 afi, bgp_get_default(), bgp);
1524 if (debug)
1525 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
1526 __func__, export_name);
1527
1528 /* Remove import RT from VRFs */
1529 ecom = bgp->vpn_policy[afi].rtlist[edir];
1530 for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
1531 export_vrf, node, vname)) {
1532 bgp_import = bgp_lookup_by_name(vname);
1533 if (!bgp_import)
1534 continue;
1535
1536 ecommunity_del_val(bgp_import->vpn_policy[afi].
1537 rtlist[idir],
1538 (struct ecommunity_val *)ecom->val);
1539
1540 }
1541 } else {
1542 /*
1543 * Router-id changes that are not explicit config
1544 * changes should not replace configured RD/RT.
1545 */
1546 if (!is_config) {
1547 if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
1548 BGP_VPN_POLICY_TOVPN_RD_SET)) {
1549 if (debug)
1550 zlog_debug("%s: auto router-id change skipped",
1551 __func__);
1552 goto postchange;
1553 }
1554 }
1555
1556 /* New router-id derive auto RD and RT and export
1557 * to VPN
1558 */
1559 form_auto_rd(bgp->router_id, bgp->vrf_rd_id,
1560 &bgp->vrf_prd_auto);
1561 bgp->vpn_policy[afi].tovpn_rd = bgp->vrf_prd_auto;
1562 prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf,
1563 sizeof(buf));
1564 bgp->vpn_policy[afi].rtlist[edir] =
1565 ecommunity_str2com(buf,
1566 ECOMMUNITY_ROUTE_TARGET, 0);
1567
1568 /* Update import_vrf rt_list */
1569 ecom = bgp->vpn_policy[afi].rtlist[edir];
1570 for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
1571 export_vrf, node, vname)) {
1572 bgp_import = bgp_lookup_by_name(vname);
1573 if (!bgp_import)
1574 continue;
1575 if (bgp_import->vpn_policy[afi].rtlist[idir])
1576 bgp_import->vpn_policy[afi].rtlist[idir]
1577 = ecommunity_merge(
1578 bgp_import->vpn_policy[afi]
1579 .rtlist[idir], ecom);
1580 else
1581 bgp_import->vpn_policy[afi].rtlist[idir]
1582 = ecommunity_dup(ecom);
1583
1584 }
1585
1586 postchange:
1587 /* Update routes to VPN */
1588 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
1589 afi, bgp_get_default(),
1590 bgp);
1591 if (debug)
1592 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
1593 __func__, export_name);
1594 }
1595 }
1596 }
1597
1598 void vpn_policy_routemap_event(const char *rmap_name)
1599 {
1600 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1601 struct listnode *mnode, *mnnode;
1602 struct bgp *bgp;
1603
1604 if (debug)
1605 zlog_debug("%s: entry", __func__);
1606
1607 if (bm->bgp == NULL) /* may be called during cleanup */
1608 return;
1609
1610 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
1611 vpn_policy_routemap_update(bgp, rmap_name);
1612 }
1613
1614 void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
1615 afi_t afi, safi_t safi)
1616 {
1617 const char *export_name;
1618 vpn_policy_direction_t idir, edir;
1619 char *vname, *tmp_name;
1620 char buf[RD_ADDRSTRLEN];
1621 struct ecommunity *ecom;
1622 bool first_export = false;
1623 int debug;
1624 struct listnode *node;
1625 bool is_inst_match = false;
1626
1627 export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
1628 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1629 edir = BGP_VPN_POLICY_DIR_TOVPN;
1630
1631 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
1632 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
1633
1634 /*
1635 * Cross-ref both VRFs. Also, note if this is the first time
1636 * any VRF is importing from "import_vrf".
1637 */
1638 vname = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
1639 : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME));
1640
1641 /* Check the import_vrf list of destination vrf for the source vrf name,
1642 * insert otherwise.
1643 */
1644 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf,
1645 node, tmp_name)) {
1646 if (strcmp(vname, tmp_name) == 0) {
1647 is_inst_match = true;
1648 break;
1649 }
1650 }
1651 if (!is_inst_match)
1652 listnode_add(to_bgp->vpn_policy[afi].import_vrf,
1653 vname);
1654
1655 /* Check if the source vrf already exports to any vrf,
1656 * first time export requires to setup auto derived RD/RT values.
1657 * Add the destination vrf name to export vrf list if it is
1658 * not present.
1659 */
1660 is_inst_match = false;
1661 vname = XSTRDUP(MTYPE_TMP, export_name);
1662 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
1663 first_export = true;
1664 } else {
1665 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
1666 node, tmp_name)) {
1667 if (strcmp(vname, tmp_name) == 0) {
1668 is_inst_match = true;
1669 break;
1670 }
1671 }
1672 }
1673 if (!is_inst_match)
1674 listnode_add(from_bgp->vpn_policy[afi].export_vrf,
1675 vname);
1676 /* Update import RT for current VRF using export RT of the VRF we're
1677 * importing from. First though, make sure "import_vrf" has that
1678 * set.
1679 */
1680 if (first_export) {
1681 form_auto_rd(from_bgp->router_id, from_bgp->vrf_rd_id,
1682 &from_bgp->vrf_prd_auto);
1683 from_bgp->vpn_policy[afi].tovpn_rd = from_bgp->vrf_prd_auto;
1684 SET_FLAG(from_bgp->vpn_policy[afi].flags,
1685 BGP_VPN_POLICY_TOVPN_RD_SET);
1686 prefix_rd2str(&from_bgp->vpn_policy[afi].tovpn_rd,
1687 buf, sizeof(buf));
1688 from_bgp->vpn_policy[afi].rtlist[edir] =
1689 ecommunity_str2com(buf, ECOMMUNITY_ROUTE_TARGET, 0);
1690 SET_FLAG(from_bgp->af_flags[afi][safi],
1691 BGP_CONFIG_VRF_TO_VRF_EXPORT);
1692 from_bgp->vpn_policy[afi].tovpn_label =
1693 BGP_PREVENT_VRF_2_VRF_LEAK;
1694 }
1695 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
1696 if (to_bgp->vpn_policy[afi].rtlist[idir])
1697 to_bgp->vpn_policy[afi].rtlist[idir] =
1698 ecommunity_merge(to_bgp->vpn_policy[afi]
1699 .rtlist[idir], ecom);
1700 else
1701 to_bgp->vpn_policy[afi].rtlist[idir] = ecommunity_dup(ecom);
1702 SET_FLAG(to_bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT);
1703
1704 if (debug) {
1705 const char *from_name;
1706
1707 from_name = from_bgp->name ? from_bgp->name :
1708 VRF_DEFAULT_NAME;
1709 zlog_debug("%s from %s to %s first_export %u import-rt %s export-rt %s",
1710 __func__, from_name, export_name, first_export,
1711 to_bgp->vpn_policy[afi].rtlist[idir] ?
1712 (ecommunity_ecom2str(to_bgp->vpn_policy[afi].
1713 rtlist[idir],
1714 ECOMMUNITY_FORMAT_ROUTE_MAP, 0)) : " ",
1715 to_bgp->vpn_policy[afi].rtlist[edir] ?
1716 (ecommunity_ecom2str(to_bgp->vpn_policy[afi].
1717 rtlist[edir],
1718 ECOMMUNITY_FORMAT_ROUTE_MAP, 0)) : " ");
1719 }
1720
1721 /* Does "import_vrf" first need to export its routes or that
1722 * is already done and we just need to import those routes
1723 * from the global table?
1724 */
1725 if (first_export)
1726 vpn_leak_postchange(edir, afi, bgp_get_default(), from_bgp);
1727 else
1728 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
1729 }
1730
1731 void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
1732 afi_t afi, safi_t safi)
1733 {
1734 const char *export_name, *tmp_name;
1735 vpn_policy_direction_t idir, edir;
1736 char *vname;
1737 struct ecommunity *ecom = NULL;
1738 struct listnode *node;
1739 int debug;
1740
1741 export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
1742 tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
1743 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1744 edir = BGP_VPN_POLICY_DIR_TOVPN;
1745
1746 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
1747 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
1748
1749 /* Were we importing from "import_vrf"? */
1750 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf, node,
1751 vname)) {
1752 if (strcmp(vname, tmp_name) == 0)
1753 break;
1754 }
1755
1756 /*
1757 * We do not check in the cli if the passed in bgp
1758 * instance is actually imported into us before
1759 * we call this function. As such if we do not
1760 * find this in the import_vrf list than
1761 * we just need to return safely.
1762 */
1763 if (!vname)
1764 return;
1765
1766 if (debug)
1767 zlog_debug("%s from %s to %s", __func__, tmp_name, export_name);
1768
1769 /* Remove "import_vrf" from our import list. */
1770 listnode_delete(to_bgp->vpn_policy[afi].import_vrf, vname);
1771 XFREE(MTYPE_TMP, vname);
1772
1773 /* Remove routes imported from "import_vrf". */
1774 /* TODO: In the current logic, we have to first remove all
1775 * imported routes and then (if needed) import back routes
1776 */
1777 vpn_leak_prechange(idir, afi, bgp_get_default(), to_bgp);
1778
1779 if (to_bgp->vpn_policy[afi].import_vrf->count == 0) {
1780 UNSET_FLAG(to_bgp->af_flags[afi][safi],
1781 BGP_CONFIG_VRF_TO_VRF_IMPORT);
1782 if (to_bgp->vpn_policy[afi].rtlist[idir])
1783 ecommunity_free(&to_bgp->vpn_policy[afi].rtlist[idir]);
1784 } else {
1785 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
1786 if (ecom)
1787 ecommunity_del_val(to_bgp->vpn_policy[afi].rtlist[idir],
1788 (struct ecommunity_val *)ecom->val);
1789 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
1790 }
1791
1792 /*
1793 * What?
1794 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
1795 * below is checking for NULL that export_vrf can be
1796 * NULL, consequently it is complaining( like a cabbage )
1797 * that we could dereference and crash in the listcount(..)
1798 * check below.
1799 * So make it happy, under protest, with liberty and justice
1800 * for all.
1801 */
1802 assert(from_bgp->vpn_policy[afi].export_vrf);
1803
1804 /* Remove us from "import_vrf's" export list. If no other VRF
1805 * is importing from "import_vrf", cleanup appropriately.
1806 */
1807 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
1808 node, vname)) {
1809 if (strcmp(vname, export_name) == 0)
1810 break;
1811 }
1812
1813 /*
1814 * If we have gotten to this point then the vname must
1815 * exist. If not, we are in a world of trouble and
1816 * have slag sitting around.
1817 *
1818 * import_vrf and export_vrf must match in having
1819 * the in/out names as appropriate.
1820 * export_vrf list could have been cleaned up
1821 * as part of no router bgp source instnace.
1822 */
1823 if (!vname)
1824 return;
1825
1826 listnode_delete(from_bgp->vpn_policy[afi].export_vrf, vname);
1827 XFREE(MTYPE_TMP, vname);
1828
1829 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
1830 vpn_leak_prechange(edir, afi, bgp_get_default(), from_bgp);
1831 ecommunity_free(&from_bgp->vpn_policy[afi].rtlist[edir]);
1832 UNSET_FLAG(from_bgp->af_flags[afi][safi],
1833 BGP_CONFIG_VRF_TO_VRF_EXPORT);
1834 memset(&from_bgp->vpn_policy[afi].tovpn_rd, 0,
1835 sizeof(struct prefix_rd));
1836 UNSET_FLAG(from_bgp->vpn_policy[afi].flags,
1837 BGP_VPN_POLICY_TOVPN_RD_SET);
1838 from_bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE;
1839
1840 }
1841 }
1842
1843 /* For testing purpose, static route of MPLS-VPN. */
1844 DEFUN (vpnv4_network,
1845 vpnv4_network_cmd,
1846 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1847 "Specify a network to announce via BGP\n"
1848 "IPv4 prefix\n"
1849 "Specify Route Distinguisher\n"
1850 "VPN Route Distinguisher\n"
1851 "VPN NLRI label (tag)\n"
1852 "VPN NLRI label (tag)\n"
1853 "Label value\n")
1854 {
1855 int idx_ipv4_prefixlen = 1;
1856 int idx_ext_community = 3;
1857 int idx_label = 5;
1858 return bgp_static_set_safi(
1859 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1860 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
1861 NULL, NULL, NULL, NULL);
1862 }
1863
1864 DEFUN (vpnv4_network_route_map,
1865 vpnv4_network_route_map_cmd,
1866 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
1867 "Specify a network to announce via BGP\n"
1868 "IPv4 prefix\n"
1869 "Specify Route Distinguisher\n"
1870 "VPN Route Distinguisher\n"
1871 "VPN NLRI label (tag)\n"
1872 "VPN NLRI label (tag)\n"
1873 "Label value\n"
1874 "route map\n"
1875 "route map name\n")
1876 {
1877 int idx_ipv4_prefixlen = 1;
1878 int idx_ext_community = 3;
1879 int idx_label = 5;
1880 int idx_word_2 = 7;
1881 return bgp_static_set_safi(
1882 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1883 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1884 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
1885 }
1886
1887 /* For testing purpose, static route of MPLS-VPN. */
1888 DEFUN (no_vpnv4_network,
1889 no_vpnv4_network_cmd,
1890 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1891 NO_STR
1892 "Specify a network to announce via BGP\n"
1893 "IPv4 prefix\n"
1894 "Specify Route Distinguisher\n"
1895 "VPN Route Distinguisher\n"
1896 "VPN NLRI label (tag)\n"
1897 "VPN NLRI label (tag)\n"
1898 "Label value\n")
1899 {
1900 int idx_ipv4_prefixlen = 2;
1901 int idx_ext_community = 4;
1902 int idx_label = 6;
1903 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
1904 argv[idx_ipv4_prefixlen]->arg,
1905 argv[idx_ext_community]->arg,
1906 argv[idx_label]->arg, 0, NULL, NULL, NULL);
1907 }
1908
1909 DEFUN (vpnv6_network,
1910 vpnv6_network_cmd,
1911 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
1912 "Specify a network to announce via BGP\n"
1913 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1914 "Specify Route Distinguisher\n"
1915 "VPN Route Distinguisher\n"
1916 "VPN NLRI label (tag)\n"
1917 "VPN NLRI label (tag)\n"
1918 "Label value\n"
1919 "route map\n"
1920 "route map name\n")
1921 {
1922 int idx_ipv6_prefix = 1;
1923 int idx_ext_community = 3;
1924 int idx_label = 5;
1925 int idx_word_2 = 7;
1926 if (argc == 8)
1927 return bgp_static_set_safi(
1928 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1929 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1930 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
1931 else
1932 return bgp_static_set_safi(
1933 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1934 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1935 NULL, 0, NULL, NULL, NULL, NULL);
1936 }
1937
1938 /* For testing purpose, static route of MPLS-VPN. */
1939 DEFUN (no_vpnv6_network,
1940 no_vpnv6_network_cmd,
1941 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1942 NO_STR
1943 "Specify a network to announce via BGP\n"
1944 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1945 "Specify Route Distinguisher\n"
1946 "VPN Route Distinguisher\n"
1947 "VPN NLRI label (tag)\n"
1948 "VPN NLRI label (tag)\n"
1949 "Label value\n")
1950 {
1951 int idx_ipv6_prefix = 2;
1952 int idx_ext_community = 4;
1953 int idx_label = 6;
1954 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
1955 argv[idx_ipv6_prefix]->arg,
1956 argv[idx_ext_community]->arg,
1957 argv[idx_label]->arg, 0, NULL, NULL, NULL);
1958 }
1959
1960 int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
1961 enum bgp_show_type type, void *output_arg, int tags,
1962 bool use_json)
1963 {
1964 struct bgp *bgp;
1965 struct bgp_table *table;
1966
1967 bgp = bgp_get_default();
1968 if (bgp == NULL) {
1969 if (!use_json)
1970 vty_out(vty, "No BGP process is configured\n");
1971 else
1972 vty_out(vty, "{}\n");
1973 return CMD_WARNING;
1974 }
1975 table = bgp->rib[afi][SAFI_MPLS_VPN];
1976 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
1977 output_arg, use_json);
1978 }
1979
1980 DEFUN (show_bgp_ip_vpn_all_rd,
1981 show_bgp_ip_vpn_all_rd_cmd,
1982 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
1983 SHOW_STR
1984 BGP_STR
1985 BGP_VPNVX_HELP_STR
1986 "Display VPN NLRI specific information\n"
1987 "Display VPN NLRI specific information\n"
1988 "Display information for a route distinguisher\n"
1989 "VPN Route Distinguisher\n"
1990 JSON_STR)
1991 {
1992 int ret;
1993 struct prefix_rd prd;
1994 afi_t afi;
1995 int idx = 0;
1996
1997 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
1998 if (argv_find(argv, argc, "rd", &idx)) {
1999 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
2000 if (!ret) {
2001 vty_out(vty,
2002 "%% Malformed Route Distinguisher\n");
2003 return CMD_WARNING;
2004 }
2005 return bgp_show_mpls_vpn(vty, afi, &prd,
2006 bgp_show_type_normal, NULL, 0,
2007 use_json(argc, argv));
2008 } else {
2009 return bgp_show_mpls_vpn(vty, afi, NULL,
2010 bgp_show_type_normal, NULL, 0,
2011 use_json(argc, argv));
2012 }
2013 }
2014 return CMD_SUCCESS;
2015 }
2016
2017 ALIAS(show_bgp_ip_vpn_all_rd,
2018 show_bgp_ip_vpn_rd_cmd,
2019 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
2020 SHOW_STR
2021 BGP_STR
2022 BGP_VPNVX_HELP_STR
2023 "Display VPN NLRI specific information\n"
2024 "Display information for a route distinguisher\n"
2025 "VPN Route Distinguisher\n"
2026 JSON_STR)
2027
2028 #ifdef KEEP_OLD_VPN_COMMANDS
2029 DEFUN (show_ip_bgp_vpn_rd,
2030 show_ip_bgp_vpn_rd_cmd,
2031 "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
2032 SHOW_STR
2033 IP_STR
2034 BGP_STR
2035 BGP_AFI_HELP_STR
2036 "Address Family modifier\n"
2037 "Display information for a route distinguisher\n"
2038 "VPN Route Distinguisher\n")
2039 {
2040 int idx_ext_community = argc - 1;
2041 int ret;
2042 struct prefix_rd prd;
2043 afi_t afi;
2044 int idx = 0;
2045
2046 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2047 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2048 if (!ret) {
2049 vty_out(vty, "%% Malformed Route Distinguisher\n");
2050 return CMD_WARNING;
2051 }
2052 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
2053 NULL, 0, 0);
2054 }
2055 return CMD_SUCCESS;
2056 }
2057
2058 DEFUN (show_ip_bgp_vpn_all,
2059 show_ip_bgp_vpn_all_cmd,
2060 "show [ip] bgp <vpnv4|vpnv6>",
2061 SHOW_STR
2062 IP_STR
2063 BGP_STR
2064 BGP_VPNVX_HELP_STR)
2065 {
2066 afi_t afi;
2067 int idx = 0;
2068
2069 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
2070 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
2071 NULL, 0, 0);
2072 return CMD_SUCCESS;
2073 }
2074
2075 DEFUN (show_ip_bgp_vpn_all_tags,
2076 show_ip_bgp_vpn_all_tags_cmd,
2077 "show [ip] bgp <vpnv4|vpnv6> all tags",
2078 SHOW_STR
2079 IP_STR
2080 BGP_STR
2081 BGP_VPNVX_HELP_STR
2082 "Display information about all VPNv4/VPNV6 NLRIs\n"
2083 "Display BGP tags for prefixes\n")
2084 {
2085 afi_t afi;
2086 int idx = 0;
2087
2088 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
2089 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
2090 NULL, 1, 0);
2091 return CMD_SUCCESS;
2092 }
2093
2094 DEFUN (show_ip_bgp_vpn_rd_tags,
2095 show_ip_bgp_vpn_rd_tags_cmd,
2096 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
2097 SHOW_STR
2098 IP_STR
2099 BGP_STR
2100 BGP_VPNVX_HELP_STR
2101 "Display information for a route distinguisher\n"
2102 "VPN Route Distinguisher\n"
2103 "Display BGP tags for prefixes\n")
2104 {
2105 int idx_ext_community = 5;
2106 int ret;
2107 struct prefix_rd prd;
2108 afi_t afi;
2109 int idx = 0;
2110
2111 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2112 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2113 if (!ret) {
2114 vty_out(vty, "%% Malformed Route Distinguisher\n");
2115 return CMD_WARNING;
2116 }
2117 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
2118 NULL, 1, 0);
2119 }
2120 return CMD_SUCCESS;
2121 }
2122
2123 DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
2124 show_ip_bgp_vpn_all_neighbor_routes_cmd,
2125 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
2126 SHOW_STR
2127 IP_STR
2128 BGP_STR
2129 BGP_VPNVX_HELP_STR
2130 "Display information about all VPNv4/VPNv6 NLRIs\n"
2131 "Detailed information on TCP and BGP neighbor connections\n"
2132 "Neighbor to display information about\n"
2133 "Display routes learned from neighbor\n"
2134 JSON_STR)
2135 {
2136 int idx_ipv4 = 6;
2137 union sockunion su;
2138 struct peer *peer;
2139 int ret;
2140 bool uj = use_json(argc, argv);
2141 afi_t afi;
2142 int idx = 0;
2143
2144 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2145 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2146 if (ret < 0) {
2147 if (uj) {
2148 json_object *json_no = NULL;
2149 json_no = json_object_new_object();
2150 json_object_string_add(json_no, "warning",
2151 "Malformed address");
2152 vty_out(vty, "%s\n",
2153 json_object_to_json_string(json_no));
2154 json_object_free(json_no);
2155 } else
2156 vty_out(vty, "Malformed address: %s\n",
2157 argv[idx_ipv4]->arg);
2158 return CMD_WARNING;
2159 }
2160
2161 peer = peer_lookup(NULL, &su);
2162 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2163 if (uj) {
2164 json_object *json_no = NULL;
2165 json_no = json_object_new_object();
2166 json_object_string_add(
2167 json_no, "warning",
2168 "No such neighbor or address family");
2169 vty_out(vty, "%s\n",
2170 json_object_to_json_string(json_no));
2171 json_object_free(json_no);
2172 } else
2173 vty_out(vty,
2174 "%% No such neighbor or address family\n");
2175 return CMD_WARNING;
2176 }
2177
2178 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
2179 &su, 0, uj);
2180 }
2181 return CMD_SUCCESS;
2182 }
2183
2184 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
2185 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
2186 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
2187 SHOW_STR
2188 IP_STR
2189 BGP_STR
2190 BGP_VPNVX_HELP_STR
2191 "Display information for a route distinguisher\n"
2192 "VPN Route Distinguisher\n"
2193 "Detailed information on TCP and BGP neighbor connections\n"
2194 "Neighbor to display information about\n"
2195 "Display routes learned from neighbor\n"
2196 JSON_STR)
2197 {
2198 int idx_ext_community = 5;
2199 int idx_ipv4 = 7;
2200 int ret;
2201 union sockunion su;
2202 struct peer *peer;
2203 struct prefix_rd prd;
2204 bool uj = use_json(argc, argv);
2205 afi_t afi;
2206 int idx = 0;
2207
2208 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2209 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2210 if (!ret) {
2211 if (uj) {
2212 json_object *json_no = NULL;
2213 json_no = json_object_new_object();
2214 json_object_string_add(
2215 json_no, "warning",
2216 "Malformed Route Distinguisher");
2217 vty_out(vty, "%s\n",
2218 json_object_to_json_string(json_no));
2219 json_object_free(json_no);
2220 } else
2221 vty_out(vty,
2222 "%% Malformed Route Distinguisher\n");
2223 return CMD_WARNING;
2224 }
2225
2226 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2227 if (ret < 0) {
2228 if (uj) {
2229 json_object *json_no = NULL;
2230 json_no = json_object_new_object();
2231 json_object_string_add(json_no, "warning",
2232 "Malformed address");
2233 vty_out(vty, "%s\n",
2234 json_object_to_json_string(json_no));
2235 json_object_free(json_no);
2236 } else
2237 vty_out(vty, "Malformed address: %s\n",
2238 argv[idx_ext_community]->arg);
2239 return CMD_WARNING;
2240 }
2241
2242 peer = peer_lookup(NULL, &su);
2243 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2244 if (uj) {
2245 json_object *json_no = NULL;
2246 json_no = json_object_new_object();
2247 json_object_string_add(
2248 json_no, "warning",
2249 "No such neighbor or address family");
2250 vty_out(vty, "%s\n",
2251 json_object_to_json_string(json_no));
2252 json_object_free(json_no);
2253 } else
2254 vty_out(vty,
2255 "%% No such neighbor or address family\n");
2256 return CMD_WARNING;
2257 }
2258
2259 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_neighbor,
2260 &su, 0, uj);
2261 }
2262 return CMD_SUCCESS;
2263 }
2264
2265 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
2266 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
2267 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
2268 SHOW_STR
2269 IP_STR
2270 BGP_STR
2271 BGP_VPNVX_HELP_STR
2272 "Display information about all VPNv4/VPNv6 NLRIs\n"
2273 "Detailed information on TCP and BGP neighbor connections\n"
2274 "Neighbor to display information about\n"
2275 "Display the routes advertised to a BGP neighbor\n"
2276 JSON_STR)
2277 {
2278 int idx_ipv4 = 6;
2279 int ret;
2280 struct peer *peer;
2281 union sockunion su;
2282 bool uj = use_json(argc, argv);
2283 afi_t afi;
2284 int idx = 0;
2285
2286 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2287 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2288 if (ret < 0) {
2289 if (uj) {
2290 json_object *json_no = NULL;
2291 json_no = json_object_new_object();
2292 json_object_string_add(json_no, "warning",
2293 "Malformed address");
2294 vty_out(vty, "%s\n",
2295 json_object_to_json_string(json_no));
2296 json_object_free(json_no);
2297 } else
2298 vty_out(vty, "Malformed address: %s\n",
2299 argv[idx_ipv4]->arg);
2300 return CMD_WARNING;
2301 }
2302 peer = peer_lookup(NULL, &su);
2303 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2304 if (uj) {
2305 json_object *json_no = NULL;
2306 json_no = json_object_new_object();
2307 json_object_string_add(
2308 json_no, "warning",
2309 "No such neighbor or address family");
2310 vty_out(vty, "%s\n",
2311 json_object_to_json_string(json_no));
2312 json_object_free(json_no);
2313 } else
2314 vty_out(vty,
2315 "%% No such neighbor or address family\n");
2316 return CMD_WARNING;
2317 }
2318 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
2319 SAFI_MPLS_VPN, uj);
2320 }
2321 return CMD_SUCCESS;
2322 }
2323
2324 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
2325 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
2326 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
2327 SHOW_STR
2328 IP_STR
2329 BGP_STR
2330 BGP_VPNVX_HELP_STR
2331 "Display information for a route distinguisher\n"
2332 "VPN Route Distinguisher\n"
2333 "Detailed information on TCP and BGP neighbor connections\n"
2334 "Neighbor to display information about\n"
2335 "Display the routes advertised to a BGP neighbor\n"
2336 JSON_STR)
2337 {
2338 int idx_ext_community = 5;
2339 int idx_ipv4 = 7;
2340 int ret;
2341 struct peer *peer;
2342 struct prefix_rd prd;
2343 union sockunion su;
2344 bool uj = use_json(argc, argv);
2345 afi_t afi;
2346 int idx = 0;
2347
2348 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2349 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2350 if (ret < 0) {
2351 if (uj) {
2352 json_object *json_no = NULL;
2353 json_no = json_object_new_object();
2354 json_object_string_add(json_no, "warning",
2355 "Malformed address");
2356 vty_out(vty, "%s\n",
2357 json_object_to_json_string(json_no));
2358 json_object_free(json_no);
2359 } else
2360 vty_out(vty, "Malformed address: %s\n",
2361 argv[idx_ext_community]->arg);
2362 return CMD_WARNING;
2363 }
2364 peer = peer_lookup(NULL, &su);
2365 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2366 if (uj) {
2367 json_object *json_no = NULL;
2368 json_no = json_object_new_object();
2369 json_object_string_add(
2370 json_no, "warning",
2371 "No such neighbor or address family");
2372 vty_out(vty, "%s\n",
2373 json_object_to_json_string(json_no));
2374 json_object_free(json_no);
2375 } else
2376 vty_out(vty,
2377 "%% No such neighbor or address family\n");
2378 return CMD_WARNING;
2379 }
2380
2381 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2382 if (!ret) {
2383 if (uj) {
2384 json_object *json_no = NULL;
2385 json_no = json_object_new_object();
2386 json_object_string_add(
2387 json_no, "warning",
2388 "Malformed Route Distinguisher");
2389 vty_out(vty, "%s\n",
2390 json_object_to_json_string(json_no));
2391 json_object_free(json_no);
2392 } else
2393 vty_out(vty,
2394 "%% Malformed Route Distinguisher\n");
2395 return CMD_WARNING;
2396 }
2397
2398 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
2399 SAFI_MPLS_VPN, uj);
2400 }
2401 return CMD_SUCCESS;
2402 }
2403 #endif /* KEEP_OLD_VPN_COMMANDS */
2404
2405 void bgp_mplsvpn_init(void)
2406 {
2407 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
2408 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
2409 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
2410
2411 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
2412 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
2413
2414 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
2415 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
2416 #ifdef KEEP_OLD_VPN_COMMANDS
2417 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
2418 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
2419 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
2420 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
2421 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
2422 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
2423 install_element(VIEW_NODE,
2424 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
2425 install_element(VIEW_NODE,
2426 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
2427 #endif /* KEEP_OLD_VPN_COMMANDS */
2428 }
2429
2430 vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
2431 {
2432 struct listnode *mnode, *mnnode;
2433 struct bgp *bgp;
2434
2435 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2436 struct ecommunity *ec;
2437
2438 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2439 continue;
2440
2441 ec = bgp->vpn_policy[AFI_IP].import_redirect_rtlist;
2442
2443 if (ecom_intersect(ec, eckey))
2444 return bgp->vrf_id;
2445 }
2446 return VRF_UNKNOWN;
2447 }
2448
2449 /*
2450 * The purpose of this function is to process leaks that were deferred
2451 * from earlier per-vrf configuration due to not-yet-existing default
2452 * vrf, in other words, configuration such as:
2453 *
2454 * router bgp MMM vrf FOO
2455 * address-family ipv4 unicast
2456 * rd vpn export 1:1
2457 * exit-address-family
2458 *
2459 * router bgp NNN
2460 * ...
2461 *
2462 * This function gets called when the default instance ("router bgp NNN")
2463 * is created.
2464 */
2465 void vpn_leak_postchange_all(void)
2466 {
2467 struct listnode *next;
2468 struct bgp *bgp;
2469 struct bgp *bgp_default = bgp_get_default();
2470
2471 assert(bgp_default);
2472
2473 /* First, do any exporting from VRFs to the single VPN RIB */
2474 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
2475
2476 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2477 continue;
2478
2479 vpn_leak_postchange(
2480 BGP_VPN_POLICY_DIR_TOVPN,
2481 AFI_IP,
2482 bgp_default,
2483 bgp);
2484
2485 vpn_leak_postchange(
2486 BGP_VPN_POLICY_DIR_TOVPN,
2487 AFI_IP6,
2488 bgp_default,
2489 bgp);
2490 }
2491
2492 /* Now, do any importing to VRFs from the single VPN RIB */
2493 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
2494
2495 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2496 continue;
2497
2498 vpn_leak_postchange(
2499 BGP_VPN_POLICY_DIR_FROMVPN,
2500 AFI_IP,
2501 bgp_default,
2502 bgp);
2503
2504 vpn_leak_postchange(
2505 BGP_VPN_POLICY_DIR_FROMVPN,
2506 AFI_IP6,
2507 bgp_default,
2508 bgp);
2509 }
2510 }
2511
2512 /* When a bgp vrf instance is unconfigured, remove its routes
2513 * from the VPN table and this vrf could be importing routes from other
2514 * bgp vrf instnaces, unimport them.
2515 * VRF X and VRF Y are exporting routes to each other.
2516 * When VRF X is deleted, unimport its routes from all target vrfs,
2517 * also VRF Y should unimport its routes from VRF X table.
2518 * This will ensure VPN table is cleaned up appropriately.
2519 */
2520 int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty)
2521 {
2522 struct bgp *to_bgp;
2523 const char *tmp_name;
2524 char *vname;
2525 struct listnode *node, *next;
2526 safi_t safi = SAFI_UNICAST;
2527 afi_t afi;
2528 bool is_vrf_leak_bind;
2529 int debug;
2530
2531 if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2532 return 0;
2533
2534 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
2535 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2536
2537 tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
2538
2539 for (afi = 0; afi < AFI_MAX; ++afi) {
2540 /* vrf leak is for IPv4 and IPv6 Unicast only */
2541 if (afi != AFI_IP && afi != AFI_IP6)
2542 continue;
2543
2544 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
2545 if (from_bgp == to_bgp)
2546 continue;
2547
2548 /* Unimport and remove source vrf from the
2549 * other vrfs import list.
2550 */
2551 struct vpn_policy *to_vpolicy;
2552
2553 is_vrf_leak_bind = false;
2554 to_vpolicy = &(to_bgp->vpn_policy[afi]);
2555 for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf, node,
2556 vname)) {
2557 if (strcmp(vname, tmp_name) == 0) {
2558 is_vrf_leak_bind = true;
2559 break;
2560 }
2561 }
2562 /* skip this bgp instance as there is no leak to this
2563 * vrf instance.
2564 */
2565 if (!is_vrf_leak_bind)
2566 continue;
2567
2568 if (debug)
2569 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
2570 __func__, from_bgp->name_pretty,
2571 to_bgp->name_pretty, afi2str(afi),
2572 to_vpolicy->import_vrf->count);
2573
2574 vrf_unimport_from_vrf(to_bgp, from_bgp, afi, safi);
2575
2576 /* readd vrf name as unimport removes import vrf name
2577 * from the destination vrf's import list where the
2578 * `import vrf` configuration still exist.
2579 */
2580 vname = XSTRDUP(MTYPE_TMP, tmp_name);
2581 listnode_add(to_bgp->vpn_policy[afi].import_vrf,
2582 vname);
2583 SET_FLAG(to_bgp->af_flags[afi][safi],
2584 BGP_CONFIG_VRF_TO_VRF_IMPORT);
2585
2586 /* If to_bgp exports its routes to the bgp vrf
2587 * which is being deleted, un-import the
2588 * to_bgp routes from VPN.
2589 */
2590 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi]
2591 .export_vrf, node,
2592 vname)) {
2593 if (strcmp(vname, tmp_name) == 0) {
2594 vrf_unimport_from_vrf(from_bgp, to_bgp,
2595 afi, safi);
2596 break;
2597 }
2598 }
2599 }
2600 }
2601 return 0;
2602 }
2603
2604 /* When a router bgp is configured, there could be a bgp vrf
2605 * instance importing routes from this newly configured
2606 * bgp vrf instance. Export routes from configured
2607 * bgp vrf to VPN.
2608 * VRF Y has import from bgp vrf x,
2609 * when a bgp vrf x instance is created, export its routes
2610 * to VRF Y instance.
2611 */
2612 void bgp_vpn_leak_export(struct bgp *from_bgp)
2613 {
2614 afi_t afi;
2615 const char *export_name;
2616 char *vname;
2617 struct listnode *node, *next;
2618 struct ecommunity *ecom;
2619 vpn_policy_direction_t idir, edir;
2620 safi_t safi = SAFI_UNICAST;
2621 struct bgp *to_bgp;
2622 int debug;
2623
2624 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
2625 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2626
2627 idir = BGP_VPN_POLICY_DIR_FROMVPN;
2628 edir = BGP_VPN_POLICY_DIR_TOVPN;
2629
2630 export_name = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
2631 : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME));
2632
2633 for (afi = 0; afi < AFI_MAX; ++afi) {
2634 /* vrf leak is for IPv4 and IPv6 Unicast only */
2635 if (afi != AFI_IP && afi != AFI_IP6)
2636 continue;
2637
2638 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
2639 if (from_bgp == to_bgp)
2640 continue;
2641
2642 /* bgp instance has import list, check to see if newly
2643 * configured bgp instance is the list.
2644 */
2645 struct vpn_policy *to_vpolicy;
2646
2647 to_vpolicy = &(to_bgp->vpn_policy[afi]);
2648 for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf,
2649 node, vname)) {
2650 if (strcmp(vname, export_name) != 0)
2651 continue;
2652
2653 if (debug)
2654 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
2655 __func__,
2656 export_name, to_bgp->name_pretty);
2657
2658 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
2659 /* remove import rt, it will be readded
2660 * as part of import from vrf.
2661 */
2662 if (ecom)
2663 ecommunity_del_val(
2664 to_vpolicy->rtlist[idir],
2665 (struct ecommunity_val *)
2666 ecom->val);
2667 vrf_import_from_vrf(to_bgp, from_bgp,
2668 afi, safi);
2669 break;
2670
2671 }
2672 }
2673 }
2674 }