]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_mplsvpn.c
Merge pull request #5644 from donaldsharp/more_pim_doc
[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 /* shallow copy */
703 static_attr = *path_vrf->attr;
704
705 /*
706 * route map handling
707 */
708 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
709 struct bgp_path_info info;
710 route_map_result_t ret;
711
712 memset(&info, 0, sizeof(info));
713 info.peer = bgp_vpn->peer_self;
714 info.attr = &static_attr;
715 ret = route_map_apply(
716 bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN],
717 p, RMAP_BGP, &info);
718 if (RMAP_DENYMATCH == ret) {
719 bgp_attr_flush(&static_attr); /* free any added parts */
720 if (debug)
721 zlog_debug(
722 "%s: vrf %s route map \"%s\" says DENY, returning",
723 __func__, bgp_vrf->name_pretty,
724 bgp_vrf->vpn_policy[afi]
725 .rmap[BGP_VPN_POLICY_DIR_TOVPN]
726 ->name);
727 return;
728 }
729 }
730
731 if (debug && static_attr.ecommunity) {
732 char *s = ecommunity_ecom2str(static_attr.ecommunity,
733 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
734
735 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
736 __func__, s);
737 XFREE(MTYPE_ECOMMUNITY_STR, s);
738 }
739
740 /*
741 * Add the vpn-policy rt-list
742 */
743 struct ecommunity *old_ecom;
744 struct ecommunity *new_ecom;
745
746 old_ecom = static_attr.ecommunity;
747 if (old_ecom) {
748 new_ecom = ecommunity_merge(
749 ecommunity_dup(old_ecom),
750 bgp_vrf->vpn_policy[afi]
751 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
752 if (!old_ecom->refcnt)
753 ecommunity_free(&old_ecom);
754 } else {
755 new_ecom = ecommunity_dup(
756 bgp_vrf->vpn_policy[afi]
757 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
758 }
759 static_attr.ecommunity = new_ecom;
760 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
761
762 if (debug && static_attr.ecommunity) {
763 char *s = ecommunity_ecom2str(static_attr.ecommunity,
764 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
765
766 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
767 __func__, s);
768 XFREE(MTYPE_ECOMMUNITY_STR, s);
769 }
770
771 /* Nexthop */
772 /* if policy nexthop not set, use 0 */
773 if (CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
774 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
775 struct prefix *nexthop =
776 &bgp_vrf->vpn_policy[afi].tovpn_nexthop;
777
778 switch (nexthop->family) {
779 case AF_INET:
780 /* prevent mp_nexthop_global_in <- self in bgp_route.c
781 */
782 static_attr.nexthop.s_addr = nexthop->u.prefix4.s_addr;
783
784 static_attr.mp_nexthop_global_in = nexthop->u.prefix4;
785 static_attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
786 break;
787
788 case AF_INET6:
789 static_attr.mp_nexthop_global = nexthop->u.prefix6;
790 static_attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
791 break;
792
793 default:
794 assert(0);
795 }
796 } else {
797 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
798 BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
799 if (afi == AFI_IP) {
800 /*
801 * For ipv4, copy to multiprotocol
802 * nexthop field
803 */
804 static_attr.mp_nexthop_global_in =
805 static_attr.nexthop;
806 static_attr.mp_nexthop_len =
807 BGP_ATTR_NHLEN_IPV4;
808 /*
809 * XXX Leave static_attr.nexthop
810 * intact for NHT
811 */
812 static_attr.flag &=
813 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
814 }
815 } else {
816 /* Update based on next-hop family to account for
817 * RFC 5549 (BGP unnumbered) scenario. Note that
818 * specific action is only needed for the case of
819 * IPv4 nexthops as the attr has been copied
820 * otherwise.
821 */
822 if (afi == AFI_IP
823 && !BGP_ATTR_NEXTHOP_AFI_IP6(path_vrf->attr)) {
824 static_attr.mp_nexthop_global_in.s_addr =
825 static_attr.nexthop.s_addr;
826 static_attr.mp_nexthop_len =
827 BGP_ATTR_NHLEN_IPV4;
828 static_attr.flag |=
829 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
830 }
831 }
832 nexthop_self_flag = 1;
833 }
834
835 label_val = bgp_vrf->vpn_policy[afi].tovpn_label;
836 if (label_val == MPLS_LABEL_NONE) {
837 encode_label(MPLS_LABEL_IMPLICIT_NULL, &label);
838 } else {
839 encode_label(label_val, &label);
840 }
841
842 /* Set originator ID to "me" */
843 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID));
844 static_attr.originator_id = bgp_vpn->router_id;
845
846
847 new_attr = bgp_attr_intern(
848 &static_attr); /* hashed refcounted everything */
849 bgp_attr_flush(&static_attr); /* free locally-allocated parts */
850
851 if (debug && new_attr->ecommunity) {
852 char *s = ecommunity_ecom2str(new_attr->ecommunity,
853 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
854
855 zlog_debug("%s: new_attr->ecommunity{%s}", __func__, s);
856 XFREE(MTYPE_ECOMMUNITY_STR, s);
857 }
858
859 /* Now new_attr is an allocated interned attr */
860
861 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
862 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
863
864 struct bgp_path_info *new_info;
865
866 new_info = leak_update(bgp_vpn, bn, new_attr, afi, safi, path_vrf,
867 &label, 1, path_vrf, bgp_vrf, NULL,
868 nexthop_self_flag, debug);
869
870 /*
871 * Routes actually installed in the vpn RIB must also be
872 * offered to all vrfs (because now they originate from
873 * the vpn RIB).
874 *
875 * Acceptance into other vrfs depends on rt-lists.
876 * Originating vrf will not accept the looped back route
877 * because of loop checking.
878 */
879 if (new_info)
880 vpn_leak_to_vrf_update(bgp_vrf, new_info);
881 }
882
883 void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
884 struct bgp *bgp_vrf, /* from */
885 struct bgp_path_info *path_vrf) /* route */
886 {
887 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
888 struct prefix *p = &path_vrf->net->p;
889 afi_t afi = family2afi(p->family);
890 safi_t safi = SAFI_MPLS_VPN;
891 struct bgp_path_info *bpi;
892 struct bgp_node *bn;
893 const char *debugmsg;
894 char buf_prefix[PREFIX_STRLEN];
895
896 if (debug) {
897 prefix2str(p, buf_prefix, sizeof(buf_prefix));
898 zlog_debug(
899 "%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
900 __func__, bgp_vrf->name_pretty, buf_prefix,
901 path_vrf->type, path_vrf->sub_type);
902 }
903
904 if (!bgp_vpn)
905 return;
906
907 if (!afi) {
908 if (debug)
909 zlog_debug("%s: can't get afi of prefix", __func__);
910 return;
911 }
912
913 /* Is this route exportable into the VPN table? */
914 if (!is_route_injectable_into_vpn(path_vrf))
915 return;
916
917 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
918 if (debug)
919 zlog_debug("%s: skipping: %s", __func__, debugmsg);
920 return;
921 }
922
923 if (debug)
924 zlog_debug("%s: withdrawing (path_vrf=%p)", __func__, path_vrf);
925
926 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
927 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
928
929 if (!bn)
930 return;
931 /*
932 * vrf -> vpn
933 * match original bpi imported from
934 */
935 for (bpi = bgp_node_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
936 if (bpi->extra && bpi->extra->parent == path_vrf) {
937 break;
938 }
939 }
940
941 if (bpi) {
942 /* withdraw from looped vrfs as well */
943 vpn_leak_to_vrf_withdraw(bgp_vpn, bpi);
944
945 bgp_aggregate_decrement(bgp_vpn, p, bpi, afi, safi);
946 bgp_path_info_delete(bn, bpi);
947 bgp_process(bgp_vpn, bn, afi, safi);
948 }
949 bgp_unlock_node(bn);
950 }
951
952 void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
953 struct bgp *bgp_vrf, /* from */
954 afi_t afi)
955 {
956 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
957 struct bgp_node *prn;
958 safi_t safi = SAFI_MPLS_VPN;
959
960 /*
961 * Walk vpn table, delete bpi with bgp_orig == bgp_vrf
962 */
963 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
964 prn = bgp_route_next(prn)) {
965
966 struct bgp_table *table;
967 struct bgp_node *bn;
968 struct bgp_path_info *bpi;
969
970 /* This is the per-RD table of prefixes */
971 table = bgp_node_get_bgp_table_info(prn);
972
973 if (!table)
974 continue;
975
976 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
977
978 char buf[PREFIX2STR_BUFFER];
979
980 bpi = bgp_node_get_bgp_path_info(bn);
981 if (debug && bpi) {
982 zlog_debug(
983 "%s: looking at prefix %s", __func__,
984 prefix2str(&bn->p, buf, sizeof(buf)));
985 }
986
987 for (; bpi; bpi = bpi->next) {
988 if (debug)
989 zlog_debug("%s: type %d, sub_type %d",
990 __func__, bpi->type,
991 bpi->sub_type);
992 if (bpi->sub_type != BGP_ROUTE_IMPORTED)
993 continue;
994 if (!bpi->extra)
995 continue;
996 if ((struct bgp *)bpi->extra->bgp_orig
997 == bgp_vrf) {
998 /* delete route */
999 if (debug)
1000 zlog_debug("%s: deleting it",
1001 __func__);
1002 bgp_aggregate_decrement(bgp_vpn, &bn->p,
1003 bpi, afi, safi);
1004 bgp_path_info_delete(bn, bpi);
1005 bgp_process(bgp_vpn, bn, afi, safi);
1006 }
1007 }
1008 }
1009 }
1010 }
1011
1012 void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn, /* to */
1013 struct bgp *bgp_vrf, /* from */
1014 afi_t afi)
1015 {
1016 struct bgp_node *bn;
1017 struct bgp_path_info *bpi;
1018 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
1019
1020 if (debug)
1021 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__, afi,
1022 bgp_vrf->name_pretty);
1023
1024 for (bn = bgp_table_top(bgp_vrf->rib[afi][SAFI_UNICAST]); bn;
1025 bn = bgp_route_next(bn)) {
1026
1027 if (debug)
1028 zlog_debug("%s: node=%p", __func__, bn);
1029
1030 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
1031 bpi = bpi->next) {
1032 if (debug)
1033 zlog_debug(
1034 "%s: calling vpn_leak_from_vrf_update",
1035 __func__);
1036 vpn_leak_from_vrf_update(bgp_vpn, bgp_vrf, bpi);
1037 }
1038 }
1039 }
1040
1041 static void
1042 vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
1043 struct bgp *bgp_vpn, /* from */
1044 struct bgp_path_info *path_vpn) /* route */
1045 {
1046 struct prefix *p = &path_vpn->net->p;
1047 afi_t afi = family2afi(p->family);
1048
1049 struct attr static_attr = {0};
1050 struct attr *new_attr = NULL;
1051 struct bgp_node *bn;
1052 safi_t safi = SAFI_UNICAST;
1053 const char *debugmsg;
1054 struct prefix nexthop_orig;
1055 mpls_label_t *pLabels = NULL;
1056 uint32_t num_labels = 0;
1057 int nexthop_self_flag = 1;
1058 struct bgp_path_info *bpi_ultimate = NULL;
1059 int origin_local = 0;
1060 struct bgp *src_vrf;
1061
1062 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1063
1064 if (!vpn_leak_from_vpn_active(bgp_vrf, afi, &debugmsg)) {
1065 if (debug)
1066 zlog_debug("%s: skipping: %s", __func__, debugmsg);
1067 return;
1068 }
1069
1070 /* Check for intersection of route targets */
1071 if (!ecom_intersect(
1072 bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1073 path_vpn->attr->ecommunity)) {
1074
1075 return;
1076 }
1077
1078 if (debug) {
1079 char buf_prefix[PREFIX_STRLEN];
1080
1081 prefix2str(p, buf_prefix, sizeof(buf_prefix));
1082 zlog_debug("%s: updating %s to vrf %s", __func__,
1083 buf_prefix, bgp_vrf->name_pretty);
1084 }
1085
1086 /* shallow copy */
1087 static_attr = *path_vpn->attr;
1088
1089 /*
1090 * Nexthop: stash and clear
1091 *
1092 * Nexthop is valid in context of VPN core, but not in destination vrf.
1093 * Stash it for later label resolution by vrf ingress path and then
1094 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1095 */
1096 uint8_t nhfamily = NEXTHOP_FAMILY(path_vpn->attr->mp_nexthop_len);
1097
1098 memset(&nexthop_orig, 0, sizeof(nexthop_orig));
1099 nexthop_orig.family = nhfamily;
1100
1101 switch (nhfamily) {
1102 case AF_INET:
1103 /* save */
1104 nexthop_orig.u.prefix4 = path_vpn->attr->mp_nexthop_global_in;
1105 nexthop_orig.prefixlen = 32;
1106
1107 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1108 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1109 static_attr.nexthop.s_addr =
1110 nexthop_orig.u.prefix4.s_addr;
1111
1112 static_attr.mp_nexthop_global_in =
1113 path_vpn->attr->mp_nexthop_global_in;
1114 static_attr.mp_nexthop_len =
1115 path_vpn->attr->mp_nexthop_len;
1116 }
1117 static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
1118 break;
1119 case AF_INET6:
1120 /* save */
1121 nexthop_orig.u.prefix6 = path_vpn->attr->mp_nexthop_global;
1122 nexthop_orig.prefixlen = 128;
1123
1124 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1125 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1126 static_attr.mp_nexthop_global = nexthop_orig.u.prefix6;
1127 }
1128 break;
1129 }
1130
1131 /*
1132 * route map handling
1133 */
1134 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
1135 struct bgp_path_info info;
1136 route_map_result_t ret;
1137
1138 memset(&info, 0, sizeof(info));
1139 info.peer = bgp_vrf->peer_self;
1140 info.attr = &static_attr;
1141 info.extra = path_vpn->extra; /* Used for source-vrf filter */
1142 ret = route_map_apply(bgp_vrf->vpn_policy[afi]
1143 .rmap[BGP_VPN_POLICY_DIR_FROMVPN],
1144 p, RMAP_BGP, &info);
1145 if (RMAP_DENYMATCH == ret) {
1146 bgp_attr_flush(&static_attr); /* free any added parts */
1147 if (debug)
1148 zlog_debug(
1149 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
1150 __func__, bgp_vrf->name_pretty,
1151 bgp_vrf->vpn_policy[afi]
1152 .rmap[BGP_VPN_POLICY_DIR_FROMVPN]
1153 ->name);
1154 return;
1155 }
1156 /*
1157 * if route-map changed nexthop, don't nexthop-self on output
1158 */
1159 if (!CHECK_FLAG(static_attr.rmap_change_flags,
1160 BATTR_RMAP_NEXTHOP_UNCHANGED))
1161 nexthop_self_flag = 0;
1162 }
1163
1164 new_attr = bgp_attr_intern(&static_attr);
1165 bgp_attr_flush(&static_attr);
1166
1167 bn = bgp_afi_node_get(bgp_vrf->rib[afi][safi], afi, safi, p, NULL);
1168
1169 /*
1170 * ensure labels are copied
1171 *
1172 * However, there is a special case: if the route originated in
1173 * another local VRF (as opposed to arriving via VPN), then the
1174 * nexthop is reached by hairpinning through this router (me)
1175 * using IP forwarding only (no LSP). Therefore, the route
1176 * imported to the VRF should not have labels attached. Note
1177 * that nexthop tracking is also involved: eliminating the
1178 * labels for these routes enables the non-labeled nexthops
1179 * from the originating VRF to be considered valid for this route.
1180 */
1181 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1182 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1183 /* work back to original route */
1184 for (bpi_ultimate = path_vpn;
1185 bpi_ultimate->extra && bpi_ultimate->extra->parent;
1186 bpi_ultimate = bpi_ultimate->extra->parent)
1187 ;
1188
1189 /*
1190 * if original route was unicast,
1191 * then it did not arrive over vpn
1192 */
1193 if (bpi_ultimate->net) {
1194 struct bgp_table *table;
1195
1196 table = bgp_node_table(bpi_ultimate->net);
1197 if (table && (table->safi == SAFI_UNICAST))
1198 origin_local = 1;
1199 }
1200
1201 /* copy labels */
1202 if (!origin_local && path_vpn->extra
1203 && path_vpn->extra->num_labels) {
1204 num_labels = path_vpn->extra->num_labels;
1205 if (num_labels > BGP_MAX_LABELS)
1206 num_labels = BGP_MAX_LABELS;
1207 pLabels = path_vpn->extra->label;
1208 }
1209 }
1210
1211 if (debug) {
1212 char buf_prefix[PREFIX_STRLEN];
1213 prefix2str(p, buf_prefix, sizeof(buf_prefix));
1214 zlog_debug("%s: pfx %s: num_labels %d", __func__, buf_prefix,
1215 num_labels);
1216 }
1217
1218 /*
1219 * For VRF-2-VRF route-leaking,
1220 * the source will be the originating VRF.
1221 */
1222 if (path_vpn->extra && path_vpn->extra->bgp_orig)
1223 src_vrf = path_vpn->extra->bgp_orig;
1224 else
1225 src_vrf = bgp_vpn;
1226
1227 leak_update(bgp_vrf, bn, new_attr, afi, safi, path_vpn, pLabels,
1228 num_labels, path_vpn, /* parent */
1229 src_vrf, &nexthop_orig, nexthop_self_flag, debug);
1230 }
1231
1232 void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
1233 struct bgp_path_info *path_vpn) /* route */
1234 {
1235 struct listnode *mnode, *mnnode;
1236 struct bgp *bgp;
1237
1238 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1239
1240 if (debug)
1241 zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
1242
1243 /* Loop over VRFs */
1244 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
1245
1246 if (!path_vpn->extra
1247 || path_vpn->extra->bgp_orig != bgp) { /* no loop */
1248 vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, path_vpn);
1249 }
1250 }
1251 }
1252
1253 void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
1254 struct bgp_path_info *path_vpn) /* route */
1255 {
1256 struct prefix *p;
1257 afi_t afi;
1258 safi_t safi = SAFI_UNICAST;
1259 struct bgp *bgp;
1260 struct listnode *mnode, *mnnode;
1261 struct bgp_node *bn;
1262 struct bgp_path_info *bpi;
1263 const char *debugmsg;
1264 char buf_prefix[PREFIX_STRLEN];
1265
1266 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1267
1268 if (debug) {
1269 prefix2str(&path_vpn->net->p, buf_prefix, sizeof(buf_prefix));
1270 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d", __func__,
1271 buf_prefix, path_vpn->type, path_vpn->sub_type);
1272 }
1273
1274 if (debug)
1275 zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
1276
1277 if (!path_vpn->net) {
1278 #if ENABLE_BGP_VNC
1279 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
1280 if (path_vpn->type == ZEBRA_ROUTE_BGP
1281 && path_vpn->sub_type == BGP_ROUTE_RFP) {
1282
1283 return;
1284 }
1285 #endif
1286 if (debug)
1287 zlog_debug(
1288 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
1289 __func__);
1290 return;
1291 }
1292
1293 p = &path_vpn->net->p;
1294 afi = family2afi(p->family);
1295
1296 /* Loop over VRFs */
1297 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
1298 if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
1299 if (debug)
1300 zlog_debug("%s: skipping: %s", __func__,
1301 debugmsg);
1302 continue;
1303 }
1304
1305 /* Check for intersection of route targets */
1306 if (!ecom_intersect(bgp->vpn_policy[afi]
1307 .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1308 path_vpn->attr->ecommunity)) {
1309
1310 continue;
1311 }
1312
1313 if (debug)
1314 zlog_debug("%s: withdrawing from vrf %s", __func__,
1315 bgp->name_pretty);
1316
1317 bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
1318
1319 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
1320 bpi = bpi->next) {
1321 if (bpi->extra
1322 && (struct bgp_path_info *)bpi->extra->parent
1323 == path_vpn) {
1324 break;
1325 }
1326 }
1327
1328 if (bpi) {
1329 if (debug)
1330 zlog_debug("%s: deleting bpi %p", __func__,
1331 bpi);
1332 bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
1333 bgp_path_info_delete(bn, bpi);
1334 bgp_process(bgp, bn, afi, safi);
1335 }
1336 bgp_unlock_node(bn);
1337 }
1338 }
1339
1340 void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
1341 afi_t afi)
1342 {
1343 struct bgp_node *bn;
1344 struct bgp_path_info *bpi;
1345 safi_t safi = SAFI_UNICAST;
1346 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1347
1348 if (debug)
1349 zlog_debug("%s: entry", __func__);
1350 /*
1351 * Walk vrf table, delete bpi with bgp_orig in a different vrf
1352 */
1353 for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
1354 bn = bgp_route_next(bn)) {
1355
1356 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
1357 bpi = bpi->next) {
1358 if (bpi->extra
1359 && bpi->extra->bgp_orig != bgp_vrf
1360 && bpi->extra->parent
1361 && is_pi_family_vpn(bpi->extra->parent)) {
1362
1363 /* delete route */
1364 bgp_aggregate_decrement(bgp_vrf, &bn->p, bpi,
1365 afi, safi);
1366 bgp_path_info_delete(bn, bpi);
1367 bgp_process(bgp_vrf, bn, afi, safi);
1368 }
1369 }
1370 }
1371 }
1372
1373 void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
1374 struct bgp *bgp_vpn, /* from */
1375 afi_t afi)
1376 {
1377 struct prefix_rd prd;
1378 struct bgp_node *prn;
1379 safi_t safi = SAFI_MPLS_VPN;
1380
1381 assert(bgp_vpn);
1382
1383 /*
1384 * Walk vpn table
1385 */
1386 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
1387 prn = bgp_route_next(prn)) {
1388
1389 struct bgp_table *table;
1390 struct bgp_node *bn;
1391 struct bgp_path_info *bpi;
1392
1393 memset(&prd, 0, sizeof(prd));
1394 prd.family = AF_UNSPEC;
1395 prd.prefixlen = 64;
1396 memcpy(prd.val, prn->p.u.val, 8);
1397
1398 /* This is the per-RD table of prefixes */
1399 table = bgp_node_get_bgp_table_info(prn);
1400
1401 if (!table)
1402 continue;
1403
1404 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
1405
1406 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
1407 bpi = bpi->next) {
1408
1409 if (bpi->extra
1410 && bpi->extra->bgp_orig == bgp_vrf)
1411 continue;
1412
1413 vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
1414 bpi);
1415 }
1416 }
1417 }
1418 }
1419
1420 /*
1421 * This function is called for definition/deletion/change to a route-map
1422 */
1423 static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
1424 {
1425 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1426 afi_t afi;
1427 struct route_map *rmap;
1428
1429 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1430 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
1431
1432 return;
1433 }
1434
1435 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
1436
1437 for (afi = 0; afi < AFI_MAX; ++afi) {
1438
1439 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
1440 && !strcmp(rmap_name,
1441 bgp->vpn_policy[afi]
1442 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
1443
1444 if (debug)
1445 zlog_debug(
1446 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1447 __func__, rmap_name, bgp->as,
1448 afi2str(afi));
1449
1450 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1451 bgp_get_default(), bgp);
1452 if (debug)
1453 zlog_debug("%s: after vpn_leak_prechange",
1454 __func__);
1455
1456 /* in case of definition/deletion */
1457 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN] =
1458 rmap;
1459
1460 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1461 bgp_get_default(), bgp);
1462
1463 if (debug)
1464 zlog_debug("%s: after vpn_leak_postchange",
1465 __func__);
1466 }
1467
1468 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]
1469 && !strcmp(rmap_name,
1470 bgp->vpn_policy[afi]
1471 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN])) {
1472
1473 if (debug) {
1474 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
1475 __func__, rmap_name, bgp->as,
1476 afi2str(afi));
1477 }
1478
1479 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1480 bgp_get_default(), bgp);
1481
1482 /* in case of definition/deletion */
1483 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
1484 rmap;
1485
1486 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1487 bgp_get_default(), bgp);
1488 }
1489 }
1490 }
1491
1492 /* This API is used during router-id change, reflect VPNs
1493 * auto RD and RT values and readvertise routes to VPN table.
1494 */
1495 void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
1496 bool is_config)
1497 {
1498 afi_t afi;
1499 int debug;
1500 char *vname;
1501 const char *export_name;
1502 char buf[RD_ADDRSTRLEN];
1503 struct bgp *bgp_import;
1504 struct listnode *node;
1505 struct ecommunity *ecom;
1506 vpn_policy_direction_t idir, edir;
1507
1508 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1509 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
1510 return;
1511
1512 export_name = bgp->name ? bgp->name : VRF_DEFAULT_NAME;
1513 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
1514 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
1515
1516 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1517 edir = BGP_VPN_POLICY_DIR_TOVPN;
1518
1519 for (afi = 0; afi < AFI_MAX; ++afi) {
1520 if (!vpn_leak_to_vpn_active(bgp, afi, NULL))
1521 continue;
1522
1523 if (withdraw) {
1524 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
1525 afi, bgp_get_default(), bgp);
1526 if (debug)
1527 zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
1528 __func__, export_name);
1529
1530 /* Remove import RT from VRFs */
1531 ecom = bgp->vpn_policy[afi].rtlist[edir];
1532 for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
1533 export_vrf, node, vname)) {
1534 bgp_import = bgp_lookup_by_name(vname);
1535 if (!bgp_import)
1536 continue;
1537
1538 ecommunity_del_val(bgp_import->vpn_policy[afi].
1539 rtlist[idir],
1540 (struct ecommunity_val *)ecom->val);
1541
1542 }
1543 } else {
1544 /*
1545 * Router-id changes that are not explicit config
1546 * changes should not replace configured RD/RT.
1547 */
1548 if (!is_config) {
1549 if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
1550 BGP_VPN_POLICY_TOVPN_RD_SET)) {
1551 if (debug)
1552 zlog_debug("%s: auto router-id change skipped",
1553 __func__);
1554 goto postchange;
1555 }
1556 }
1557
1558 /* New router-id derive auto RD and RT and export
1559 * to VPN
1560 */
1561 form_auto_rd(bgp->router_id, bgp->vrf_rd_id,
1562 &bgp->vrf_prd_auto);
1563 bgp->vpn_policy[afi].tovpn_rd = bgp->vrf_prd_auto;
1564 prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf,
1565 sizeof(buf));
1566 bgp->vpn_policy[afi].rtlist[edir] =
1567 ecommunity_str2com(buf,
1568 ECOMMUNITY_ROUTE_TARGET, 0);
1569
1570 /* Update import_vrf rt_list */
1571 ecom = bgp->vpn_policy[afi].rtlist[edir];
1572 for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
1573 export_vrf, node, vname)) {
1574 bgp_import = bgp_lookup_by_name(vname);
1575 if (!bgp_import)
1576 continue;
1577 if (bgp_import->vpn_policy[afi].rtlist[idir])
1578 bgp_import->vpn_policy[afi].rtlist[idir]
1579 = ecommunity_merge(
1580 bgp_import->vpn_policy[afi]
1581 .rtlist[idir], ecom);
1582 else
1583 bgp_import->vpn_policy[afi].rtlist[idir]
1584 = ecommunity_dup(ecom);
1585
1586 }
1587
1588 postchange:
1589 /* Update routes to VPN */
1590 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
1591 afi, bgp_get_default(),
1592 bgp);
1593 if (debug)
1594 zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
1595 __func__, export_name);
1596 }
1597 }
1598 }
1599
1600 void vpn_policy_routemap_event(const char *rmap_name)
1601 {
1602 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1603 struct listnode *mnode, *mnnode;
1604 struct bgp *bgp;
1605
1606 if (debug)
1607 zlog_debug("%s: entry", __func__);
1608
1609 if (bm->bgp == NULL) /* may be called during cleanup */
1610 return;
1611
1612 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
1613 vpn_policy_routemap_update(bgp, rmap_name);
1614 }
1615
1616 void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
1617 afi_t afi, safi_t safi)
1618 {
1619 const char *export_name;
1620 vpn_policy_direction_t idir, edir;
1621 char *vname, *tmp_name;
1622 char buf[RD_ADDRSTRLEN];
1623 struct ecommunity *ecom;
1624 bool first_export = false;
1625 int debug;
1626 struct listnode *node;
1627 bool is_inst_match = false;
1628
1629 export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
1630 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1631 edir = BGP_VPN_POLICY_DIR_TOVPN;
1632
1633 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
1634 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
1635
1636 /*
1637 * Cross-ref both VRFs. Also, note if this is the first time
1638 * any VRF is importing from "import_vrf".
1639 */
1640 vname = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
1641 : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME));
1642
1643 /* Check the import_vrf list of destination vrf for the source vrf name,
1644 * insert otherwise.
1645 */
1646 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf,
1647 node, tmp_name)) {
1648 if (strcmp(vname, tmp_name) == 0) {
1649 is_inst_match = true;
1650 break;
1651 }
1652 }
1653 if (!is_inst_match)
1654 listnode_add(to_bgp->vpn_policy[afi].import_vrf,
1655 vname);
1656
1657 /* Check if the source vrf already exports to any vrf,
1658 * first time export requires to setup auto derived RD/RT values.
1659 * Add the destination vrf name to export vrf list if it is
1660 * not present.
1661 */
1662 is_inst_match = false;
1663 vname = XSTRDUP(MTYPE_TMP, export_name);
1664 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
1665 first_export = true;
1666 } else {
1667 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
1668 node, tmp_name)) {
1669 if (strcmp(vname, tmp_name) == 0) {
1670 is_inst_match = true;
1671 break;
1672 }
1673 }
1674 }
1675 if (!is_inst_match)
1676 listnode_add(from_bgp->vpn_policy[afi].export_vrf,
1677 vname);
1678 /* Update import RT for current VRF using export RT of the VRF we're
1679 * importing from. First though, make sure "import_vrf" has that
1680 * set.
1681 */
1682 if (first_export) {
1683 form_auto_rd(from_bgp->router_id, from_bgp->vrf_rd_id,
1684 &from_bgp->vrf_prd_auto);
1685 from_bgp->vpn_policy[afi].tovpn_rd = from_bgp->vrf_prd_auto;
1686 SET_FLAG(from_bgp->vpn_policy[afi].flags,
1687 BGP_VPN_POLICY_TOVPN_RD_SET);
1688 prefix_rd2str(&from_bgp->vpn_policy[afi].tovpn_rd,
1689 buf, sizeof(buf));
1690 from_bgp->vpn_policy[afi].rtlist[edir] =
1691 ecommunity_str2com(buf, ECOMMUNITY_ROUTE_TARGET, 0);
1692 SET_FLAG(from_bgp->af_flags[afi][safi],
1693 BGP_CONFIG_VRF_TO_VRF_EXPORT);
1694 from_bgp->vpn_policy[afi].tovpn_label =
1695 BGP_PREVENT_VRF_2_VRF_LEAK;
1696 }
1697 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
1698 if (to_bgp->vpn_policy[afi].rtlist[idir])
1699 to_bgp->vpn_policy[afi].rtlist[idir] =
1700 ecommunity_merge(to_bgp->vpn_policy[afi]
1701 .rtlist[idir], ecom);
1702 else
1703 to_bgp->vpn_policy[afi].rtlist[idir] = ecommunity_dup(ecom);
1704 SET_FLAG(to_bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT);
1705
1706 if (debug) {
1707 const char *from_name;
1708
1709 from_name = from_bgp->name ? from_bgp->name :
1710 VRF_DEFAULT_NAME;
1711 zlog_debug("%s from %s to %s first_export %u import-rt %s export-rt %s",
1712 __func__, from_name, export_name, first_export,
1713 to_bgp->vpn_policy[afi].rtlist[idir] ?
1714 (ecommunity_ecom2str(to_bgp->vpn_policy[afi].
1715 rtlist[idir],
1716 ECOMMUNITY_FORMAT_ROUTE_MAP, 0)) : " ",
1717 to_bgp->vpn_policy[afi].rtlist[edir] ?
1718 (ecommunity_ecom2str(to_bgp->vpn_policy[afi].
1719 rtlist[edir],
1720 ECOMMUNITY_FORMAT_ROUTE_MAP, 0)) : " ");
1721 }
1722
1723 /* Does "import_vrf" first need to export its routes or that
1724 * is already done and we just need to import those routes
1725 * from the global table?
1726 */
1727 if (first_export)
1728 vpn_leak_postchange(edir, afi, bgp_get_default(), from_bgp);
1729 else
1730 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
1731 }
1732
1733 void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
1734 afi_t afi, safi_t safi)
1735 {
1736 const char *export_name, *tmp_name;
1737 vpn_policy_direction_t idir, edir;
1738 char *vname;
1739 struct ecommunity *ecom = NULL;
1740 struct listnode *node;
1741 int debug;
1742
1743 export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
1744 tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
1745 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1746 edir = BGP_VPN_POLICY_DIR_TOVPN;
1747
1748 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
1749 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
1750
1751 /* Were we importing from "import_vrf"? */
1752 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf, node,
1753 vname)) {
1754 if (strcmp(vname, tmp_name) == 0)
1755 break;
1756 }
1757
1758 /*
1759 * We do not check in the cli if the passed in bgp
1760 * instance is actually imported into us before
1761 * we call this function. As such if we do not
1762 * find this in the import_vrf list than
1763 * we just need to return safely.
1764 */
1765 if (!vname)
1766 return;
1767
1768 if (debug)
1769 zlog_debug("%s from %s to %s", __func__, tmp_name, export_name);
1770
1771 /* Remove "import_vrf" from our import list. */
1772 listnode_delete(to_bgp->vpn_policy[afi].import_vrf, vname);
1773 XFREE(MTYPE_TMP, vname);
1774
1775 /* Remove routes imported from "import_vrf". */
1776 /* TODO: In the current logic, we have to first remove all
1777 * imported routes and then (if needed) import back routes
1778 */
1779 vpn_leak_prechange(idir, afi, bgp_get_default(), to_bgp);
1780
1781 if (to_bgp->vpn_policy[afi].import_vrf->count == 0) {
1782 UNSET_FLAG(to_bgp->af_flags[afi][safi],
1783 BGP_CONFIG_VRF_TO_VRF_IMPORT);
1784 if (to_bgp->vpn_policy[afi].rtlist[idir])
1785 ecommunity_free(&to_bgp->vpn_policy[afi].rtlist[idir]);
1786 } else {
1787 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
1788 if (ecom)
1789 ecommunity_del_val(to_bgp->vpn_policy[afi].rtlist[idir],
1790 (struct ecommunity_val *)ecom->val);
1791 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
1792 }
1793
1794 /*
1795 * What?
1796 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
1797 * below is checking for NULL that export_vrf can be
1798 * NULL, consequently it is complaining( like a cabbage )
1799 * that we could dereference and crash in the listcount(..)
1800 * check below.
1801 * So make it happy, under protest, with liberty and justice
1802 * for all.
1803 */
1804 assert(from_bgp->vpn_policy[afi].export_vrf);
1805
1806 /* Remove us from "import_vrf's" export list. If no other VRF
1807 * is importing from "import_vrf", cleanup appropriately.
1808 */
1809 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
1810 node, vname)) {
1811 if (strcmp(vname, export_name) == 0)
1812 break;
1813 }
1814
1815 /*
1816 * If we have gotten to this point then the vname must
1817 * exist. If not, we are in a world of trouble and
1818 * have slag sitting around.
1819 *
1820 * import_vrf and export_vrf must match in having
1821 * the in/out names as appropriate.
1822 * export_vrf list could have been cleaned up
1823 * as part of no router bgp source instnace.
1824 */
1825 if (!vname)
1826 return;
1827
1828 listnode_delete(from_bgp->vpn_policy[afi].export_vrf, vname);
1829 XFREE(MTYPE_TMP, vname);
1830
1831 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
1832 vpn_leak_prechange(edir, afi, bgp_get_default(), from_bgp);
1833 ecommunity_free(&from_bgp->vpn_policy[afi].rtlist[edir]);
1834 UNSET_FLAG(from_bgp->af_flags[afi][safi],
1835 BGP_CONFIG_VRF_TO_VRF_EXPORT);
1836 memset(&from_bgp->vpn_policy[afi].tovpn_rd, 0,
1837 sizeof(struct prefix_rd));
1838 UNSET_FLAG(from_bgp->vpn_policy[afi].flags,
1839 BGP_VPN_POLICY_TOVPN_RD_SET);
1840 from_bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE;
1841
1842 }
1843 }
1844
1845 /* For testing purpose, static route of MPLS-VPN. */
1846 DEFUN (vpnv4_network,
1847 vpnv4_network_cmd,
1848 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1849 "Specify a network to announce via BGP\n"
1850 "IPv4 prefix\n"
1851 "Specify Route Distinguisher\n"
1852 "VPN Route Distinguisher\n"
1853 "VPN NLRI label (tag)\n"
1854 "VPN NLRI label (tag)\n"
1855 "Label value\n")
1856 {
1857 int idx_ipv4_prefixlen = 1;
1858 int idx_ext_community = 3;
1859 int idx_label = 5;
1860 return bgp_static_set_safi(
1861 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1862 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
1863 NULL, NULL, NULL, NULL);
1864 }
1865
1866 DEFUN (vpnv4_network_route_map,
1867 vpnv4_network_route_map_cmd,
1868 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
1869 "Specify a network to announce via BGP\n"
1870 "IPv4 prefix\n"
1871 "Specify Route Distinguisher\n"
1872 "VPN Route Distinguisher\n"
1873 "VPN NLRI label (tag)\n"
1874 "VPN NLRI label (tag)\n"
1875 "Label value\n"
1876 "route map\n"
1877 "route map name\n")
1878 {
1879 int idx_ipv4_prefixlen = 1;
1880 int idx_ext_community = 3;
1881 int idx_label = 5;
1882 int idx_word_2 = 7;
1883 return bgp_static_set_safi(
1884 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1885 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1886 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
1887 }
1888
1889 /* For testing purpose, static route of MPLS-VPN. */
1890 DEFUN (no_vpnv4_network,
1891 no_vpnv4_network_cmd,
1892 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1893 NO_STR
1894 "Specify a network to announce via BGP\n"
1895 "IPv4 prefix\n"
1896 "Specify Route Distinguisher\n"
1897 "VPN Route Distinguisher\n"
1898 "VPN NLRI label (tag)\n"
1899 "VPN NLRI label (tag)\n"
1900 "Label value\n")
1901 {
1902 int idx_ipv4_prefixlen = 2;
1903 int idx_ext_community = 4;
1904 int idx_label = 6;
1905 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
1906 argv[idx_ipv4_prefixlen]->arg,
1907 argv[idx_ext_community]->arg,
1908 argv[idx_label]->arg, 0, NULL, NULL, NULL);
1909 }
1910
1911 DEFUN (vpnv6_network,
1912 vpnv6_network_cmd,
1913 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
1914 "Specify a network to announce via BGP\n"
1915 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1916 "Specify Route Distinguisher\n"
1917 "VPN Route Distinguisher\n"
1918 "VPN NLRI label (tag)\n"
1919 "VPN NLRI label (tag)\n"
1920 "Label value\n"
1921 "route map\n"
1922 "route map name\n")
1923 {
1924 int idx_ipv6_prefix = 1;
1925 int idx_ext_community = 3;
1926 int idx_label = 5;
1927 int idx_word_2 = 7;
1928 if (argc == 8)
1929 return bgp_static_set_safi(
1930 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1931 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1932 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
1933 else
1934 return bgp_static_set_safi(
1935 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1936 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1937 NULL, 0, NULL, NULL, NULL, NULL);
1938 }
1939
1940 /* For testing purpose, static route of MPLS-VPN. */
1941 DEFUN (no_vpnv6_network,
1942 no_vpnv6_network_cmd,
1943 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
1944 NO_STR
1945 "Specify a network to announce via BGP\n"
1946 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1947 "Specify Route Distinguisher\n"
1948 "VPN Route Distinguisher\n"
1949 "VPN NLRI label (tag)\n"
1950 "VPN NLRI label (tag)\n"
1951 "Label value\n")
1952 {
1953 int idx_ipv6_prefix = 2;
1954 int idx_ext_community = 4;
1955 int idx_label = 6;
1956 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
1957 argv[idx_ipv6_prefix]->arg,
1958 argv[idx_ext_community]->arg,
1959 argv[idx_label]->arg, 0, NULL, NULL, NULL);
1960 }
1961
1962 int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
1963 enum bgp_show_type type, void *output_arg, int tags,
1964 bool use_json)
1965 {
1966 struct bgp *bgp;
1967 struct bgp_table *table;
1968
1969 bgp = bgp_get_default();
1970 if (bgp == NULL) {
1971 if (!use_json)
1972 vty_out(vty, "No BGP process is configured\n");
1973 else
1974 vty_out(vty, "{}\n");
1975 return CMD_WARNING;
1976 }
1977 table = bgp->rib[afi][SAFI_MPLS_VPN];
1978 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
1979 output_arg, use_json);
1980 }
1981
1982 DEFUN (show_bgp_ip_vpn_all_rd,
1983 show_bgp_ip_vpn_all_rd_cmd,
1984 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
1985 SHOW_STR
1986 BGP_STR
1987 BGP_VPNVX_HELP_STR
1988 "Display VPN NLRI specific information\n"
1989 "Display VPN NLRI specific information\n"
1990 "Display information for a route distinguisher\n"
1991 "VPN Route Distinguisher\n"
1992 JSON_STR)
1993 {
1994 int ret;
1995 struct prefix_rd prd;
1996 afi_t afi;
1997 int idx = 0;
1998
1999 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
2000 if (argv_find(argv, argc, "rd", &idx)) {
2001 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
2002 if (!ret) {
2003 vty_out(vty,
2004 "%% Malformed Route Distinguisher\n");
2005 return CMD_WARNING;
2006 }
2007 return bgp_show_mpls_vpn(vty, afi, &prd,
2008 bgp_show_type_normal, NULL, 0,
2009 use_json(argc, argv));
2010 } else {
2011 return bgp_show_mpls_vpn(vty, afi, NULL,
2012 bgp_show_type_normal, NULL, 0,
2013 use_json(argc, argv));
2014 }
2015 }
2016 return CMD_SUCCESS;
2017 }
2018
2019 ALIAS(show_bgp_ip_vpn_all_rd,
2020 show_bgp_ip_vpn_rd_cmd,
2021 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
2022 SHOW_STR
2023 BGP_STR
2024 BGP_VPNVX_HELP_STR
2025 "Display VPN NLRI specific information\n"
2026 "Display information for a route distinguisher\n"
2027 "VPN Route Distinguisher\n"
2028 JSON_STR)
2029
2030 #ifdef KEEP_OLD_VPN_COMMANDS
2031 DEFUN (show_ip_bgp_vpn_rd,
2032 show_ip_bgp_vpn_rd_cmd,
2033 "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
2034 SHOW_STR
2035 IP_STR
2036 BGP_STR
2037 BGP_AFI_HELP_STR
2038 "Address Family modifier\n"
2039 "Display information for a route distinguisher\n"
2040 "VPN Route Distinguisher\n")
2041 {
2042 int idx_ext_community = argc - 1;
2043 int ret;
2044 struct prefix_rd prd;
2045 afi_t afi;
2046 int idx = 0;
2047
2048 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2049 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2050 if (!ret) {
2051 vty_out(vty, "%% Malformed Route Distinguisher\n");
2052 return CMD_WARNING;
2053 }
2054 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
2055 NULL, 0, 0);
2056 }
2057 return CMD_SUCCESS;
2058 }
2059
2060 DEFUN (show_ip_bgp_vpn_all,
2061 show_ip_bgp_vpn_all_cmd,
2062 "show [ip] bgp <vpnv4|vpnv6>",
2063 SHOW_STR
2064 IP_STR
2065 BGP_STR
2066 BGP_VPNVX_HELP_STR)
2067 {
2068 afi_t afi;
2069 int idx = 0;
2070
2071 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
2072 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
2073 NULL, 0, 0);
2074 return CMD_SUCCESS;
2075 }
2076
2077 DEFUN (show_ip_bgp_vpn_all_tags,
2078 show_ip_bgp_vpn_all_tags_cmd,
2079 "show [ip] bgp <vpnv4|vpnv6> all tags",
2080 SHOW_STR
2081 IP_STR
2082 BGP_STR
2083 BGP_VPNVX_HELP_STR
2084 "Display information about all VPNv4/VPNV6 NLRIs\n"
2085 "Display BGP tags for prefixes\n")
2086 {
2087 afi_t afi;
2088 int idx = 0;
2089
2090 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
2091 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
2092 NULL, 1, 0);
2093 return CMD_SUCCESS;
2094 }
2095
2096 DEFUN (show_ip_bgp_vpn_rd_tags,
2097 show_ip_bgp_vpn_rd_tags_cmd,
2098 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
2099 SHOW_STR
2100 IP_STR
2101 BGP_STR
2102 BGP_VPNVX_HELP_STR
2103 "Display information for a route distinguisher\n"
2104 "VPN Route Distinguisher\n"
2105 "Display BGP tags for prefixes\n")
2106 {
2107 int idx_ext_community = 5;
2108 int ret;
2109 struct prefix_rd prd;
2110 afi_t afi;
2111 int idx = 0;
2112
2113 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2114 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2115 if (!ret) {
2116 vty_out(vty, "%% Malformed Route Distinguisher\n");
2117 return CMD_WARNING;
2118 }
2119 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
2120 NULL, 1, 0);
2121 }
2122 return CMD_SUCCESS;
2123 }
2124
2125 DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
2126 show_ip_bgp_vpn_all_neighbor_routes_cmd,
2127 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
2128 SHOW_STR
2129 IP_STR
2130 BGP_STR
2131 BGP_VPNVX_HELP_STR
2132 "Display information about all VPNv4/VPNv6 NLRIs\n"
2133 "Detailed information on TCP and BGP neighbor connections\n"
2134 "Neighbor to display information about\n"
2135 "Display routes learned from neighbor\n"
2136 JSON_STR)
2137 {
2138 int idx_ipv4 = 6;
2139 union sockunion su;
2140 struct peer *peer;
2141 int ret;
2142 bool uj = use_json(argc, argv);
2143 afi_t afi;
2144 int idx = 0;
2145
2146 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2147 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2148 if (ret < 0) {
2149 if (uj) {
2150 json_object *json_no = NULL;
2151 json_no = json_object_new_object();
2152 json_object_string_add(json_no, "warning",
2153 "Malformed address");
2154 vty_out(vty, "%s\n",
2155 json_object_to_json_string(json_no));
2156 json_object_free(json_no);
2157 } else
2158 vty_out(vty, "Malformed address: %s\n",
2159 argv[idx_ipv4]->arg);
2160 return CMD_WARNING;
2161 }
2162
2163 peer = peer_lookup(NULL, &su);
2164 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2165 if (uj) {
2166 json_object *json_no = NULL;
2167 json_no = json_object_new_object();
2168 json_object_string_add(
2169 json_no, "warning",
2170 "No such neighbor or address family");
2171 vty_out(vty, "%s\n",
2172 json_object_to_json_string(json_no));
2173 json_object_free(json_no);
2174 } else
2175 vty_out(vty,
2176 "%% No such neighbor or address family\n");
2177 return CMD_WARNING;
2178 }
2179
2180 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
2181 &su, 0, uj);
2182 }
2183 return CMD_SUCCESS;
2184 }
2185
2186 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
2187 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
2188 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
2189 SHOW_STR
2190 IP_STR
2191 BGP_STR
2192 BGP_VPNVX_HELP_STR
2193 "Display information for a route distinguisher\n"
2194 "VPN Route Distinguisher\n"
2195 "Detailed information on TCP and BGP neighbor connections\n"
2196 "Neighbor to display information about\n"
2197 "Display routes learned from neighbor\n"
2198 JSON_STR)
2199 {
2200 int idx_ext_community = 5;
2201 int idx_ipv4 = 7;
2202 int ret;
2203 union sockunion su;
2204 struct peer *peer;
2205 struct prefix_rd prd;
2206 bool uj = use_json(argc, argv);
2207 afi_t afi;
2208 int idx = 0;
2209
2210 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2211 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2212 if (!ret) {
2213 if (uj) {
2214 json_object *json_no = NULL;
2215 json_no = json_object_new_object();
2216 json_object_string_add(
2217 json_no, "warning",
2218 "Malformed Route Distinguisher");
2219 vty_out(vty, "%s\n",
2220 json_object_to_json_string(json_no));
2221 json_object_free(json_no);
2222 } else
2223 vty_out(vty,
2224 "%% Malformed Route Distinguisher\n");
2225 return CMD_WARNING;
2226 }
2227
2228 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2229 if (ret < 0) {
2230 if (uj) {
2231 json_object *json_no = NULL;
2232 json_no = json_object_new_object();
2233 json_object_string_add(json_no, "warning",
2234 "Malformed address");
2235 vty_out(vty, "%s\n",
2236 json_object_to_json_string(json_no));
2237 json_object_free(json_no);
2238 } else
2239 vty_out(vty, "Malformed address: %s\n",
2240 argv[idx_ext_community]->arg);
2241 return CMD_WARNING;
2242 }
2243
2244 peer = peer_lookup(NULL, &su);
2245 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2246 if (uj) {
2247 json_object *json_no = NULL;
2248 json_no = json_object_new_object();
2249 json_object_string_add(
2250 json_no, "warning",
2251 "No such neighbor or address family");
2252 vty_out(vty, "%s\n",
2253 json_object_to_json_string(json_no));
2254 json_object_free(json_no);
2255 } else
2256 vty_out(vty,
2257 "%% No such neighbor or address family\n");
2258 return CMD_WARNING;
2259 }
2260
2261 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_neighbor,
2262 &su, 0, uj);
2263 }
2264 return CMD_SUCCESS;
2265 }
2266
2267 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
2268 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
2269 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
2270 SHOW_STR
2271 IP_STR
2272 BGP_STR
2273 BGP_VPNVX_HELP_STR
2274 "Display information about all VPNv4/VPNv6 NLRIs\n"
2275 "Detailed information on TCP and BGP neighbor connections\n"
2276 "Neighbor to display information about\n"
2277 "Display the routes advertised to a BGP neighbor\n"
2278 JSON_STR)
2279 {
2280 int idx_ipv4 = 6;
2281 int ret;
2282 struct peer *peer;
2283 union sockunion su;
2284 bool uj = use_json(argc, argv);
2285 afi_t afi;
2286 int idx = 0;
2287
2288 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2289 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2290 if (ret < 0) {
2291 if (uj) {
2292 json_object *json_no = NULL;
2293 json_no = json_object_new_object();
2294 json_object_string_add(json_no, "warning",
2295 "Malformed address");
2296 vty_out(vty, "%s\n",
2297 json_object_to_json_string(json_no));
2298 json_object_free(json_no);
2299 } else
2300 vty_out(vty, "Malformed address: %s\n",
2301 argv[idx_ipv4]->arg);
2302 return CMD_WARNING;
2303 }
2304 peer = peer_lookup(NULL, &su);
2305 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2306 if (uj) {
2307 json_object *json_no = NULL;
2308 json_no = json_object_new_object();
2309 json_object_string_add(
2310 json_no, "warning",
2311 "No such neighbor or address family");
2312 vty_out(vty, "%s\n",
2313 json_object_to_json_string(json_no));
2314 json_object_free(json_no);
2315 } else
2316 vty_out(vty,
2317 "%% No such neighbor or address family\n");
2318 return CMD_WARNING;
2319 }
2320 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
2321 SAFI_MPLS_VPN, uj);
2322 }
2323 return CMD_SUCCESS;
2324 }
2325
2326 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
2327 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
2328 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
2329 SHOW_STR
2330 IP_STR
2331 BGP_STR
2332 BGP_VPNVX_HELP_STR
2333 "Display information for a route distinguisher\n"
2334 "VPN Route Distinguisher\n"
2335 "Detailed information on TCP and BGP neighbor connections\n"
2336 "Neighbor to display information about\n"
2337 "Display the routes advertised to a BGP neighbor\n"
2338 JSON_STR)
2339 {
2340 int idx_ext_community = 5;
2341 int idx_ipv4 = 7;
2342 int ret;
2343 struct peer *peer;
2344 struct prefix_rd prd;
2345 union sockunion su;
2346 bool uj = use_json(argc, argv);
2347 afi_t afi;
2348 int idx = 0;
2349
2350 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2351 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2352 if (ret < 0) {
2353 if (uj) {
2354 json_object *json_no = NULL;
2355 json_no = json_object_new_object();
2356 json_object_string_add(json_no, "warning",
2357 "Malformed address");
2358 vty_out(vty, "%s\n",
2359 json_object_to_json_string(json_no));
2360 json_object_free(json_no);
2361 } else
2362 vty_out(vty, "Malformed address: %s\n",
2363 argv[idx_ext_community]->arg);
2364 return CMD_WARNING;
2365 }
2366 peer = peer_lookup(NULL, &su);
2367 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2368 if (uj) {
2369 json_object *json_no = NULL;
2370 json_no = json_object_new_object();
2371 json_object_string_add(
2372 json_no, "warning",
2373 "No such neighbor or address family");
2374 vty_out(vty, "%s\n",
2375 json_object_to_json_string(json_no));
2376 json_object_free(json_no);
2377 } else
2378 vty_out(vty,
2379 "%% No such neighbor or address family\n");
2380 return CMD_WARNING;
2381 }
2382
2383 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2384 if (!ret) {
2385 if (uj) {
2386 json_object *json_no = NULL;
2387 json_no = json_object_new_object();
2388 json_object_string_add(
2389 json_no, "warning",
2390 "Malformed Route Distinguisher");
2391 vty_out(vty, "%s\n",
2392 json_object_to_json_string(json_no));
2393 json_object_free(json_no);
2394 } else
2395 vty_out(vty,
2396 "%% Malformed Route Distinguisher\n");
2397 return CMD_WARNING;
2398 }
2399
2400 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
2401 SAFI_MPLS_VPN, uj);
2402 }
2403 return CMD_SUCCESS;
2404 }
2405 #endif /* KEEP_OLD_VPN_COMMANDS */
2406
2407 void bgp_mplsvpn_init(void)
2408 {
2409 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
2410 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
2411 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
2412
2413 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
2414 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
2415
2416 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
2417 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
2418 #ifdef KEEP_OLD_VPN_COMMANDS
2419 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
2420 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
2421 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
2422 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
2423 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
2424 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
2425 install_element(VIEW_NODE,
2426 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
2427 install_element(VIEW_NODE,
2428 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
2429 #endif /* KEEP_OLD_VPN_COMMANDS */
2430 }
2431
2432 vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
2433 {
2434 struct listnode *mnode, *mnnode;
2435 struct bgp *bgp;
2436
2437 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2438 struct ecommunity *ec;
2439
2440 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2441 continue;
2442
2443 ec = bgp->vpn_policy[AFI_IP].import_redirect_rtlist;
2444
2445 if (ecom_intersect(ec, eckey))
2446 return bgp->vrf_id;
2447 }
2448 return VRF_UNKNOWN;
2449 }
2450
2451 /*
2452 * The purpose of this function is to process leaks that were deferred
2453 * from earlier per-vrf configuration due to not-yet-existing default
2454 * vrf, in other words, configuration such as:
2455 *
2456 * router bgp MMM vrf FOO
2457 * address-family ipv4 unicast
2458 * rd vpn export 1:1
2459 * exit-address-family
2460 *
2461 * router bgp NNN
2462 * ...
2463 *
2464 * This function gets called when the default instance ("router bgp NNN")
2465 * is created.
2466 */
2467 void vpn_leak_postchange_all(void)
2468 {
2469 struct listnode *next;
2470 struct bgp *bgp;
2471 struct bgp *bgp_default = bgp_get_default();
2472
2473 assert(bgp_default);
2474
2475 /* First, do any exporting from VRFs to the single VPN RIB */
2476 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
2477
2478 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2479 continue;
2480
2481 vpn_leak_postchange(
2482 BGP_VPN_POLICY_DIR_TOVPN,
2483 AFI_IP,
2484 bgp_default,
2485 bgp);
2486
2487 vpn_leak_postchange(
2488 BGP_VPN_POLICY_DIR_TOVPN,
2489 AFI_IP6,
2490 bgp_default,
2491 bgp);
2492 }
2493
2494 /* Now, do any importing to VRFs from the single VPN RIB */
2495 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
2496
2497 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2498 continue;
2499
2500 vpn_leak_postchange(
2501 BGP_VPN_POLICY_DIR_FROMVPN,
2502 AFI_IP,
2503 bgp_default,
2504 bgp);
2505
2506 vpn_leak_postchange(
2507 BGP_VPN_POLICY_DIR_FROMVPN,
2508 AFI_IP6,
2509 bgp_default,
2510 bgp);
2511 }
2512 }
2513
2514 /* When a bgp vrf instance is unconfigured, remove its routes
2515 * from the VPN table and this vrf could be importing routes from other
2516 * bgp vrf instnaces, unimport them.
2517 * VRF X and VRF Y are exporting routes to each other.
2518 * When VRF X is deleted, unimport its routes from all target vrfs,
2519 * also VRF Y should unimport its routes from VRF X table.
2520 * This will ensure VPN table is cleaned up appropriately.
2521 */
2522 int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty)
2523 {
2524 struct bgp *to_bgp;
2525 const char *tmp_name;
2526 char *vname;
2527 struct listnode *node, *next;
2528 safi_t safi = SAFI_UNICAST;
2529 afi_t afi;
2530 bool is_vrf_leak_bind;
2531 int debug;
2532
2533 if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2534 return 0;
2535
2536 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
2537 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2538
2539 tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
2540
2541 for (afi = 0; afi < AFI_MAX; ++afi) {
2542 /* vrf leak is for IPv4 and IPv6 Unicast only */
2543 if (afi != AFI_IP && afi != AFI_IP6)
2544 continue;
2545
2546 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
2547 if (from_bgp == to_bgp)
2548 continue;
2549
2550 /* Unimport and remove source vrf from the
2551 * other vrfs import list.
2552 */
2553 struct vpn_policy *to_vpolicy;
2554
2555 is_vrf_leak_bind = false;
2556 to_vpolicy = &(to_bgp->vpn_policy[afi]);
2557 for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf, node,
2558 vname)) {
2559 if (strcmp(vname, tmp_name) == 0) {
2560 is_vrf_leak_bind = true;
2561 break;
2562 }
2563 }
2564 /* skip this bgp instance as there is no leak to this
2565 * vrf instance.
2566 */
2567 if (!is_vrf_leak_bind)
2568 continue;
2569
2570 if (debug)
2571 zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
2572 __func__, from_bgp->name_pretty,
2573 to_bgp->name_pretty, afi2str(afi),
2574 to_vpolicy->import_vrf->count);
2575
2576 vrf_unimport_from_vrf(to_bgp, from_bgp, afi, safi);
2577
2578 /* readd vrf name as unimport removes import vrf name
2579 * from the destination vrf's import list where the
2580 * `import vrf` configuration still exist.
2581 */
2582 vname = XSTRDUP(MTYPE_TMP, tmp_name);
2583 listnode_add(to_bgp->vpn_policy[afi].import_vrf,
2584 vname);
2585 SET_FLAG(to_bgp->af_flags[afi][safi],
2586 BGP_CONFIG_VRF_TO_VRF_IMPORT);
2587
2588 /* If to_bgp exports its routes to the bgp vrf
2589 * which is being deleted, un-import the
2590 * to_bgp routes from VPN.
2591 */
2592 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi]
2593 .export_vrf, node,
2594 vname)) {
2595 if (strcmp(vname, tmp_name) == 0) {
2596 vrf_unimport_from_vrf(from_bgp, to_bgp,
2597 afi, safi);
2598 break;
2599 }
2600 }
2601 }
2602 }
2603 return 0;
2604 }
2605
2606 /* When a router bgp is configured, there could be a bgp vrf
2607 * instance importing routes from this newly configured
2608 * bgp vrf instance. Export routes from configured
2609 * bgp vrf to VPN.
2610 * VRF Y has import from bgp vrf x,
2611 * when a bgp vrf x instance is created, export its routes
2612 * to VRF Y instance.
2613 */
2614 void bgp_vpn_leak_export(struct bgp *from_bgp)
2615 {
2616 afi_t afi;
2617 const char *export_name;
2618 char *vname;
2619 struct listnode *node, *next;
2620 struct ecommunity *ecom;
2621 vpn_policy_direction_t idir, edir;
2622 safi_t safi = SAFI_UNICAST;
2623 struct bgp *to_bgp;
2624 int debug;
2625
2626 debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
2627 BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
2628
2629 idir = BGP_VPN_POLICY_DIR_FROMVPN;
2630 edir = BGP_VPN_POLICY_DIR_TOVPN;
2631
2632 export_name = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
2633 : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME));
2634
2635 for (afi = 0; afi < AFI_MAX; ++afi) {
2636 /* vrf leak is for IPv4 and IPv6 Unicast only */
2637 if (afi != AFI_IP && afi != AFI_IP6)
2638 continue;
2639
2640 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
2641 if (from_bgp == to_bgp)
2642 continue;
2643
2644 /* bgp instance has import list, check to see if newly
2645 * configured bgp instance is the list.
2646 */
2647 struct vpn_policy *to_vpolicy;
2648
2649 to_vpolicy = &(to_bgp->vpn_policy[afi]);
2650 for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf,
2651 node, vname)) {
2652 if (strcmp(vname, export_name) != 0)
2653 continue;
2654
2655 if (debug)
2656 zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
2657 __func__,
2658 export_name, to_bgp->name_pretty);
2659
2660 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
2661 /* remove import rt, it will be readded
2662 * as part of import from vrf.
2663 */
2664 if (ecom)
2665 ecommunity_del_val(
2666 to_vpolicy->rtlist[idir],
2667 (struct ecommunity_val *)
2668 ecom->val);
2669 vrf_import_from_vrf(to_bgp, from_bgp,
2670 afi, safi);
2671 break;
2672
2673 }
2674 }
2675 }
2676 }