]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.c
Merge pull request #3125 from dslicenc/linklocal-nht
[mirror_frr.git] / bgpd / bgp_mplsvpn.c
CommitLineData
718e3744 1/* MPLS-VPN
896014f4
DL
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 */
718e3744 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"
3f9c7369 28#include "queue.h"
039f3a34 29#include "filter.h"
ddb5b488 30#include "mpls.h"
b9c7bc5a
PZ
31#include "json.h"
32#include "zclient.h"
9bedbb1e 33
718e3744 34#include "bgpd/bgpd.h"
ddb5b488 35#include "bgpd/bgp_debug.h"
14454c9f 36#include "bgpd/bgp_errors.h"
718e3744 37#include "bgpd/bgp_table.h"
38#include "bgpd/bgp_route.h"
39#include "bgpd/bgp_attr.h"
9bedbb1e 40#include "bgpd/bgp_label.h"
718e3744 41#include "bgpd/bgp_mplsvpn.h"
48a5452b 42#include "bgpd/bgp_packet.h"
3f227172 43#include "bgpd/bgp_vty.h"
784d3a42 44#include "bgpd/bgp_vpn.h"
ddb5b488
PZ
45#include "bgpd/bgp_ecommunity.h"
46#include "bgpd/bgp_zebra.h"
47#include "bgpd/bgp_nexthop.h"
960035b2 48#include "bgpd/bgp_nht.h"
718e3744 49
65efcfce 50#if ENABLE_BGP_VNC
f8b6f499 51#include "bgpd/rfapi/rfapi_backend.h"
65efcfce
LB
52#endif
53
ddb5b488
PZ
54/*
55 * Definitions and external declarations.
56 */
57extern struct zclient *zclient;
58
d62a17ae 59extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
60 int *index, afi_t *afi)
3f227172 61{
d62a17ae 62 int ret = 0;
63 if (argv_find(argv, argc, "vpnv4", index)) {
64 ret = 1;
65 if (afi)
66 *afi = AFI_IP;
67 } else if (argv_find(argv, argc, "vpnv6", index)) {
68 ret = 1;
69 if (afi)
70 *afi = AFI_IP6;
71 }
72 return ret;
3f227172
PG
73}
74
d7c0a89a 75uint32_t decode_label(mpls_label_t *label_pnt)
718e3744 76{
d7c0a89a
QY
77 uint32_t l;
78 uint8_t *pnt = (uint8_t *)label_pnt;
718e3744 79
d7c0a89a
QY
80 l = ((uint32_t)*pnt++ << 12);
81 l |= (uint32_t)*pnt++ << 4;
82 l |= (uint32_t)((*pnt & 0xf0) >> 4);
d62a17ae 83 return l;
718e3744 84}
85
d62a17ae 86void encode_label(mpls_label_t label, mpls_label_t *label_pnt)
65efcfce 87{
d7c0a89a 88 uint8_t *pnt = (uint8_t *)label_pnt;
d62a17ae 89 if (pnt == NULL)
90 return;
13b7e7f0
DS
91 if (label == BGP_PREVENT_VRF_2_VRF_LEAK) {
92 *label_pnt = label;
93 return;
94 }
d62a17ae 95 *pnt++ = (label >> 12) & 0xff;
96 *pnt++ = (label >> 4) & 0xff;
97 *pnt++ = ((label << 4) + 1) & 0xff; /* S=1 */
65efcfce
LB
98}
99
d62a17ae 100int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
101 struct bgp_nlri *packet)
718e3744 102{
d7c0a89a
QY
103 uint8_t *pnt;
104 uint8_t *lim;
d62a17ae 105 struct prefix p;
106 int psize = 0;
107 int prefixlen;
d7c0a89a 108 uint16_t type;
d62a17ae 109 struct rd_as rd_as;
110 struct rd_ip rd_ip;
111 struct prefix_rd prd;
ddb5b488 112 mpls_label_t label = {0};
d62a17ae 113 afi_t afi;
114 safi_t safi;
115 int addpath_encoded;
d7c0a89a 116 uint32_t addpath_id;
d62a17ae 117
d62a17ae 118 /* Make prefix_rd */
119 prd.family = AF_UNSPEC;
120 prd.prefixlen = 64;
121
122 pnt = packet->nlri;
123 lim = pnt + packet->length;
124 afi = packet->afi;
125 safi = packet->safi;
126 addpath_id = 0;
127
128 addpath_encoded =
129 (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
130 && CHECK_FLAG(peer->af_cap[afi][safi],
131 PEER_CAP_ADDPATH_AF_TX_RCV));
718e3744 132
50905aa2 133#define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
d62a17ae 134 for (; pnt < lim; pnt += psize) {
135 /* Clear prefix structure. */
136 memset(&p, 0, sizeof(struct prefix));
137
138 if (addpath_encoded) {
139
140 /* When packet overflow occurs return immediately. */
141 if (pnt + BGP_ADDPATH_ID_LEN > lim)
142 return -1;
143
144 addpath_id = ntohl(*((uint32_t *)pnt));
145 pnt += BGP_ADDPATH_ID_LEN;
146 }
147
148 /* Fetch prefix length. */
149 prefixlen = *pnt++;
150 p.family = afi2family(packet->afi);
151 psize = PSIZE(prefixlen);
152
153 if (prefixlen < VPN_PREFIXLEN_MIN_BYTES * 8) {
af4c2728 154 flog_err(
e50f7cfd 155 EC_BGP_UPDATE_RCV,
d62a17ae 156 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
157 peer->host, prefixlen);
158 return -1;
159 }
160
161 /* sanity check against packet data */
162 if ((pnt + psize) > lim) {
af4c2728 163 flog_err(
e50f7cfd 164 EC_BGP_UPDATE_RCV,
d62a17ae 165 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
166 peer->host, prefixlen, (uint)(lim - pnt));
167 return -1;
168 }
169
170 /* sanity check against storage for the IP address portion */
171 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t)sizeof(p.u)) {
af4c2728 172 flog_err(
e50f7cfd 173 EC_BGP_UPDATE_RCV,
d62a17ae 174 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
175 peer->host,
176 prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
177 sizeof(p.u));
178 return -1;
179 }
180
181 /* Sanity check against max bitlen of the address family */
182 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen(&p)) {
af4c2728 183 flog_err(
e50f7cfd 184 EC_BGP_UPDATE_RCV,
d62a17ae 185 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
186 peer->host,
187 prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
188 p.family, prefix_blen(&p));
189 return -1;
190 }
191
192 /* Copy label to prefix. */
193 memcpy(&label, pnt, BGP_LABEL_BYTES);
194 bgp_set_valid_label(&label);
195
196 /* Copy routing distinguisher to rd. */
197 memcpy(&prd.val, pnt + BGP_LABEL_BYTES, 8);
198
199 /* Decode RD type. */
200 type = decode_rd_type(pnt + BGP_LABEL_BYTES);
201
202 switch (type) {
203 case RD_TYPE_AS:
204 decode_rd_as(pnt + 5, &rd_as);
205 break;
206
207 case RD_TYPE_AS4:
208 decode_rd_as4(pnt + 5, &rd_as);
209 break;
210
211 case RD_TYPE_IP:
212 decode_rd_ip(pnt + 5, &rd_ip);
213 break;
fe770c88 214
65efcfce 215#if ENABLE_BGP_VNC
d62a17ae 216 case RD_TYPE_VNC_ETH:
217 break;
65efcfce
LB
218#endif
219
d62a17ae 220 default:
1c50c1c0 221 flog_err(EC_BGP_UPDATE_RCV, "Unknown RD type %d", type);
d62a17ae 222 break; /* just report */
223 }
224
225 p.prefixlen =
226 prefixlen
227 - VPN_PREFIXLEN_MIN_BYTES * 8; /* exclude label & RD */
a85297a7 228 memcpy(p.u.val, pnt + VPN_PREFIXLEN_MIN_BYTES,
d62a17ae 229 psize - VPN_PREFIXLEN_MIN_BYTES);
230
231 if (attr) {
232 bgp_update(peer, &p, addpath_id, attr, packet->afi,
233 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
b57ba6d2 234 BGP_ROUTE_NORMAL, &prd, &label, 1, 0, NULL);
d62a17ae 235 } else {
236 bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
237 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
b57ba6d2 238 BGP_ROUTE_NORMAL, &prd, &label, 1, NULL);
d62a17ae 239 }
240 }
241 /* Packet length consistency check. */
242 if (pnt != lim) {
af4c2728 243 flog_err(
e50f7cfd 244 EC_BGP_UPDATE_RCV,
d62a17ae 245 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
246 peer->host, lim - pnt);
247 return -1;
248 }
249
250 return 0;
50905aa2 251#undef VPN_PREFIXLEN_MIN_BYTES
718e3744 252}
253
ddb5b488
PZ
254/*
255 * This function informs zebra of the label this vrf sets on routes
256 * leaked to VPN. Zebra should install this label in the kernel with
257 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
258 *
259 * Sending this vrf-label association is qualified by a) whether vrf->vpn
260 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
261 * are set) and b) whether vpn-policy label is set.
262 *
263 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
264 * for this vrf, which zebra interprets to mean "delete this vrf-label
265 * association."
266 */
267void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi)
268{
269 mpls_label_t label = MPLS_LABEL_NONE;
ddb5b488
PZ
270 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
271
ddb5b488
PZ
272 if (bgp->vrf_id == VRF_UNKNOWN) {
273 if (debug) {
274 zlog_debug(
275 "%s: vrf %s: afi %s: vrf_id not set, "
276 "can't set zebra vrf label",
960035b2 277 __func__, bgp->name_pretty, afi2str(afi));
ddb5b488
PZ
278 }
279 return;
280 }
281
282 if (vpn_leak_to_vpn_active(bgp, afi, NULL)) {
283 label = bgp->vpn_policy[afi].tovpn_label;
284 }
285
286 if (debug) {
287 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
960035b2
PZ
288 __func__, bgp->name_pretty, afi2str(afi), label,
289 bgp->vrf_id);
ddb5b488
PZ
290 }
291
292 zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
293 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
294}
295
296/*
297 * If zebra tells us vrf has become unconfigured, tell zebra not to
298 * use this label to forward to the vrf anymore
299 */
300void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi)
301{
302 mpls_label_t label = MPLS_LABEL_NONE;
303 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
304
305 if (bgp->vrf_id == VRF_UNKNOWN) {
306 if (debug) {
307 zlog_debug(
308 "%s: vrf_id not set, can't delete zebra vrf label",
309 __func__);
310 }
311 return;
312 }
313
314 if (debug) {
315 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__,
960035b2 316 bgp->name_pretty, bgp->vrf_id);
ddb5b488
PZ
317 }
318
319 zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
320 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
321}
322
e70e9f8e
PZ
323int vpn_leak_label_callback(
324 mpls_label_t label,
325 void *labelid,
326 bool allocated)
327{
328 struct vpn_policy *vp = (struct vpn_policy *)labelid;
329 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
330
331 if (debug)
332 zlog_debug("%s: label=%u, allocated=%d",
333 __func__, label, allocated);
334
335 if (!allocated) {
336 /*
337 * previously-allocated label is now invalid
338 */
339 if (CHECK_FLAG(vp->flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO) &&
340 (vp->tovpn_label != MPLS_LABEL_NONE)) {
341
342 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
343 vp->afi, bgp_get_default(), vp->bgp);
344 vp->tovpn_label = MPLS_LABEL_NONE;
345 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
346 vp->afi, bgp_get_default(), vp->bgp);
347 }
348 return 0;
349 }
350
351 /*
352 * New label allocation
353 */
354 if (!CHECK_FLAG(vp->flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) {
355
356 /*
357 * not currently configured for auto label, reject allocation
358 */
359 return -1;
360 }
361
362 if (vp->tovpn_label != MPLS_LABEL_NONE) {
363 if (label == vp->tovpn_label) {
364 /* already have same label, accept but do nothing */
365 return 0;
366 }
367 /* Shouldn't happen: different label allocation */
e50f7cfd 368 flog_err(EC_BGP_LABEL,
1c50c1c0
QY
369 "%s: %s had label %u but got new assignment %u",
370 __func__, vp->bgp->name_pretty, vp->tovpn_label,
371 label);
e70e9f8e
PZ
372 /* use new one */
373 }
374
375 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
376 vp->afi, bgp_get_default(), vp->bgp);
377 vp->tovpn_label = label;
378 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
379 vp->afi, bgp_get_default(), vp->bgp);
380
381 return 0;
382}
383
ddb5b488
PZ
384static int ecom_intersect(struct ecommunity *e1, struct ecommunity *e2)
385{
386 int i;
387 int j;
388
389 if (!e1 || !e2)
390 return 0;
391
392 for (i = 0; i < e1->size; ++i) {
393 for (j = 0; j < e2->size; ++j) {
394 if (!memcmp(e1->val + (i * ECOMMUNITY_SIZE),
395 e2->val + (j * ECOMMUNITY_SIZE),
396 ECOMMUNITY_SIZE)) {
397
398 return 1;
399 }
400 }
401 }
402 return 0;
403}
404
e37fb4bf
PZ
405static bool labels_same(struct bgp_info *bi, mpls_label_t *label, uint32_t n)
406{
407 uint32_t i;
408
409 if (!bi->extra) {
410 if (!n)
411 return true;
412 else
413 return false;
414 }
415
416 if (n != bi->extra->num_labels)
417 return false;
418
419 for (i = 0; i < n; ++i) {
420 if (label[i] != bi->extra->label[i])
421 return false;
422 }
423 return true;
424}
425
426/*
427 * make encoded route labels match specified encoded label set
428 */
429static void setlabels(
430 struct bgp_info *bi,
431 mpls_label_t *label, /* array of labels */
432 uint32_t num_labels)
433{
434 if (num_labels)
435 assert(label);
436 assert(num_labels <= BGP_MAX_LABELS);
437
438 if (!num_labels) {
439 if (bi->extra)
440 bi->extra->num_labels = 0;
441 return;
442 }
443
444 struct bgp_info_extra *extra = bgp_info_extra_get(bi);
445 uint32_t i;
446
447 for (i = 0; i < num_labels; ++i) {
448 extra->label[i] = label[i];
449 if (!bgp_is_valid_label(&label[i])) {
450 bgp_set_valid_label(&extra->label[i]);
451 }
452 }
453 extra->num_labels = num_labels;
454}
455
ddb5b488
PZ
456/*
457 * returns pointer to new bgp_info upon success
458 */
459static struct bgp_info *
960035b2
PZ
460leak_update(
461 struct bgp *bgp, /* destination bgp instance */
462 struct bgp_node *bn,
463 struct attr *new_attr, /* already interned */
464 afi_t afi,
465 safi_t safi,
466 struct bgp_info *source_bi,
467 mpls_label_t *label,
e37fb4bf 468 uint32_t num_labels,
960035b2
PZ
469 void *parent,
470 struct bgp *bgp_orig,
471 struct prefix *nexthop_orig,
472 int nexthop_self_flag,
473 int debug)
ddb5b488
PZ
474{
475 struct prefix *p = &bn->p;
476 struct bgp_info *bi;
f46d45c1 477 struct bgp_info *bi_ultimate;
ddb5b488
PZ
478 struct bgp_info *new;
479 char buf_prefix[PREFIX_STRLEN];
ddb5b488
PZ
480
481 if (debug) {
482 prefix2str(&bn->p, buf_prefix, sizeof(buf_prefix));
960035b2
PZ
483 zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
484 __func__, bgp->name_pretty, buf_prefix,
485 source_bi->type, source_bi->sub_type);
ddb5b488
PZ
486 }
487
f46d45c1
PZ
488 /*
489 * Routes that are redistributed into BGP from zebra do not get
490 * nexthop tracking. However, if those routes are subsequently
491 * imported to other RIBs within BGP, the leaked routes do not
492 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
493 * in order to determine if the route we are currently leaking
494 * should have nexthop tracking, we must find the ultimate
495 * parent so we can check its sub_type.
496 *
497 * As of now, source_bi may at most be a second-generation route
498 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
499 * Using a loop here supports more complex intra-bgp import-export
500 * schemes that could be implemented in the future.
3bd70bf8 501 *
f46d45c1
PZ
502 */
503 for (bi_ultimate = source_bi;
504 bi_ultimate->extra && bi_ultimate->extra->parent;
505 bi_ultimate = bi_ultimate->extra->parent)
506 ;
507
ddb5b488
PZ
508 /*
509 * match parent
510 */
511 for (bi = bn->info; bi; bi = bi->next) {
512 if (bi->extra && bi->extra->parent == parent)
513 break;
514 }
515
516 if (bi) {
e37fb4bf
PZ
517 bool labelssame = labels_same(bi, label, num_labels);
518
ddb5b488 519 if (attrhash_cmp(bi->attr, new_attr)
e37fb4bf 520 && labelssame
ddb5b488
PZ
521 && !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
522
523 bgp_attr_unintern(&new_attr);
524 if (debug)
525 zlog_debug(
526 "%s: ->%s: %s: Found route, no change",
960035b2 527 __func__, bgp->name_pretty,
ddb5b488
PZ
528 buf_prefix);
529 return NULL;
530 }
531
532 /* attr is changed */
533 bgp_info_set_flag(bn, bi, BGP_INFO_ATTR_CHANGED);
534
535 /* Rewrite BGP route information. */
536 if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
537 bgp_info_restore(bn, bi);
538 else
539 bgp_aggregate_decrement(bgp, p, bi, afi, safi);
540 bgp_attr_unintern(&bi->attr);
541 bi->attr = new_attr;
542 bi->uptime = bgp_clock();
543
e37fb4bf
PZ
544 /*
545 * rewrite labels
546 */
547 if (!labelssame)
548 setlabels(bi, label, num_labels);
549
960035b2
PZ
550 if (nexthop_self_flag)
551 bgp_info_set_flag(bn, bi, BGP_INFO_ANNC_NH_SELF);
552
553 struct bgp *bgp_nexthop = bgp;
554 int nh_valid;
555
556 if (bi->extra && bi->extra->bgp_orig)
557 bgp_nexthop = bi->extra->bgp_orig;
558
559 /* No nexthop tracking for redistributed routes */
f46d45c1 560 if (bi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
960035b2
PZ
561 nh_valid = 1;
562 else
563 /*
564 * TBD do we need to do anything about the
565 * 'connected' parameter?
566 */
567 nh_valid = bgp_find_or_add_nexthop(
568 bgp, bgp_nexthop,
569 afi, bi, NULL, 0);
570
571 if (debug)
572 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
573 __func__, (nh_valid ? "" : "not "),
574 bgp_nexthop->name_pretty);
575
576 if (nh_valid)
577 bgp_info_set_flag(bn, bi, BGP_INFO_VALID);
578
ddb5b488
PZ
579 /* Process change. */
580 bgp_aggregate_increment(bgp, p, bi, afi, safi);
581 bgp_process(bgp, bn, afi, safi);
582 bgp_unlock_node(bn);
583
584 if (debug)
585 zlog_debug("%s: ->%s: %s Found route, changed attr",
960035b2 586 __func__, bgp->name_pretty, buf_prefix);
ddb5b488 587
e504cf3b 588 return bi;
ddb5b488
PZ
589 }
590
960035b2
PZ
591 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
592 bgp->peer_self, new_attr, bn);
593
594 if (nexthop_self_flag)
595 bgp_info_set_flag(bn, new, BGP_INFO_ANNC_NH_SELF);
ddb5b488 596
4b85140f
DS
597 bgp_info_extra_get(new);
598
e37fb4bf
PZ
599 if (num_labels)
600 setlabels(new, label, num_labels);
601
528cd74f 602 new->extra->parent = bgp_info_lock(parent);
7c82b312 603 bgp_lock_node((struct bgp_node *)((struct bgp_info *)parent)->net);
ddb5b488 604 if (bgp_orig)
21d88ef7 605 new->extra->bgp_orig = bgp_lock(bgp_orig);
ddb5b488
PZ
606 if (nexthop_orig)
607 new->extra->nexthop_orig = *nexthop_orig;
608
960035b2
PZ
609 /*
610 * nexthop tracking for unicast routes
611 */
612 struct bgp *bgp_nexthop = bgp;
613 int nh_valid;
614
4b85140f 615 if (new->extra->bgp_orig)
960035b2
PZ
616 bgp_nexthop = new->extra->bgp_orig;
617
618 /*
619 * No nexthop tracking for redistributed routes because
620 * their originating protocols will do the tracking and
621 * withdraw those routes if the nexthops become unreachable
622 */
f46d45c1 623 if (bi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
960035b2
PZ
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_info_set_flag(bn, new, BGP_INFO_VALID);
639
ddb5b488
PZ
640 bgp_aggregate_increment(bgp, p, new, afi, safi);
641 bgp_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__,
960035b2 648 bgp->name_pretty, buf_prefix);
ddb5b488
PZ
649
650 return new;
651}
652
653/* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
654void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
655 struct bgp *bgp_vrf, /* from */
656 struct bgp_info *info_vrf) /* route */
657{
658 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
659 struct prefix *p = &info_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;
960035b2
PZ
668 int nexthop_self_flag = 0;
669
670 if (debug)
671 zlog_debug("%s: from vrf %s", __func__, bgp_vrf->name_pretty);
ddb5b488 672
c8f57349
DS
673 if (debug && info_vrf->attr->ecommunity) {
674 char *s = ecommunity_ecom2str(info_vrf->attr->ecommunity,
675 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 676
12a844a5
DS
677 zlog_debug("%s: %s info_vrf->type=%d, EC{%s}", __func__,
678 bgp_vrf->name, info_vrf->type, s);
c8f57349 679 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
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
cc5a6ddd 691 /* loop check - should not be an imported route. */
692 if (info_vrf->extra && info_vrf->extra->bgp_orig)
ddb5b488
PZ
693 return;
694
695
696 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
697 if (debug)
12a844a5
DS
698 zlog_debug("%s: %s skipping: %s", __func__,
699 bgp_vrf->name, debugmsg);
ddb5b488
PZ
700 return;
701 }
702
703 bgp_attr_dup(&static_attr, info_vrf->attr); /* shallow copy */
704
705 /*
706 * route map handling
707 */
708 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
709 struct bgp_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",
960035b2 723 __func__, bgp_vrf->name_pretty,
ddb5b488
PZ
724 bgp_vrf->vpn_policy[afi]
725 .rmap[BGP_VPN_POLICY_DIR_TOVPN]
726 ->name);
727 return;
728 }
729 }
730
c8f57349
DS
731 if (debug && static_attr.ecommunity) {
732 char *s = ecommunity_ecom2str(static_attr.ecommunity,
733 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 734
ddb5b488
PZ
735 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
736 __func__, s);
c8f57349 737 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
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
c8f57349
DS
762 if (debug && static_attr.ecommunity) {
763 char *s = ecommunity_ecom2str(static_attr.ecommunity,
764 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 765
ddb5b488
PZ
766 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
767 __func__, s);
c8f57349 768 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
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)) {
ddb5b488
PZ
775 struct prefix *nexthop =
776 &bgp_vrf->vpn_policy[afi].tovpn_nexthop;
12a844a5 777
ddb5b488
PZ
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 = 4;
786 break;
787
788 case AF_INET6:
789 static_attr.mp_nexthop_global = nexthop->u.prefix6;
790 static_attr.mp_nexthop_len = 16;
791 break;
792
793 default:
794 assert(0);
795 }
796 } else {
12a844a5
DS
797 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
798 BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
799 if (afi == AFI_IP) {
020a3f60
DS
800 /*
801 * For ipv4, copy to multiprotocol
802 * nexthop field
803 */
804 static_attr.mp_nexthop_global_in =
805 static_attr.nexthop;
12a844a5 806 static_attr.mp_nexthop_len = 4;
020a3f60
DS
807 /*
808 * XXX Leave static_attr.nexthop
809 * intact for NHT
810 */
811 static_attr.flag &=
812 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
12a844a5
DS
813 }
814 } else {
77e62f2b 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(info_vrf->attr)) {
12a844a5
DS
823 static_attr.mp_nexthop_global_in.s_addr =
824 static_attr.nexthop.s_addr;
825 static_attr.mp_nexthop_len = 4;
826 static_attr.flag |=
827 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
12a844a5 828 }
ddb5b488 829 }
960035b2 830 nexthop_self_flag = 1;
ddb5b488
PZ
831 }
832
833 label_val = bgp_vrf->vpn_policy[afi].tovpn_label;
834 if (label_val == MPLS_LABEL_NONE) {
291e32c3 835 encode_label(MPLS_LABEL_IMPLICIT_NULL, &label);
ddb5b488
PZ
836 } else {
837 encode_label(label_val, &label);
838 }
839
840 /* Set originator ID to "me" */
841 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID));
842 static_attr.originator_id = bgp_vpn->router_id;
843
844
845 new_attr = bgp_attr_intern(
846 &static_attr); /* hashed refcounted everything */
847 bgp_attr_flush(&static_attr); /* free locally-allocated parts */
848
c3e345b1
DS
849 if (debug && new_attr->ecommunity) {
850 char *s = ecommunity_ecom2str(new_attr->ecommunity,
851 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 852
ddb5b488 853 zlog_debug("%s: new_attr->ecommunity{%s}", __func__, s);
c3e345b1 854 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
855 }
856
857 /* Now new_attr is an allocated interned attr */
858
859 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
860 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
861
862 struct bgp_info *new_info;
863
864 new_info = leak_update(bgp_vpn, bn, new_attr, afi, safi, info_vrf,
960035b2
PZ
865 &label, 1, info_vrf, bgp_vrf, NULL,
866 nexthop_self_flag, debug);
ddb5b488
PZ
867
868 /*
869 * Routes actually installed in the vpn RIB must also be
870 * offered to all vrfs (because now they originate from
871 * the vpn RIB).
872 *
873 * Acceptance into other vrfs depends on rt-lists.
874 * Originating vrf will not accept the looped back route
875 * because of loop checking.
876 */
877 if (new_info)
321b4bc9 878 vpn_leak_to_vrf_update(bgp_vrf, new_info);
ddb5b488
PZ
879}
880
881void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
882 struct bgp *bgp_vrf, /* from */
883 struct bgp_info *info_vrf) /* route */
884{
885 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
886 struct prefix *p = &info_vrf->net->p;
887 afi_t afi = family2afi(p->family);
888 safi_t safi = SAFI_MPLS_VPN;
889 struct bgp_info *bi;
890 struct bgp_node *bn;
891 const char *debugmsg;
960035b2
PZ
892 char buf_prefix[PREFIX_STRLEN];
893
894 if (debug) {
895 prefix2str(p, buf_prefix, sizeof(buf_prefix));
896 zlog_debug(
897 "%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
898 __func__, bgp_vrf->name_pretty, buf_prefix,
899 info_vrf->type, info_vrf->sub_type);
900 }
ddb5b488 901
ddb5b488 902 if (info_vrf->sub_type != BGP_ROUTE_NORMAL
82e7e75d 903 && info_vrf->sub_type != BGP_ROUTE_STATIC
904 && info_vrf->sub_type != BGP_ROUTE_REDISTRIBUTE) {
ddb5b488
PZ
905
906 if (debug)
907 zlog_debug("%s: wrong sub_type %d", __func__,
908 info_vrf->sub_type);
909 return;
910 }
911 if (!bgp_vpn)
912 return;
913
914 if (!afi) {
915 if (debug)
916 zlog_debug("%s: can't get afi of prefix", __func__);
917 return;
918 }
919
920 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
921 if (debug)
922 zlog_debug("%s: skipping: %s", __func__, debugmsg);
923 return;
924 }
925
926 if (debug)
927 zlog_debug("%s: withdrawing (info_vrf=%p)", __func__, info_vrf);
928
929 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
930 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
931
932 /*
933 * vrf -> vpn
934 * match original bi imported from
935 */
936 for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
937 if (bi->extra && bi->extra->parent == info_vrf) {
938 break;
939 }
940 }
941
942 if (bi) {
943 /* withdraw from looped vrfs as well */
944 vpn_leak_to_vrf_withdraw(bgp_vpn, bi);
945
946 bgp_aggregate_decrement(bgp_vpn, p, bi, afi, safi);
947 bgp_info_delete(bn, bi);
948 bgp_process(bgp_vpn, bn, afi, safi);
949 }
950 bgp_unlock_node(bn);
951}
952
953void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
954 struct bgp *bgp_vrf, /* from */
955 afi_t afi)
956{
957 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
958 struct bgp_node *prn;
959 safi_t safi = SAFI_MPLS_VPN;
960
961 /*
ddb5b488
PZ
962 * Walk vpn table, delete bi with bgp_orig == bgp_vrf
963 */
964 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
965 prn = bgp_route_next(prn)) {
966
967 struct bgp_table *table;
968 struct bgp_node *bn;
969 struct bgp_info *bi;
970
971 /* This is the per-RD table of prefixes */
972 table = prn->info;
973
974 if (!table)
975 continue;
976
977 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
978
979 char buf[PREFIX2STR_BUFFER];
980
981 if (debug && bn->info) {
982 zlog_debug(
983 "%s: looking at prefix %s", __func__,
984 prefix2str(&bn->p, buf, sizeof(buf)));
985 }
986
987 for (bi = bn->info; bi; bi = bi->next) {
988 if (debug)
989 zlog_debug("%s: type %d, sub_type %d",
990 __func__, bi->type,
991 bi->sub_type);
992 if (bi->sub_type != BGP_ROUTE_IMPORTED)
993 continue;
994 if (!bi->extra)
995 continue;
996 if ((struct bgp *)bi->extra->bgp_orig
997 == bgp_vrf) {
998 /* delete route */
999 if (debug)
1000 zlog_debug("%s: deleting it\n",
1001 __func__);
1002 bgp_aggregate_decrement(bgp_vpn, &bn->p,
1003 bi, afi, safi);
1004 bgp_info_delete(bn, bi);
1005 bgp_process(bgp_vpn, bn, afi, safi);
1006 }
1007 }
1008 }
1009 }
1010}
1011
1012void 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_info *bi;
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,
960035b2 1022 bgp_vrf->name_pretty);
ddb5b488
PZ
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 (bi = bn->info; bi; bi = bi->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, bi);
1036 }
1037 }
1038}
1039
1040static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
1041 struct bgp *bgp_vpn, /* from */
1042 struct bgp_info *info_vpn) /* route */
1043{
1044 struct prefix *p = &info_vpn->net->p;
1045 afi_t afi = family2afi(p->family);
1046
ddb5b488
PZ
1047 struct attr static_attr = {0};
1048 struct attr *new_attr = NULL;
1049 struct bgp_node *bn;
1050 safi_t safi = SAFI_UNICAST;
1051 const char *debugmsg;
1052 struct prefix nexthop_orig;
1053 mpls_label_t *pLabels = NULL;
e37fb4bf 1054 uint32_t num_labels = 0;
960035b2 1055 int nexthop_self_flag = 1;
513bf8d6
PZ
1056 struct bgp_info *bi_ultimate = NULL;
1057 int origin_local = 0;
d6632478 1058 struct bgp *src_vrf;
ddb5b488
PZ
1059
1060 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1061
b9c7bc5a 1062 if (!vpn_leak_from_vpn_active(bgp_vrf, afi, &debugmsg)) {
ddb5b488
PZ
1063 if (debug)
1064 zlog_debug("%s: skipping: %s", __func__, debugmsg);
1065 return;
1066 }
1067
1068 /* Check for intersection of route targets */
1069 if (!ecom_intersect(
1070 bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1071 info_vpn->attr->ecommunity)) {
1072
1073 return;
1074 }
1075
1076 if (debug)
960035b2
PZ
1077 zlog_debug("%s: updating to vrf %s", __func__,
1078 bgp_vrf->name_pretty);
ddb5b488
PZ
1079
1080 bgp_attr_dup(&static_attr, info_vpn->attr); /* shallow copy */
1081
1082 /*
1083 * Nexthop: stash and clear
1084 *
1085 * Nexthop is valid in context of VPN core, but not in destination vrf.
1086 * Stash it for later label resolution by vrf ingress path and then
1087 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1088 */
1089 uint8_t nhfamily = NEXTHOP_FAMILY(info_vpn->attr->mp_nexthop_len);
1090
1091 memset(&nexthop_orig, 0, sizeof(nexthop_orig));
1092 nexthop_orig.family = nhfamily;
1093
1094 switch (nhfamily) {
ddb5b488
PZ
1095 case AF_INET:
1096 /* save */
1097 nexthop_orig.u.prefix4 = info_vpn->attr->mp_nexthop_global_in;
1098 nexthop_orig.prefixlen = 32;
12a844a5
DS
1099
1100 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1101 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1102 static_attr.nexthop.s_addr =
1103 nexthop_orig.u.prefix4.s_addr;
1104
1105 static_attr.mp_nexthop_global_in =
1106 info_vpn->attr->mp_nexthop_global_in;
1107 static_attr.mp_nexthop_len =
1108 info_vpn->attr->mp_nexthop_len;
1109 }
ddb5b488 1110 static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
ddb5b488 1111 break;
ddb5b488
PZ
1112 case AF_INET6:
1113 /* save */
1114 nexthop_orig.u.prefix6 = info_vpn->attr->mp_nexthop_global;
1115 nexthop_orig.prefixlen = 128;
12a844a5
DS
1116
1117 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1118 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1119 static_attr.mp_nexthop_global = nexthop_orig.u.prefix6;
12a844a5 1120 }
ddb5b488
PZ
1121 break;
1122 }
1123
ddb5b488
PZ
1124 /*
1125 * route map handling
ddb5b488 1126 */
ddb5b488
PZ
1127 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
1128 struct bgp_info info;
1129 route_map_result_t ret;
1130
1131 memset(&info, 0, sizeof(info));
1132 info.peer = bgp_vrf->peer_self;
1133 info.attr = &static_attr;
1134 ret = route_map_apply(bgp_vrf->vpn_policy[afi]
1135 .rmap[BGP_VPN_POLICY_DIR_FROMVPN],
1136 p, RMAP_BGP, &info);
1137 if (RMAP_DENYMATCH == ret) {
1138 bgp_attr_flush(&static_attr); /* free any added parts */
1139 if (debug)
1140 zlog_debug(
1141 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
960035b2 1142 __func__, bgp_vrf->name_pretty,
ddb5b488
PZ
1143 bgp_vrf->vpn_policy[afi]
1144 .rmap[BGP_VPN_POLICY_DIR_FROMVPN]
1145 ->name);
1146 return;
1147 }
960035b2
PZ
1148 /*
1149 * if route-map changed nexthop, don't nexthop-self on output
1150 */
1151 if (!CHECK_FLAG(static_attr.rmap_change_flags,
1152 BATTR_RMAP_NEXTHOP_UNCHANGED))
1153 nexthop_self_flag = 0;
ddb5b488
PZ
1154 }
1155
1156 new_attr = bgp_attr_intern(&static_attr);
1157 bgp_attr_flush(&static_attr);
1158
1159 bn = bgp_afi_node_get(bgp_vrf->rib[afi][safi], afi, safi, p, NULL);
1160
1161 /*
1162 * ensure labels are copied
513bf8d6
PZ
1163 *
1164 * However, there is a special case: if the route originated in
1165 * another local VRF (as opposed to arriving via VPN), then the
1166 * nexthop is reached by hairpinning through this router (me)
1167 * using IP forwarding only (no LSP). Therefore, the route
1168 * imported to the VRF should not have labels attached. Note
1169 * that nexthop tracking is also involved: eliminating the
1170 * labels for these routes enables the non-labeled nexthops
1171 * from the originating VRF to be considered valid for this route.
ddb5b488 1172 */
12a844a5
DS
1173 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1174 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1175 /* work back to original route */
1176 for (bi_ultimate = info_vpn;
1177 bi_ultimate->extra && bi_ultimate->extra->parent;
1178 bi_ultimate = bi_ultimate->extra->parent)
1179 ;
513bf8d6 1180
12a844a5
DS
1181 /*
1182 * if original route was unicast,
1183 * then it did not arrive over vpn
1184 */
1185 if (bi_ultimate->net) {
1186 struct bgp_table *table;
513bf8d6 1187
12a844a5
DS
1188 table = bgp_node_table(bi_ultimate->net);
1189 if (table && (table->safi == SAFI_UNICAST))
1190 origin_local = 1;
1191 }
513bf8d6 1192
12a844a5
DS
1193 /* copy labels */
1194 if (!origin_local &&
1195 info_vpn->extra && info_vpn->extra->num_labels) {
1196 num_labels = info_vpn->extra->num_labels;
1197 if (num_labels > BGP_MAX_LABELS)
1198 num_labels = BGP_MAX_LABELS;
1199 pLabels = info_vpn->extra->label;
1200 }
ddb5b488 1201 }
513bf8d6 1202
ddb5b488
PZ
1203 if (debug) {
1204 char buf_prefix[PREFIX_STRLEN];
1205 prefix2str(p, buf_prefix, sizeof(buf_prefix));
1206 zlog_debug("%s: pfx %s: num_labels %d", __func__, buf_prefix,
1207 num_labels);
1208 }
1209
44338987 1210 /*
1d4e8b0d
DS
1211 * For VRF-2-VRF route-leaking,
1212 * the source will be the originating VRF.
44338987 1213 */
d6632478
PZ
1214 if (info_vpn->extra && info_vpn->extra->bgp_orig)
1215 src_vrf = info_vpn->extra->bgp_orig;
1216 else
1217 src_vrf = bgp_vpn;
1218
960035b2
PZ
1219 leak_update(bgp_vrf, bn, new_attr, afi, safi, info_vpn,
1220 pLabels, num_labels,
1221 info_vpn, /* parent */
d6632478 1222 src_vrf, &nexthop_orig, nexthop_self_flag, debug);
ddb5b488
PZ
1223}
1224
1225void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
1226 struct bgp_info *info_vpn) /* route */
1227{
1228 struct listnode *mnode, *mnnode;
1229 struct bgp *bgp;
1230
1231 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1232
1233 if (debug)
1234 zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
1235
1236 /* Loop over VRFs */
1237 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
1238
1239 if (!info_vpn->extra
1240 || info_vpn->extra->bgp_orig != bgp) { /* no loop */
1241 vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, info_vpn);
1242 }
1243 }
1244}
1245
1246void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
1247 struct bgp_info *info_vpn) /* route */
1248{
1b3510a0
PZ
1249 struct prefix *p;
1250 afi_t afi;
ddb5b488
PZ
1251 safi_t safi = SAFI_UNICAST;
1252 struct bgp *bgp;
1253 struct listnode *mnode, *mnnode;
ddb5b488
PZ
1254 struct bgp_node *bn;
1255 struct bgp_info *bi;
1256 const char *debugmsg;
960035b2 1257 char buf_prefix[PREFIX_STRLEN];
ddb5b488
PZ
1258
1259 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1260
960035b2
PZ
1261 if (debug) {
1262 prefix2str(&info_vpn->net->p, buf_prefix, sizeof(buf_prefix));
1263 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d",
1264 __func__, buf_prefix,
1265 info_vpn->type, info_vpn->sub_type);
1266 }
1267
ddb5b488
PZ
1268 if (debug)
1269 zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
1270
1b3510a0 1271 if (!info_vpn->net) {
56c2c080 1272#if ENABLE_BGP_VNC
1b3510a0
PZ
1273 /* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
1274 if (info_vpn->type == ZEBRA_ROUTE_BGP &&
1275 info_vpn->sub_type == BGP_ROUTE_RFP) {
1276
1277 return;
1278 }
56c2c080 1279#endif
1b3510a0
PZ
1280 if (debug)
1281 zlog_debug("%s: info_vpn->net unexpectedly NULL, no prefix, bailing",
1282 __func__);
1283 return;
1284 }
1285
1286 p = &info_vpn->net->p;
1287 afi = family2afi(p->family);
ddb5b488
PZ
1288
1289 /* Loop over VRFs */
1290 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
b9c7bc5a 1291 if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
ddb5b488
PZ
1292 if (debug)
1293 zlog_debug("%s: skipping: %s", __func__,
1294 debugmsg);
1295 continue;
1296 }
1297
1298 /* Check for intersection of route targets */
1299 if (!ecom_intersect(bgp->vpn_policy[afi]
1300 .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1301 info_vpn->attr->ecommunity)) {
1302
1303 continue;
1304 }
1305
1306 if (debug)
1307 zlog_debug("%s: withdrawing from vrf %s", __func__,
960035b2 1308 bgp->name_pretty);
ddb5b488
PZ
1309
1310 bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
1311 for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
1312 if (bi->extra
1313 && (struct bgp_info *)bi->extra->parent
1314 == info_vpn) {
1315 break;
1316 }
1317 }
1318
1319 if (bi) {
1320 if (debug)
1321 zlog_debug("%s: deleting bi %p", __func__, bi);
1322 bgp_aggregate_decrement(bgp, p, bi, afi, safi);
1323 bgp_info_delete(bn, bi);
1324 bgp_process(bgp, bn, afi, safi);
1325 }
1326 bgp_unlock_node(bn);
1327 }
1328}
1329
1330void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
1331 afi_t afi)
1332{
1333 struct bgp_node *bn;
1334 struct bgp_info *bi;
1335 safi_t safi = SAFI_UNICAST;
1336 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
ddb5b488
PZ
1337
1338 if (debug)
1339 zlog_debug("%s: entry", __func__);
1340 /*
d793761d 1341 * Walk vrf table, delete bi with bgp_orig in a different vrf
ddb5b488
PZ
1342 */
1343 for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
1344 bn = bgp_route_next(bn)) {
1345
1346 for (bi = bn->info; bi; bi = bi->next) {
d793761d 1347 if (bi->extra && bi->extra->bgp_orig != bgp_vrf) {
ddb5b488
PZ
1348
1349 /* delete route */
1350 bgp_aggregate_decrement(bgp_vrf, &bn->p, bi,
1351 afi, safi);
1352 bgp_info_delete(bn, bi);
1353 bgp_process(bgp_vrf, bn, afi, safi);
1354 }
1355 }
1356 }
1357}
1358
1359void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
1360 struct bgp *bgp_vpn, /* from */
1361 afi_t afi)
1362{
1363 struct prefix_rd prd;
1364 struct bgp_node *prn;
1365 safi_t safi = SAFI_MPLS_VPN;
1366
3bd70bf8 1367 assert(bgp_vpn);
73aed584 1368
ddb5b488
PZ
1369 /*
1370 * Walk vpn table
1371 */
1372 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
1373 prn = bgp_route_next(prn)) {
1374
1375 struct bgp_table *table;
1376 struct bgp_node *bn;
1377 struct bgp_info *bi;
1378
1379 memset(&prd, 0, sizeof(prd));
1380 prd.family = AF_UNSPEC;
1381 prd.prefixlen = 64;
1382 memcpy(prd.val, prn->p.u.val, 8);
1383
1384 /* This is the per-RD table of prefixes */
1385 table = prn->info;
1386
1387 if (!table)
1388 continue;
1389
1390 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
1391
1392 for (bi = bn->info; bi; bi = bi->next) {
1393
1394 if (bi->extra && bi->extra->bgp_orig == bgp_vrf)
1395 continue;
1396
1397 vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
1398 bi);
1399 }
1400 }
1401 }
1402}
1403
d92a55df
PZ
1404/*
1405 * This function is called for definition/deletion/change to a route-map
1406 */
ddb5b488
PZ
1407static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
1408{
1409 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1410 afi_t afi;
1411 struct route_map *rmap;
1412
1413 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1414 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
1415
1416 return;
1417 }
1418
1419 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
1420
1421 for (afi = 0; afi < AFI_MAX; ++afi) {
1422
d92a55df
PZ
1423 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
1424 && !strcmp(rmap_name,
ddb5b488
PZ
1425 bgp->vpn_policy[afi]
1426 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
1427
1428 if (debug)
1429 zlog_debug(
1430 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1431 __func__, rmap_name, bgp->as,
1432 afi2str(afi));
1433
1434 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1435 bgp_get_default(), bgp);
1436 if (debug)
1437 zlog_debug("%s: after vpn_leak_prechange",
1438 __func__);
1439
d92a55df
PZ
1440 /* in case of definition/deletion */
1441 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN] =
1442 rmap;
ddb5b488
PZ
1443
1444 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1445 bgp_get_default(), bgp);
d92a55df 1446
ddb5b488
PZ
1447 if (debug)
1448 zlog_debug("%s: after vpn_leak_postchange",
1449 __func__);
1450 }
1451
d92a55df
PZ
1452 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]
1453 && !strcmp(rmap_name,
1454 bgp->vpn_policy[afi]
1455 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN])) {
b9c7bc5a
PZ
1456
1457 if (debug) {
1458 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
ddb5b488
PZ
1459 __func__, rmap_name, bgp->as,
1460 afi2str(afi));
b9c7bc5a 1461 }
ddb5b488
PZ
1462
1463 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1464 bgp_get_default(), bgp);
1465
d92a55df
PZ
1466 /* in case of definition/deletion */
1467 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
1468 rmap;
ddb5b488
PZ
1469
1470 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1471 bgp_get_default(), bgp);
1472 }
1473 }
1474}
1475
1476void vpn_policy_routemap_event(const char *rmap_name)
1477{
1478 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1479 struct listnode *mnode, *mnnode;
1480 struct bgp *bgp;
1481
1482 if (debug)
1483 zlog_debug("%s: entry", __func__);
1484
1485 if (bm->bgp == NULL) /* may be called during cleanup */
1486 return;
1487
1488 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
1489 vpn_policy_routemap_update(bgp, rmap_name);
1490}
1491
1d4e8b0d 1492void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 1493 afi_t afi, safi_t safi)
1494{
1495 const char *export_name;
1496 vpn_policy_direction_t idir, edir;
1497 char *vname;
1498 char buf[1000];
1499 struct ecommunity *ecom;
1500 bool first_export = false;
1501
a8dadcf6 1502 export_name = to_bgp->name ? to_bgp->name : BGP_DEFAULT_NAME;
44338987 1503 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1504 edir = BGP_VPN_POLICY_DIR_TOVPN;
1505
1d4e8b0d
DS
1506 /*
1507 * Cross-ref both VRFs. Also, note if this is the first time
44338987 1508 * any VRF is importing from "import_vrf".
1509 */
a8dadcf6
DS
1510 vname = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
1511 : XSTRDUP(MTYPE_TMP, BGP_DEFAULT_NAME));
1512
1d4e8b0d 1513 listnode_add(to_bgp->vpn_policy[afi].import_vrf, vname);
44338987 1514
1d4e8b0d 1515 if (!listcount(from_bgp->vpn_policy[afi].export_vrf))
44338987 1516 first_export = true;
1517 vname = XSTRDUP(MTYPE_TMP, export_name);
1d4e8b0d 1518 listnode_add(from_bgp->vpn_policy[afi].export_vrf, vname);
44338987 1519
1520 /* Update import RT for current VRF using export RT of the VRF we're
1521 * importing from. First though, make sure "import_vrf" has that
1522 * set.
1523 */
1524 if (first_export) {
1d4e8b0d
DS
1525 form_auto_rd(from_bgp->router_id, from_bgp->vrf_rd_id,
1526 &from_bgp->vrf_prd_auto);
1527 from_bgp->vpn_policy[afi].tovpn_rd = from_bgp->vrf_prd_auto;
1528 SET_FLAG(from_bgp->vpn_policy[afi].flags,
44338987 1529 BGP_VPN_POLICY_TOVPN_RD_SET);
1d4e8b0d 1530 prefix_rd2str(&from_bgp->vpn_policy[afi].tovpn_rd,
44338987 1531 buf, sizeof(buf));
1d4e8b0d 1532 from_bgp->vpn_policy[afi].rtlist[edir] =
44338987 1533 ecommunity_str2com(buf, ECOMMUNITY_ROUTE_TARGET, 0);
1d4e8b0d 1534 SET_FLAG(from_bgp->af_flags[afi][safi],
44338987 1535 BGP_CONFIG_VRF_TO_VRF_EXPORT);
13b7e7f0
DS
1536 from_bgp->vpn_policy[afi].tovpn_label =
1537 BGP_PREVENT_VRF_2_VRF_LEAK;
44338987 1538 }
1d4e8b0d
DS
1539 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
1540 if (to_bgp->vpn_policy[afi].rtlist[idir])
1541 to_bgp->vpn_policy[afi].rtlist[idir] =
1542 ecommunity_merge(to_bgp->vpn_policy[afi]
44338987 1543 .rtlist[idir], ecom);
1544 else
1d4e8b0d
DS
1545 to_bgp->vpn_policy[afi].rtlist[idir] = ecommunity_dup(ecom);
1546 SET_FLAG(to_bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT);
44338987 1547
1548 /* Does "import_vrf" first need to export its routes or that
1549 * is already done and we just need to import those routes
1550 * from the global table?
1551 */
1552 if (first_export)
1d4e8b0d 1553 vpn_leak_postchange(edir, afi, bgp_get_default(), from_bgp);
44338987 1554 else
1d4e8b0d 1555 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
44338987 1556}
1557
1d4e8b0d 1558void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 1559 afi_t afi, safi_t safi)
1560{
a8dadcf6 1561 const char *export_name, *tmp_name;
44338987 1562 vpn_policy_direction_t idir, edir;
1563 char *vname;
1564 struct ecommunity *ecom;
1565 struct listnode *node;
1566
a8dadcf6
DS
1567 export_name = to_bgp->name ? to_bgp->name : BGP_DEFAULT_NAME;
1568 tmp_name = from_bgp->name ? from_bgp->name : BGP_DEFAULT_NAME;
44338987 1569 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1570 edir = BGP_VPN_POLICY_DIR_TOVPN;
1571
1572 /* Were we importing from "import_vrf"? */
1d4e8b0d
DS
1573 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf, node,
1574 vname)) {
a8dadcf6 1575 if (strcmp(vname, tmp_name) == 0)
020a3f60 1576 break;
44338987 1577 }
1d4e8b0d
DS
1578
1579 /*
1580 * We do not check in the cli if the passed in bgp
1581 * instance is actually imported into us before
1582 * we call this function. As such if we do not
1583 * find this in the import_vrf list than
1584 * we just need to return safely.
1585 */
44338987 1586 if (!vname)
1587 return;
1588
1589 /* Remove "import_vrf" from our import list. */
1d4e8b0d 1590 listnode_delete(to_bgp->vpn_policy[afi].import_vrf, vname);
44338987 1591 XFREE(MTYPE_TMP, vname);
1592
1593 /* Remove routes imported from "import_vrf". */
1594 /* TODO: In the current logic, we have to first remove all
1595 * imported routes and then (if needed) import back routes
1596 */
1d4e8b0d 1597 vpn_leak_prechange(idir, afi, bgp_get_default(), to_bgp);
44338987 1598
1d4e8b0d
DS
1599 if (to_bgp->vpn_policy[afi].import_vrf->count == 0) {
1600 UNSET_FLAG(to_bgp->af_flags[afi][safi],
44338987 1601 BGP_CONFIG_VRF_TO_VRF_IMPORT);
1d4e8b0d 1602 ecommunity_free(&to_bgp->vpn_policy[afi].rtlist[idir]);
44338987 1603 } else {
1d4e8b0d
DS
1604 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
1605 ecommunity_del_val(to_bgp->vpn_policy[afi].rtlist[idir],
44338987 1606 (struct ecommunity_val *)ecom->val);
1d4e8b0d 1607 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
44338987 1608 }
1609
89d59347
DS
1610 /*
1611 * What?
1612 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
1613 * below is checking for NULL that export_vrf can be
1614 * NULL, consequently it is complaining( like a cabbage )
1615 * that we could dereference and crash in the listcount(..)
1616 * check below.
1617 * So make it happy, under protest, with liberty and justice
1618 * for all.
1619 */
1d4e8b0d 1620 assert(from_bgp->vpn_policy[afi].export_vrf);
89d59347 1621
44338987 1622 /* Remove us from "import_vrf's" export list. If no other VRF
1623 * is importing from "import_vrf", cleanup appropriately.
1624 */
1d4e8b0d 1625 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
44338987 1626 node, vname)) {
1627 if (strcmp(vname, export_name) == 0)
1628 break;
1629 }
1630
1d4e8b0d
DS
1631 /*
1632 * If we have gotten to this point then the vname must
1633 * exist. If not, we are in a world of trouble and
1634 * have slag sitting around.
1635 *
1636 * import_vrf and export_vrf must match in having
1637 * the in/out names as appropriate.
1638 */
1639 assert(vname);
1640
1641 listnode_delete(from_bgp->vpn_policy[afi].export_vrf, vname);
44338987 1642 XFREE(MTYPE_TMP, vname);
1643
1d4e8b0d
DS
1644 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
1645 vpn_leak_prechange(edir, afi, bgp_get_default(), from_bgp);
1646 ecommunity_free(&from_bgp->vpn_policy[afi].rtlist[edir]);
1647 UNSET_FLAG(from_bgp->af_flags[afi][safi],
44338987 1648 BGP_CONFIG_VRF_TO_VRF_EXPORT);
1d4e8b0d 1649 memset(&from_bgp->vpn_policy[afi].tovpn_rd, 0,
44338987 1650 sizeof(struct prefix_rd));
1d4e8b0d 1651 UNSET_FLAG(from_bgp->vpn_policy[afi].flags,
44338987 1652 BGP_VPN_POLICY_TOVPN_RD_SET);
13b7e7f0
DS
1653 from_bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE;
1654
44338987 1655 }
1656}
1657
718e3744 1658/* For testing purpose, static route of MPLS-VPN. */
1659DEFUN (vpnv4_network,
1660 vpnv4_network_cmd,
d114b977 1661 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1662 "Specify a network to announce via BGP\n"
0c7b1b01 1663 "IPv4 prefix\n"
718e3744 1664 "Specify Route Distinguisher\n"
1665 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1666 "VPN NLRI label (tag)\n"
1667 "VPN NLRI label (tag)\n"
1668 "Label value\n")
718e3744 1669{
d62a17ae 1670 int idx_ipv4_prefixlen = 1;
1671 int idx_ext_community = 3;
1672 int idx_label = 5;
1673 return bgp_static_set_safi(
1674 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1675 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
1676 NULL, NULL, NULL, NULL);
137446f9
LB
1677}
1678
1679DEFUN (vpnv4_network_route_map,
1680 vpnv4_network_route_map_cmd,
d114b977 1681 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
137446f9 1682 "Specify a network to announce via BGP\n"
0c7b1b01 1683 "IPv4 prefix\n"
137446f9
LB
1684 "Specify Route Distinguisher\n"
1685 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1686 "VPN NLRI label (tag)\n"
1687 "VPN NLRI label (tag)\n"
1688 "Label value\n"
137446f9
LB
1689 "route map\n"
1690 "route map name\n")
1691{
d62a17ae 1692 int idx_ipv4_prefixlen = 1;
1693 int idx_ext_community = 3;
1694 int idx_label = 5;
1695 int idx_word_2 = 7;
1696 return bgp_static_set_safi(
1697 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1698 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1699 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
718e3744 1700}
1701
1702/* For testing purpose, static route of MPLS-VPN. */
1703DEFUN (no_vpnv4_network,
1704 no_vpnv4_network_cmd,
d114b977 1705 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1706 NO_STR
1707 "Specify a network to announce via BGP\n"
0c7b1b01 1708 "IPv4 prefix\n"
718e3744 1709 "Specify Route Distinguisher\n"
1710 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1711 "VPN NLRI label (tag)\n"
1712 "VPN NLRI label (tag)\n"
1713 "Label value\n")
718e3744 1714{
d62a17ae 1715 int idx_ipv4_prefixlen = 2;
1716 int idx_ext_community = 4;
1717 int idx_label = 6;
1718 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
1719 argv[idx_ipv4_prefixlen]->arg,
1720 argv[idx_ext_community]->arg,
1721 argv[idx_label]->arg, 0, NULL, NULL, NULL);
718e3744 1722}
1723
c286be96
LX
1724DEFUN (vpnv6_network,
1725 vpnv6_network_cmd,
d114b977 1726 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
c286be96
LX
1727 "Specify a network to announce via BGP\n"
1728 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1729 "Specify Route Distinguisher\n"
1730 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1731 "VPN NLRI label (tag)\n"
1732 "VPN NLRI label (tag)\n"
1733 "Label value\n"
11daee81
DS
1734 "route map\n"
1735 "route map name\n")
c286be96 1736{
d62a17ae 1737 int idx_ipv6_prefix = 1;
1738 int idx_ext_community = 3;
1739 int idx_label = 5;
1740 int idx_word_2 = 7;
1741 if (argc == 8)
1742 return bgp_static_set_safi(
1743 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1744 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1745 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
1746 else
1747 return bgp_static_set_safi(
1748 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1749 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1750 NULL, 0, NULL, NULL, NULL, NULL);
c286be96
LX
1751}
1752
1753/* For testing purpose, static route of MPLS-VPN. */
1754DEFUN (no_vpnv6_network,
1755 no_vpnv6_network_cmd,
d114b977 1756 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
c286be96
LX
1757 NO_STR
1758 "Specify a network to announce via BGP\n"
1759 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1760 "Specify Route Distinguisher\n"
1761 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1762 "VPN NLRI label (tag)\n"
1763 "VPN NLRI label (tag)\n"
1764 "Label value\n")
c286be96 1765{
d62a17ae 1766 int idx_ipv6_prefix = 2;
1767 int idx_ext_community = 4;
1768 int idx_label = 6;
1769 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
1770 argv[idx_ipv6_prefix]->arg,
1771 argv[idx_ext_community]->arg,
1772 argv[idx_label]->arg, 0, NULL, NULL, NULL);
c286be96
LX
1773}
1774
d62a17ae 1775int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
1776 enum bgp_show_type type, void *output_arg, int tags,
9f049418 1777 bool use_json)
718e3744 1778{
d62a17ae 1779 struct bgp *bgp;
1780 struct bgp_table *table;
d62a17ae 1781
1782 bgp = bgp_get_default();
1783 if (bgp == NULL) {
1784 if (!use_json)
1785 vty_out(vty, "No BGP process is configured\n");
16307668
RW
1786 else
1787 vty_out(vty, "{}\n");
d62a17ae 1788 return CMD_WARNING;
1789 }
1ae44dfc 1790 table = bgp->rib[afi][SAFI_MPLS_VPN];
a4d82a8a
PZ
1791 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
1792 output_arg, use_json);
718e3744 1793}
1794
4f280b15
LB
1795DEFUN (show_bgp_ip_vpn_all_rd,
1796 show_bgp_ip_vpn_all_rd_cmd,
d114b977 1797 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
e3e29b32
LB
1798 SHOW_STR
1799 BGP_STR
05e588f4 1800 BGP_VPNVX_HELP_STR
e3e29b32 1801 "Display VPN NLRI specific information\n"
af8528fa 1802 "Display VPN NLRI specific information\n"
e3e29b32
LB
1803 "Display information for a route distinguisher\n"
1804 "VPN Route Distinguisher\n"
1805 JSON_STR)
1806{
d62a17ae 1807 int ret;
1808 struct prefix_rd prd;
1809 afi_t afi;
1810 int idx = 0;
1811
1812 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
3d7c4cd7 1813 if (argv_find(argv, argc, "rd", &idx)) {
a4d82a8a 1814 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
d62a17ae 1815 if (!ret) {
1816 vty_out(vty,
1817 "%% Malformed Route Distinguisher\n");
1818 return CMD_WARNING;
1819 }
1820 return bgp_show_mpls_vpn(vty, afi, &prd,
1821 bgp_show_type_normal, NULL, 0,
1822 use_json(argc, argv));
1823 } else {
1824 return bgp_show_mpls_vpn(vty, afi, NULL,
1825 bgp_show_type_normal, NULL, 0,
1826 use_json(argc, argv));
1827 }
1828 }
1829 return CMD_SUCCESS;
718e3744 1830}
1831
af8528fa
LB
1832ALIAS(show_bgp_ip_vpn_all_rd,
1833 show_bgp_ip_vpn_rd_cmd,
1834 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1835 SHOW_STR
1836 BGP_STR
1837 BGP_VPNVX_HELP_STR
1838 "Display VPN NLRI specific information\n"
1839 "Display information for a route distinguisher\n"
1840 "VPN Route Distinguisher\n"
1841 JSON_STR)
1842
1843#ifdef KEEP_OLD_VPN_COMMANDS
3f227172
PG
1844DEFUN (show_ip_bgp_vpn_rd,
1845 show_ip_bgp_vpn_rd_cmd,
af8528fa 1846 "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
718e3744 1847 SHOW_STR
1848 IP_STR
1849 BGP_STR
4f280b15 1850 BGP_AFI_HELP_STR
3517059b 1851 "Address Family modifier\n"
718e3744 1852 "Display information for a route distinguisher\n"
1853 "VPN Route Distinguisher\n")
1854{
d62a17ae 1855 int idx_ext_community = argc - 1;
1856 int ret;
1857 struct prefix_rd prd;
1858 afi_t afi;
1859 int idx = 0;
1860
1861 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1862 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1863 if (!ret) {
1864 vty_out(vty, "%% Malformed Route Distinguisher\n");
1865 return CMD_WARNING;
1866 }
1867 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1868 NULL, 0, 0);
1869 }
1870 return CMD_SUCCESS;
1871}
718e3744 1872
4f280b15
LB
1873DEFUN (show_ip_bgp_vpn_all,
1874 show_ip_bgp_vpn_all_cmd,
1875 "show [ip] bgp <vpnv4|vpnv6>",
1876 SHOW_STR
1877 IP_STR
1878 BGP_STR
1879 BGP_VPNVX_HELP_STR)
1880{
d62a17ae 1881 afi_t afi;
1882 int idx = 0;
4f280b15 1883
d62a17ae 1884 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1885 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1886 NULL, 0, 0);
1887 return CMD_SUCCESS;
4f280b15
LB
1888}
1889
3f227172
PG
1890DEFUN (show_ip_bgp_vpn_all_tags,
1891 show_ip_bgp_vpn_all_tags_cmd,
1892 "show [ip] bgp <vpnv4|vpnv6> all tags",
718e3744 1893 SHOW_STR
1894 IP_STR
1895 BGP_STR
3f227172
PG
1896 BGP_VPNVX_HELP_STR
1897 "Display information about all VPNv4/VPNV6 NLRIs\n"
718e3744 1898 "Display BGP tags for prefixes\n")
1899{
d62a17ae 1900 afi_t afi;
1901 int idx = 0;
3f227172 1902
d62a17ae 1903 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1904 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1905 NULL, 1, 0);
1906 return CMD_SUCCESS;
718e3744 1907}
1908
3f227172
PG
1909DEFUN (show_ip_bgp_vpn_rd_tags,
1910 show_ip_bgp_vpn_rd_tags_cmd,
d114b977 1911 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
718e3744 1912 SHOW_STR
1913 IP_STR
1914 BGP_STR
3f227172 1915 BGP_VPNVX_HELP_STR
718e3744 1916 "Display information for a route distinguisher\n"
1917 "VPN Route Distinguisher\n"
1918 "Display BGP tags for prefixes\n")
1919{
d62a17ae 1920 int idx_ext_community = 5;
1921 int ret;
1922 struct prefix_rd prd;
1923 afi_t afi;
1924 int idx = 0;
1925
1926 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1927 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1928 if (!ret) {
1929 vty_out(vty, "%% Malformed Route Distinguisher\n");
1930 return CMD_WARNING;
1931 }
1932 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1933 NULL, 1, 0);
1934 }
1935 return CMD_SUCCESS;
718e3744 1936}
1937
3f227172
PG
1938DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
1939 show_ip_bgp_vpn_all_neighbor_routes_cmd,
1940 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
718e3744 1941 SHOW_STR
1942 IP_STR
1943 BGP_STR
3f227172
PG
1944 BGP_VPNVX_HELP_STR
1945 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 1946 "Detailed information on TCP and BGP neighbor connections\n"
1947 "Neighbor to display information about\n"
856ca177 1948 "Display routes learned from neighbor\n"
9973d184 1949 JSON_STR)
718e3744 1950{
d62a17ae 1951 int idx_ipv4 = 6;
1952 union sockunion su;
1953 struct peer *peer;
1954 int ret;
9f049418 1955 bool uj = use_json(argc, argv);
d62a17ae 1956 afi_t afi;
1957 int idx = 0;
1958
1959 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1960 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1961 if (ret < 0) {
1962 if (uj) {
1963 json_object *json_no = NULL;
1964 json_no = json_object_new_object();
1965 json_object_string_add(json_no, "warning",
1966 "Malformed address");
1967 vty_out(vty, "%s\n",
1968 json_object_to_json_string(json_no));
1969 json_object_free(json_no);
1970 } else
1971 vty_out(vty, "Malformed address: %s\n",
1972 argv[idx_ipv4]->arg);
1973 return CMD_WARNING;
1974 }
1975
1976 peer = peer_lookup(NULL, &su);
1977 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1978 if (uj) {
1979 json_object *json_no = NULL;
1980 json_no = json_object_new_object();
1981 json_object_string_add(
1982 json_no, "warning",
1983 "No such neighbor or address family");
1984 vty_out(vty, "%s\n",
1985 json_object_to_json_string(json_no));
1986 json_object_free(json_no);
1987 } else
1988 vty_out(vty,
1989 "%% No such neighbor or address family\n");
1990 return CMD_WARNING;
1991 }
1992
1993 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
1994 &su, 0, uj);
1995 }
1996 return CMD_SUCCESS;
718e3744 1997}
1998
3f227172
PG
1999DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
2000 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
d114b977 2001 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
718e3744 2002 SHOW_STR
2003 IP_STR
2004 BGP_STR
3f227172 2005 BGP_VPNVX_HELP_STR
718e3744 2006 "Display information for a route distinguisher\n"
2007 "VPN Route Distinguisher\n"
2008 "Detailed information on TCP and BGP neighbor connections\n"
2009 "Neighbor to display information about\n"
856ca177 2010 "Display routes learned from neighbor\n"
9973d184 2011 JSON_STR)
718e3744 2012{
d62a17ae 2013 int idx_ext_community = 5;
2014 int idx_ipv4 = 7;
2015 int ret;
2016 union sockunion su;
2017 struct peer *peer;
2018 struct prefix_rd prd;
9f049418 2019 bool uj = use_json(argc, argv);
d62a17ae 2020 afi_t afi;
2021 int idx = 0;
2022
2023 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2024 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2025 if (!ret) {
2026 if (uj) {
2027 json_object *json_no = NULL;
2028 json_no = json_object_new_object();
2029 json_object_string_add(
2030 json_no, "warning",
2031 "Malformed Route Distinguisher");
2032 vty_out(vty, "%s\n",
2033 json_object_to_json_string(json_no));
2034 json_object_free(json_no);
2035 } else
2036 vty_out(vty,
2037 "%% Malformed Route Distinguisher\n");
2038 return CMD_WARNING;
2039 }
2040
2041 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2042 if (ret < 0) {
2043 if (uj) {
2044 json_object *json_no = NULL;
2045 json_no = json_object_new_object();
2046 json_object_string_add(json_no, "warning",
2047 "Malformed address");
2048 vty_out(vty, "%s\n",
2049 json_object_to_json_string(json_no));
2050 json_object_free(json_no);
2051 } else
2052 vty_out(vty, "Malformed address: %s\n",
2053 argv[idx_ext_community]->arg);
2054 return CMD_WARNING;
2055 }
2056
2057 peer = peer_lookup(NULL, &su);
2058 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2059 if (uj) {
2060 json_object *json_no = NULL;
2061 json_no = json_object_new_object();
2062 json_object_string_add(
2063 json_no, "warning",
2064 "No such neighbor or address family");
2065 vty_out(vty, "%s\n",
2066 json_object_to_json_string(json_no));
2067 json_object_free(json_no);
2068 } else
2069 vty_out(vty,
2070 "%% No such neighbor or address family\n");
2071 return CMD_WARNING;
2072 }
2073
2074 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_neighbor,
2075 &su, 0, uj);
2076 }
2077 return CMD_SUCCESS;
718e3744 2078}
2079
3f227172
PG
2080DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
2081 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
2082 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
718e3744 2083 SHOW_STR
2084 IP_STR
2085 BGP_STR
3f227172
PG
2086 BGP_VPNVX_HELP_STR
2087 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 2088 "Detailed information on TCP and BGP neighbor connections\n"
2089 "Neighbor to display information about\n"
856ca177 2090 "Display the routes advertised to a BGP neighbor\n"
9973d184 2091 JSON_STR)
718e3744 2092{
d62a17ae 2093 int idx_ipv4 = 6;
2094 int ret;
2095 struct peer *peer;
2096 union sockunion su;
9f049418 2097 bool uj = use_json(argc, argv);
d62a17ae 2098 afi_t afi;
2099 int idx = 0;
2100
2101 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2102 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2103 if (ret < 0) {
2104 if (uj) {
2105 json_object *json_no = NULL;
2106 json_no = json_object_new_object();
2107 json_object_string_add(json_no, "warning",
2108 "Malformed address");
2109 vty_out(vty, "%s\n",
2110 json_object_to_json_string(json_no));
2111 json_object_free(json_no);
2112 } else
2113 vty_out(vty, "Malformed address: %s\n",
2114 argv[idx_ipv4]->arg);
2115 return CMD_WARNING;
2116 }
2117 peer = peer_lookup(NULL, &su);
2118 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2119 if (uj) {
2120 json_object *json_no = NULL;
2121 json_no = json_object_new_object();
2122 json_object_string_add(
2123 json_no, "warning",
2124 "No such neighbor or address family");
2125 vty_out(vty, "%s\n",
2126 json_object_to_json_string(json_no));
2127 json_object_free(json_no);
2128 } else
2129 vty_out(vty,
2130 "%% No such neighbor or address family\n");
2131 return CMD_WARNING;
2132 }
2133 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
2134 SAFI_MPLS_VPN, uj);
2135 }
2136 return CMD_SUCCESS;
718e3744 2137}
2138
3f227172
PG
2139DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
2140 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
d114b977 2141 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
718e3744 2142 SHOW_STR
2143 IP_STR
2144 BGP_STR
3f227172 2145 BGP_VPNVX_HELP_STR
718e3744 2146 "Display information for a route distinguisher\n"
2147 "VPN Route Distinguisher\n"
2148 "Detailed information on TCP and BGP neighbor connections\n"
2149 "Neighbor to display information about\n"
856ca177 2150 "Display the routes advertised to a BGP neighbor\n"
9973d184 2151 JSON_STR)
718e3744 2152{
d62a17ae 2153 int idx_ext_community = 5;
2154 int idx_ipv4 = 7;
2155 int ret;
2156 struct peer *peer;
2157 struct prefix_rd prd;
2158 union sockunion su;
9f049418 2159 bool uj = use_json(argc, argv);
d62a17ae 2160 afi_t afi;
2161 int idx = 0;
2162
2163 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2164 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2165 if (ret < 0) {
2166 if (uj) {
2167 json_object *json_no = NULL;
2168 json_no = json_object_new_object();
2169 json_object_string_add(json_no, "warning",
2170 "Malformed address");
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, "Malformed address: %s\n",
2176 argv[idx_ext_community]->arg);
2177 return CMD_WARNING;
2178 }
2179 peer = peer_lookup(NULL, &su);
2180 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2181 if (uj) {
2182 json_object *json_no = NULL;
2183 json_no = json_object_new_object();
2184 json_object_string_add(
2185 json_no, "warning",
2186 "No such neighbor or address family");
2187 vty_out(vty, "%s\n",
2188 json_object_to_json_string(json_no));
2189 json_object_free(json_no);
2190 } else
2191 vty_out(vty,
2192 "%% No such neighbor or address family\n");
2193 return CMD_WARNING;
2194 }
2195
2196 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2197 if (!ret) {
2198 if (uj) {
2199 json_object *json_no = NULL;
2200 json_no = json_object_new_object();
2201 json_object_string_add(
2202 json_no, "warning",
2203 "Malformed Route Distinguisher");
2204 vty_out(vty, "%s\n",
2205 json_object_to_json_string(json_no));
2206 json_object_free(json_no);
2207 } else
2208 vty_out(vty,
2209 "%% Malformed Route Distinguisher\n");
2210 return CMD_WARNING;
2211 }
2212
2213 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
2214 SAFI_MPLS_VPN, uj);
2215 }
2216 return CMD_SUCCESS;
718e3744 2217}
d6902373 2218#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2219
d62a17ae 2220void bgp_mplsvpn_init(void)
718e3744 2221{
d62a17ae 2222 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
2223 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
2224 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
718e3744 2225
d62a17ae 2226 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
2227 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
c286be96 2228
d62a17ae 2229 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
af8528fa 2230 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
d6902373 2231#ifdef KEEP_OLD_VPN_COMMANDS
af8528fa 2232 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
d62a17ae 2233 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
2234 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
2235 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
2236 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
2237 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
2238 install_element(VIEW_NODE,
2239 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
2240 install_element(VIEW_NODE,
2241 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
d6902373 2242#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2243}
301ad80a
PG
2244
2245vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
2246{
2247 struct listnode *mnode, *mnnode;
2248 struct bgp *bgp;
2249
2250 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2251 struct ecommunity *ec;
2252
2253 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2254 continue;
2255
2256 ec = bgp->vpn_policy[AFI_IP].import_redirect_rtlist;
2257
2258 if (ecom_intersect(ec, eckey))
2259 return bgp->vrf_id;
2260 }
2261 return VRF_UNKNOWN;
2262}
3bd70bf8
PZ
2263
2264/*
2265 * The purpose of this function is to process leaks that were deferred
2266 * from earlier per-vrf configuration due to not-yet-existing default
2267 * vrf, in other words, configuration such as:
2268 *
2269 * router bgp MMM vrf FOO
2270 * address-family ipv4 unicast
2271 * rd vpn export 1:1
2272 * exit-address-family
2273 *
2274 * router bgp NNN
2275 * ...
2276 *
2277 * This function gets called when the default instance ("router bgp NNN")
2278 * is created.
2279 */
2280void vpn_leak_postchange_all(void)
2281{
2282 struct listnode *next;
2283 struct bgp *bgp;
2284 struct bgp *bgp_default = bgp_get_default();
2285
2286 assert(bgp_default);
2287
2288 /* First, do any exporting from VRFs to the single VPN RIB */
2289 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
2290
2291 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2292 continue;
2293
2294 vpn_leak_postchange(
2295 BGP_VPN_POLICY_DIR_TOVPN,
2296 AFI_IP,
2297 bgp_default,
2298 bgp);
2299
2300 vpn_leak_postchange(
2301 BGP_VPN_POLICY_DIR_TOVPN,
2302 AFI_IP6,
2303 bgp_default,
2304 bgp);
2305 }
2306
2307 /* Now, do any importing to VRFs from the single VPN RIB */
2308 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
2309
2310 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2311 continue;
2312
2313 vpn_leak_postchange(
2314 BGP_VPN_POLICY_DIR_FROMVPN,
2315 AFI_IP,
2316 bgp_default,
2317 bgp);
2318
2319 vpn_leak_postchange(
2320 BGP_VPN_POLICY_DIR_FROMVPN,
2321 AFI_IP6,
2322 bgp_default,
2323 bgp);
2324 }
2325}