]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.c
bgpd: Convert binfo to path
[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
4b7e6066
DS
405static bool labels_same(struct bgp_path_info *bi, mpls_label_t *label,
406 uint32_t n)
e37fb4bf
PZ
407{
408 uint32_t i;
409
410 if (!bi->extra) {
411 if (!n)
412 return true;
413 else
414 return false;
415 }
416
417 if (n != bi->extra->num_labels)
418 return false;
419
420 for (i = 0; i < n; ++i) {
421 if (label[i] != bi->extra->label[i])
422 return false;
423 }
424 return true;
425}
426
427/*
428 * make encoded route labels match specified encoded label set
429 */
4b7e6066
DS
430static void setlabels(struct bgp_path_info *bi,
431 mpls_label_t *label, /* array of labels */
432 uint32_t num_labels)
e37fb4bf
PZ
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
18ee8310 444 struct bgp_path_info_extra *extra = bgp_path_info_extra_get(bi);
e37fb4bf
PZ
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 456/*
18ee8310 457 * returns pointer to new bgp_path_info upon success
ddb5b488 458 */
4b7e6066
DS
459static struct bgp_path_info *
460leak_update(struct bgp *bgp, /* destination bgp instance */
461 struct bgp_node *bn, struct attr *new_attr, /* already interned */
462 afi_t afi, safi_t safi, struct bgp_path_info *source_bi,
463 mpls_label_t *label, uint32_t num_labels, void *parent,
464 struct bgp *bgp_orig, struct prefix *nexthop_orig,
465 int nexthop_self_flag, int debug)
ddb5b488
PZ
466{
467 struct prefix *p = &bn->p;
4b7e6066
DS
468 struct bgp_path_info *bi;
469 struct bgp_path_info *bi_ultimate;
470 struct bgp_path_info *new;
ddb5b488 471 char buf_prefix[PREFIX_STRLEN];
ddb5b488
PZ
472
473 if (debug) {
474 prefix2str(&bn->p, buf_prefix, sizeof(buf_prefix));
960035b2
PZ
475 zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
476 __func__, bgp->name_pretty, buf_prefix,
477 source_bi->type, source_bi->sub_type);
ddb5b488
PZ
478 }
479
f46d45c1
PZ
480 /*
481 * Routes that are redistributed into BGP from zebra do not get
482 * nexthop tracking. However, if those routes are subsequently
483 * imported to other RIBs within BGP, the leaked routes do not
484 * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
485 * in order to determine if the route we are currently leaking
486 * should have nexthop tracking, we must find the ultimate
487 * parent so we can check its sub_type.
488 *
489 * As of now, source_bi may at most be a second-generation route
490 * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
491 * Using a loop here supports more complex intra-bgp import-export
492 * schemes that could be implemented in the future.
3bd70bf8 493 *
f46d45c1
PZ
494 */
495 for (bi_ultimate = source_bi;
496 bi_ultimate->extra && bi_ultimate->extra->parent;
497 bi_ultimate = bi_ultimate->extra->parent)
498 ;
499
ddb5b488
PZ
500 /*
501 * match parent
502 */
503 for (bi = bn->info; bi; bi = bi->next) {
504 if (bi->extra && bi->extra->parent == parent)
505 break;
506 }
507
508 if (bi) {
e37fb4bf
PZ
509 bool labelssame = labels_same(bi, label, num_labels);
510
1defdda8
DS
511 if (attrhash_cmp(bi->attr, new_attr) && labelssame
512 && !CHECK_FLAG(bi->flags, BGP_PATH_REMOVED)) {
ddb5b488
PZ
513
514 bgp_attr_unintern(&new_attr);
515 if (debug)
516 zlog_debug(
517 "%s: ->%s: %s: Found route, no change",
960035b2 518 __func__, bgp->name_pretty,
ddb5b488
PZ
519 buf_prefix);
520 return NULL;
521 }
522
523 /* attr is changed */
18ee8310 524 bgp_path_info_set_flag(bn, bi, BGP_PATH_ATTR_CHANGED);
ddb5b488
PZ
525
526 /* Rewrite BGP route information. */
1defdda8 527 if (CHECK_FLAG(bi->flags, BGP_PATH_REMOVED))
18ee8310 528 bgp_path_info_restore(bn, bi);
ddb5b488
PZ
529 else
530 bgp_aggregate_decrement(bgp, p, bi, afi, safi);
531 bgp_attr_unintern(&bi->attr);
532 bi->attr = new_attr;
533 bi->uptime = bgp_clock();
534
e37fb4bf
PZ
535 /*
536 * rewrite labels
537 */
538 if (!labelssame)
539 setlabels(bi, label, num_labels);
540
960035b2 541 if (nexthop_self_flag)
18ee8310 542 bgp_path_info_set_flag(bn, bi, BGP_PATH_ANNC_NH_SELF);
960035b2
PZ
543
544 struct bgp *bgp_nexthop = bgp;
545 int nh_valid;
546
547 if (bi->extra && bi->extra->bgp_orig)
548 bgp_nexthop = bi->extra->bgp_orig;
549
550 /* No nexthop tracking for redistributed routes */
f46d45c1 551 if (bi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
960035b2
PZ
552 nh_valid = 1;
553 else
554 /*
555 * TBD do we need to do anything about the
556 * 'connected' parameter?
557 */
558 nh_valid = bgp_find_or_add_nexthop(
559 bgp, bgp_nexthop,
560 afi, bi, NULL, 0);
561
562 if (debug)
563 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
564 __func__, (nh_valid ? "" : "not "),
565 bgp_nexthop->name_pretty);
566
567 if (nh_valid)
18ee8310 568 bgp_path_info_set_flag(bn, bi, BGP_PATH_VALID);
960035b2 569
ddb5b488
PZ
570 /* Process change. */
571 bgp_aggregate_increment(bgp, p, bi, afi, safi);
572 bgp_process(bgp, bn, afi, safi);
573 bgp_unlock_node(bn);
574
575 if (debug)
576 zlog_debug("%s: ->%s: %s Found route, changed attr",
960035b2 577 __func__, bgp->name_pretty, buf_prefix);
ddb5b488 578
e504cf3b 579 return bi;
ddb5b488
PZ
580 }
581
960035b2
PZ
582 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
583 bgp->peer_self, new_attr, bn);
584
585 if (nexthop_self_flag)
18ee8310 586 bgp_path_info_set_flag(bn, new, BGP_PATH_ANNC_NH_SELF);
ddb5b488 587
18ee8310 588 bgp_path_info_extra_get(new);
4b85140f 589
e37fb4bf
PZ
590 if (num_labels)
591 setlabels(new, label, num_labels);
592
18ee8310 593 new->extra->parent = bgp_path_info_lock(parent);
4b7e6066 594 bgp_lock_node((struct bgp_node *)((struct bgp_path_info *)parent)->net);
ddb5b488 595 if (bgp_orig)
21d88ef7 596 new->extra->bgp_orig = bgp_lock(bgp_orig);
ddb5b488
PZ
597 if (nexthop_orig)
598 new->extra->nexthop_orig = *nexthop_orig;
599
960035b2
PZ
600 /*
601 * nexthop tracking for unicast routes
602 */
603 struct bgp *bgp_nexthop = bgp;
604 int nh_valid;
605
4b85140f 606 if (new->extra->bgp_orig)
960035b2
PZ
607 bgp_nexthop = new->extra->bgp_orig;
608
609 /*
610 * No nexthop tracking for redistributed routes because
611 * their originating protocols will do the tracking and
612 * withdraw those routes if the nexthops become unreachable
613 */
f46d45c1 614 if (bi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
960035b2
PZ
615 nh_valid = 1;
616 else
617 /*
618 * TBD do we need to do anything about the
619 * 'connected' parameter?
620 */
621 nh_valid = bgp_find_or_add_nexthop(bgp, bgp_nexthop,
622 afi, new, NULL, 0);
623
624 if (debug)
625 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
626 __func__, (nh_valid ? "" : "not "),
627 bgp_nexthop->name_pretty);
628 if (nh_valid)
18ee8310 629 bgp_path_info_set_flag(bn, new, BGP_PATH_VALID);
960035b2 630
ddb5b488 631 bgp_aggregate_increment(bgp, p, new, afi, safi);
18ee8310 632 bgp_path_info_add(bn, new);
ddb5b488
PZ
633
634 bgp_unlock_node(bn);
635 bgp_process(bgp, bn, afi, safi);
636
637 if (debug)
638 zlog_debug("%s: ->%s: %s: Added new route", __func__,
960035b2 639 bgp->name_pretty, buf_prefix);
ddb5b488
PZ
640
641 return new;
642}
643
644/* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
4b7e6066
DS
645void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
646 struct bgp *bgp_vrf, /* from */
647 struct bgp_path_info *info_vrf) /* route */
ddb5b488
PZ
648{
649 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
650 struct prefix *p = &info_vrf->net->p;
651 afi_t afi = family2afi(p->family);
652 struct attr static_attr = {0};
653 struct attr *new_attr = NULL;
654 safi_t safi = SAFI_MPLS_VPN;
655 mpls_label_t label_val;
656 mpls_label_t label;
657 struct bgp_node *bn;
658 const char *debugmsg;
960035b2
PZ
659 int nexthop_self_flag = 0;
660
661 if (debug)
662 zlog_debug("%s: from vrf %s", __func__, bgp_vrf->name_pretty);
ddb5b488 663
c8f57349
DS
664 if (debug && info_vrf->attr->ecommunity) {
665 char *s = ecommunity_ecom2str(info_vrf->attr->ecommunity,
666 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 667
12a844a5
DS
668 zlog_debug("%s: %s info_vrf->type=%d, EC{%s}", __func__,
669 bgp_vrf->name, info_vrf->type, s);
c8f57349 670 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
671 }
672
673 if (!bgp_vpn)
674 return;
675
676 if (!afi) {
677 if (debug)
678 zlog_debug("%s: can't get afi of prefix", __func__);
679 return;
680 }
681
cc5a6ddd 682 /* loop check - should not be an imported route. */
683 if (info_vrf->extra && info_vrf->extra->bgp_orig)
ddb5b488
PZ
684 return;
685
686
687 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
688 if (debug)
12a844a5
DS
689 zlog_debug("%s: %s skipping: %s", __func__,
690 bgp_vrf->name, debugmsg);
ddb5b488
PZ
691 return;
692 }
693
694 bgp_attr_dup(&static_attr, info_vrf->attr); /* shallow copy */
695
696 /*
697 * route map handling
698 */
699 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
4b7e6066 700 struct bgp_path_info info;
ddb5b488
PZ
701 route_map_result_t ret;
702
703 memset(&info, 0, sizeof(info));
704 info.peer = bgp_vpn->peer_self;
705 info.attr = &static_attr;
706 ret = route_map_apply(
707 bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN],
708 p, RMAP_BGP, &info);
709 if (RMAP_DENYMATCH == ret) {
710 bgp_attr_flush(&static_attr); /* free any added parts */
711 if (debug)
712 zlog_debug(
713 "%s: vrf %s route map \"%s\" says DENY, returning",
960035b2 714 __func__, bgp_vrf->name_pretty,
ddb5b488
PZ
715 bgp_vrf->vpn_policy[afi]
716 .rmap[BGP_VPN_POLICY_DIR_TOVPN]
717 ->name);
718 return;
719 }
720 }
721
c8f57349
DS
722 if (debug && static_attr.ecommunity) {
723 char *s = ecommunity_ecom2str(static_attr.ecommunity,
724 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 725
ddb5b488
PZ
726 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
727 __func__, s);
c8f57349 728 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
729 }
730
731 /*
732 * Add the vpn-policy rt-list
733 */
734 struct ecommunity *old_ecom;
735 struct ecommunity *new_ecom;
736
737 old_ecom = static_attr.ecommunity;
738 if (old_ecom) {
739 new_ecom = ecommunity_merge(
740 ecommunity_dup(old_ecom),
741 bgp_vrf->vpn_policy[afi]
742 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
743 if (!old_ecom->refcnt)
744 ecommunity_free(&old_ecom);
745 } else {
746 new_ecom = ecommunity_dup(
747 bgp_vrf->vpn_policy[afi]
748 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
749 }
750 static_attr.ecommunity = new_ecom;
751 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
752
c8f57349
DS
753 if (debug && static_attr.ecommunity) {
754 char *s = ecommunity_ecom2str(static_attr.ecommunity,
755 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 756
ddb5b488
PZ
757 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
758 __func__, s);
c8f57349 759 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
760 }
761
762 /* Nexthop */
763 /* if policy nexthop not set, use 0 */
764 if (CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
765 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
ddb5b488
PZ
766 struct prefix *nexthop =
767 &bgp_vrf->vpn_policy[afi].tovpn_nexthop;
12a844a5 768
ddb5b488
PZ
769 switch (nexthop->family) {
770 case AF_INET:
771 /* prevent mp_nexthop_global_in <- self in bgp_route.c
772 */
773 static_attr.nexthop.s_addr = nexthop->u.prefix4.s_addr;
774
775 static_attr.mp_nexthop_global_in = nexthop->u.prefix4;
776 static_attr.mp_nexthop_len = 4;
777 break;
778
779 case AF_INET6:
780 static_attr.mp_nexthop_global = nexthop->u.prefix6;
781 static_attr.mp_nexthop_len = 16;
782 break;
783
784 default:
785 assert(0);
786 }
787 } else {
12a844a5
DS
788 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
789 BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
790 if (afi == AFI_IP) {
020a3f60
DS
791 /*
792 * For ipv4, copy to multiprotocol
793 * nexthop field
794 */
795 static_attr.mp_nexthop_global_in =
796 static_attr.nexthop;
12a844a5 797 static_attr.mp_nexthop_len = 4;
020a3f60
DS
798 /*
799 * XXX Leave static_attr.nexthop
800 * intact for NHT
801 */
802 static_attr.flag &=
803 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
12a844a5
DS
804 }
805 } else {
77e62f2b 806 /* Update based on next-hop family to account for
807 * RFC 5549 (BGP unnumbered) scenario. Note that
808 * specific action is only needed for the case of
809 * IPv4 nexthops as the attr has been copied
810 * otherwise.
811 */
812 if (afi == AFI_IP &&
813 !BGP_ATTR_NEXTHOP_AFI_IP6(info_vrf->attr)) {
12a844a5
DS
814 static_attr.mp_nexthop_global_in.s_addr =
815 static_attr.nexthop.s_addr;
816 static_attr.mp_nexthop_len = 4;
817 static_attr.flag |=
818 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
12a844a5 819 }
ddb5b488 820 }
960035b2 821 nexthop_self_flag = 1;
ddb5b488
PZ
822 }
823
824 label_val = bgp_vrf->vpn_policy[afi].tovpn_label;
825 if (label_val == MPLS_LABEL_NONE) {
291e32c3 826 encode_label(MPLS_LABEL_IMPLICIT_NULL, &label);
ddb5b488
PZ
827 } else {
828 encode_label(label_val, &label);
829 }
830
831 /* Set originator ID to "me" */
832 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID));
833 static_attr.originator_id = bgp_vpn->router_id;
834
835
836 new_attr = bgp_attr_intern(
837 &static_attr); /* hashed refcounted everything */
838 bgp_attr_flush(&static_attr); /* free locally-allocated parts */
839
c3e345b1
DS
840 if (debug && new_attr->ecommunity) {
841 char *s = ecommunity_ecom2str(new_attr->ecommunity,
842 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 843
ddb5b488 844 zlog_debug("%s: new_attr->ecommunity{%s}", __func__, s);
c3e345b1 845 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
846 }
847
848 /* Now new_attr is an allocated interned attr */
849
850 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
851 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
852
4b7e6066 853 struct bgp_path_info *new_info;
ddb5b488
PZ
854
855 new_info = leak_update(bgp_vpn, bn, new_attr, afi, safi, info_vrf,
960035b2
PZ
856 &label, 1, info_vrf, bgp_vrf, NULL,
857 nexthop_self_flag, debug);
ddb5b488
PZ
858
859 /*
860 * Routes actually installed in the vpn RIB must also be
861 * offered to all vrfs (because now they originate from
862 * the vpn RIB).
863 *
864 * Acceptance into other vrfs depends on rt-lists.
865 * Originating vrf will not accept the looped back route
866 * because of loop checking.
867 */
868 if (new_info)
321b4bc9 869 vpn_leak_to_vrf_update(bgp_vrf, new_info);
ddb5b488
PZ
870}
871
4b7e6066
DS
872void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
873 struct bgp *bgp_vrf, /* from */
874 struct bgp_path_info *info_vrf) /* route */
ddb5b488
PZ
875{
876 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
877 struct prefix *p = &info_vrf->net->p;
878 afi_t afi = family2afi(p->family);
879 safi_t safi = SAFI_MPLS_VPN;
4b7e6066 880 struct bgp_path_info *bi;
ddb5b488
PZ
881 struct bgp_node *bn;
882 const char *debugmsg;
960035b2
PZ
883 char buf_prefix[PREFIX_STRLEN];
884
885 if (debug) {
886 prefix2str(p, buf_prefix, sizeof(buf_prefix));
887 zlog_debug(
888 "%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
889 __func__, bgp_vrf->name_pretty, buf_prefix,
890 info_vrf->type, info_vrf->sub_type);
891 }
ddb5b488 892
ddb5b488 893 if (info_vrf->sub_type != BGP_ROUTE_NORMAL
82e7e75d 894 && info_vrf->sub_type != BGP_ROUTE_STATIC
895 && info_vrf->sub_type != BGP_ROUTE_REDISTRIBUTE) {
ddb5b488
PZ
896
897 if (debug)
898 zlog_debug("%s: wrong sub_type %d", __func__,
899 info_vrf->sub_type);
900 return;
901 }
902 if (!bgp_vpn)
903 return;
904
905 if (!afi) {
906 if (debug)
907 zlog_debug("%s: can't get afi of prefix", __func__);
908 return;
909 }
910
911 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
912 if (debug)
913 zlog_debug("%s: skipping: %s", __func__, debugmsg);
914 return;
915 }
916
917 if (debug)
918 zlog_debug("%s: withdrawing (info_vrf=%p)", __func__, info_vrf);
919
920 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
921 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
922
923 /*
924 * vrf -> vpn
925 * match original bi imported from
926 */
927 for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
928 if (bi->extra && bi->extra->parent == info_vrf) {
929 break;
930 }
931 }
932
933 if (bi) {
934 /* withdraw from looped vrfs as well */
935 vpn_leak_to_vrf_withdraw(bgp_vpn, bi);
936
937 bgp_aggregate_decrement(bgp_vpn, p, bi, afi, safi);
18ee8310 938 bgp_path_info_delete(bn, bi);
ddb5b488
PZ
939 bgp_process(bgp_vpn, bn, afi, safi);
940 }
941 bgp_unlock_node(bn);
942}
943
944void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
945 struct bgp *bgp_vrf, /* from */
946 afi_t afi)
947{
948 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
949 struct bgp_node *prn;
950 safi_t safi = SAFI_MPLS_VPN;
951
952 /*
ddb5b488
PZ
953 * Walk vpn table, delete bi with bgp_orig == bgp_vrf
954 */
955 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
956 prn = bgp_route_next(prn)) {
957
958 struct bgp_table *table;
959 struct bgp_node *bn;
4b7e6066 960 struct bgp_path_info *bi;
ddb5b488
PZ
961
962 /* This is the per-RD table of prefixes */
963 table = prn->info;
964
965 if (!table)
966 continue;
967
968 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
969
970 char buf[PREFIX2STR_BUFFER];
971
972 if (debug && bn->info) {
973 zlog_debug(
974 "%s: looking at prefix %s", __func__,
975 prefix2str(&bn->p, buf, sizeof(buf)));
976 }
977
978 for (bi = bn->info; bi; bi = bi->next) {
979 if (debug)
980 zlog_debug("%s: type %d, sub_type %d",
981 __func__, bi->type,
982 bi->sub_type);
983 if (bi->sub_type != BGP_ROUTE_IMPORTED)
984 continue;
985 if (!bi->extra)
986 continue;
987 if ((struct bgp *)bi->extra->bgp_orig
988 == bgp_vrf) {
989 /* delete route */
990 if (debug)
991 zlog_debug("%s: deleting it\n",
992 __func__);
993 bgp_aggregate_decrement(bgp_vpn, &bn->p,
994 bi, afi, safi);
18ee8310 995 bgp_path_info_delete(bn, bi);
ddb5b488
PZ
996 bgp_process(bgp_vpn, bn, afi, safi);
997 }
998 }
999 }
1000 }
1001}
1002
1003void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn, /* to */
1004 struct bgp *bgp_vrf, /* from */
1005 afi_t afi)
1006{
1007 struct bgp_node *bn;
4b7e6066 1008 struct bgp_path_info *bi;
ddb5b488
PZ
1009 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
1010
1011 if (debug)
1012 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__, afi,
960035b2 1013 bgp_vrf->name_pretty);
ddb5b488
PZ
1014
1015 for (bn = bgp_table_top(bgp_vrf->rib[afi][SAFI_UNICAST]); bn;
1016 bn = bgp_route_next(bn)) {
1017
1018 if (debug)
1019 zlog_debug("%s: node=%p", __func__, bn);
1020
1021 for (bi = bn->info; bi; bi = bi->next) {
1022 if (debug)
1023 zlog_debug(
1024 "%s: calling vpn_leak_from_vrf_update",
1025 __func__);
1026 vpn_leak_from_vrf_update(bgp_vpn, bgp_vrf, bi);
1027 }
1028 }
1029}
1030
4b7e6066
DS
1031static void
1032vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
1033 struct bgp *bgp_vpn, /* from */
1034 struct bgp_path_info *info_vpn) /* route */
ddb5b488
PZ
1035{
1036 struct prefix *p = &info_vpn->net->p;
1037 afi_t afi = family2afi(p->family);
1038
ddb5b488
PZ
1039 struct attr static_attr = {0};
1040 struct attr *new_attr = NULL;
1041 struct bgp_node *bn;
1042 safi_t safi = SAFI_UNICAST;
1043 const char *debugmsg;
1044 struct prefix nexthop_orig;
1045 mpls_label_t *pLabels = NULL;
e37fb4bf 1046 uint32_t num_labels = 0;
960035b2 1047 int nexthop_self_flag = 1;
4b7e6066 1048 struct bgp_path_info *bi_ultimate = NULL;
513bf8d6 1049 int origin_local = 0;
d6632478 1050 struct bgp *src_vrf;
ddb5b488
PZ
1051
1052 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1053
b9c7bc5a 1054 if (!vpn_leak_from_vpn_active(bgp_vrf, afi, &debugmsg)) {
ddb5b488
PZ
1055 if (debug)
1056 zlog_debug("%s: skipping: %s", __func__, debugmsg);
1057 return;
1058 }
1059
1060 /* Check for intersection of route targets */
1061 if (!ecom_intersect(
1062 bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1063 info_vpn->attr->ecommunity)) {
1064
1065 return;
1066 }
1067
1068 if (debug)
960035b2
PZ
1069 zlog_debug("%s: updating to vrf %s", __func__,
1070 bgp_vrf->name_pretty);
ddb5b488
PZ
1071
1072 bgp_attr_dup(&static_attr, info_vpn->attr); /* shallow copy */
1073
1074 /*
1075 * Nexthop: stash and clear
1076 *
1077 * Nexthop is valid in context of VPN core, but not in destination vrf.
1078 * Stash it for later label resolution by vrf ingress path and then
1079 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1080 */
1081 uint8_t nhfamily = NEXTHOP_FAMILY(info_vpn->attr->mp_nexthop_len);
1082
1083 memset(&nexthop_orig, 0, sizeof(nexthop_orig));
1084 nexthop_orig.family = nhfamily;
1085
1086 switch (nhfamily) {
ddb5b488
PZ
1087 case AF_INET:
1088 /* save */
1089 nexthop_orig.u.prefix4 = info_vpn->attr->mp_nexthop_global_in;
1090 nexthop_orig.prefixlen = 32;
12a844a5
DS
1091
1092 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1093 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1094 static_attr.nexthop.s_addr =
1095 nexthop_orig.u.prefix4.s_addr;
1096
1097 static_attr.mp_nexthop_global_in =
1098 info_vpn->attr->mp_nexthop_global_in;
1099 static_attr.mp_nexthop_len =
1100 info_vpn->attr->mp_nexthop_len;
1101 }
ddb5b488 1102 static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
ddb5b488 1103 break;
ddb5b488
PZ
1104 case AF_INET6:
1105 /* save */
1106 nexthop_orig.u.prefix6 = info_vpn->attr->mp_nexthop_global;
1107 nexthop_orig.prefixlen = 128;
12a844a5
DS
1108
1109 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1110 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1111 static_attr.mp_nexthop_global = nexthop_orig.u.prefix6;
12a844a5 1112 }
ddb5b488
PZ
1113 break;
1114 }
1115
ddb5b488
PZ
1116 /*
1117 * route map handling
ddb5b488 1118 */
ddb5b488 1119 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
4b7e6066 1120 struct bgp_path_info info;
ddb5b488
PZ
1121 route_map_result_t ret;
1122
1123 memset(&info, 0, sizeof(info));
1124 info.peer = bgp_vrf->peer_self;
1125 info.attr = &static_attr;
1126 ret = route_map_apply(bgp_vrf->vpn_policy[afi]
1127 .rmap[BGP_VPN_POLICY_DIR_FROMVPN],
1128 p, RMAP_BGP, &info);
1129 if (RMAP_DENYMATCH == ret) {
1130 bgp_attr_flush(&static_attr); /* free any added parts */
1131 if (debug)
1132 zlog_debug(
1133 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
960035b2 1134 __func__, bgp_vrf->name_pretty,
ddb5b488
PZ
1135 bgp_vrf->vpn_policy[afi]
1136 .rmap[BGP_VPN_POLICY_DIR_FROMVPN]
1137 ->name);
1138 return;
1139 }
960035b2
PZ
1140 /*
1141 * if route-map changed nexthop, don't nexthop-self on output
1142 */
1143 if (!CHECK_FLAG(static_attr.rmap_change_flags,
1144 BATTR_RMAP_NEXTHOP_UNCHANGED))
1145 nexthop_self_flag = 0;
ddb5b488
PZ
1146 }
1147
1148 new_attr = bgp_attr_intern(&static_attr);
1149 bgp_attr_flush(&static_attr);
1150
1151 bn = bgp_afi_node_get(bgp_vrf->rib[afi][safi], afi, safi, p, NULL);
1152
1153 /*
1154 * ensure labels are copied
513bf8d6
PZ
1155 *
1156 * However, there is a special case: if the route originated in
1157 * another local VRF (as opposed to arriving via VPN), then the
1158 * nexthop is reached by hairpinning through this router (me)
1159 * using IP forwarding only (no LSP). Therefore, the route
1160 * imported to the VRF should not have labels attached. Note
1161 * that nexthop tracking is also involved: eliminating the
1162 * labels for these routes enables the non-labeled nexthops
1163 * from the originating VRF to be considered valid for this route.
ddb5b488 1164 */
12a844a5
DS
1165 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1166 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1167 /* work back to original route */
1168 for (bi_ultimate = info_vpn;
1169 bi_ultimate->extra && bi_ultimate->extra->parent;
1170 bi_ultimate = bi_ultimate->extra->parent)
1171 ;
513bf8d6 1172
12a844a5
DS
1173 /*
1174 * if original route was unicast,
1175 * then it did not arrive over vpn
1176 */
1177 if (bi_ultimate->net) {
1178 struct bgp_table *table;
513bf8d6 1179
12a844a5
DS
1180 table = bgp_node_table(bi_ultimate->net);
1181 if (table && (table->safi == SAFI_UNICAST))
1182 origin_local = 1;
1183 }
513bf8d6 1184
12a844a5
DS
1185 /* copy labels */
1186 if (!origin_local &&
1187 info_vpn->extra && info_vpn->extra->num_labels) {
1188 num_labels = info_vpn->extra->num_labels;
1189 if (num_labels > BGP_MAX_LABELS)
1190 num_labels = BGP_MAX_LABELS;
1191 pLabels = info_vpn->extra->label;
1192 }
ddb5b488 1193 }
513bf8d6 1194
ddb5b488
PZ
1195 if (debug) {
1196 char buf_prefix[PREFIX_STRLEN];
1197 prefix2str(p, buf_prefix, sizeof(buf_prefix));
1198 zlog_debug("%s: pfx %s: num_labels %d", __func__, buf_prefix,
1199 num_labels);
1200 }
1201
44338987 1202 /*
1d4e8b0d
DS
1203 * For VRF-2-VRF route-leaking,
1204 * the source will be the originating VRF.
44338987 1205 */
d6632478
PZ
1206 if (info_vpn->extra && info_vpn->extra->bgp_orig)
1207 src_vrf = info_vpn->extra->bgp_orig;
1208 else
1209 src_vrf = bgp_vpn;
1210
960035b2
PZ
1211 leak_update(bgp_vrf, bn, new_attr, afi, safi, info_vpn,
1212 pLabels, num_labels,
1213 info_vpn, /* parent */
d6632478 1214 src_vrf, &nexthop_orig, nexthop_self_flag, debug);
ddb5b488
PZ
1215}
1216
4b7e6066
DS
1217void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
1218 struct bgp_path_info *info_vpn) /* route */
ddb5b488
PZ
1219{
1220 struct listnode *mnode, *mnnode;
1221 struct bgp *bgp;
1222
1223 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1224
1225 if (debug)
1226 zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
1227
1228 /* Loop over VRFs */
1229 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
1230
1231 if (!info_vpn->extra
1232 || info_vpn->extra->bgp_orig != bgp) { /* no loop */
1233 vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, info_vpn);
1234 }
1235 }
1236}
1237
4b7e6066
DS
1238void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
1239 struct bgp_path_info *info_vpn) /* route */
ddb5b488 1240{
1b3510a0
PZ
1241 struct prefix *p;
1242 afi_t afi;
ddb5b488
PZ
1243 safi_t safi = SAFI_UNICAST;
1244 struct bgp *bgp;
1245 struct listnode *mnode, *mnnode;
ddb5b488 1246 struct bgp_node *bn;
4b7e6066 1247 struct bgp_path_info *bi;
ddb5b488 1248 const char *debugmsg;
960035b2 1249 char buf_prefix[PREFIX_STRLEN];
ddb5b488
PZ
1250
1251 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1252
960035b2
PZ
1253 if (debug) {
1254 prefix2str(&info_vpn->net->p, buf_prefix, sizeof(buf_prefix));
1255 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d",
1256 __func__, buf_prefix,
1257 info_vpn->type, info_vpn->sub_type);
1258 }
1259
ddb5b488
PZ
1260 if (debug)
1261 zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
1262
1b3510a0 1263 if (!info_vpn->net) {
56c2c080 1264#if ENABLE_BGP_VNC
1b3510a0
PZ
1265 /* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
1266 if (info_vpn->type == ZEBRA_ROUTE_BGP &&
1267 info_vpn->sub_type == BGP_ROUTE_RFP) {
1268
1269 return;
1270 }
56c2c080 1271#endif
1b3510a0
PZ
1272 if (debug)
1273 zlog_debug("%s: info_vpn->net unexpectedly NULL, no prefix, bailing",
1274 __func__);
1275 return;
1276 }
1277
1278 p = &info_vpn->net->p;
1279 afi = family2afi(p->family);
ddb5b488
PZ
1280
1281 /* Loop over VRFs */
1282 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
b9c7bc5a 1283 if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
ddb5b488
PZ
1284 if (debug)
1285 zlog_debug("%s: skipping: %s", __func__,
1286 debugmsg);
1287 continue;
1288 }
1289
1290 /* Check for intersection of route targets */
1291 if (!ecom_intersect(bgp->vpn_policy[afi]
1292 .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1293 info_vpn->attr->ecommunity)) {
1294
1295 continue;
1296 }
1297
1298 if (debug)
1299 zlog_debug("%s: withdrawing from vrf %s", __func__,
960035b2 1300 bgp->name_pretty);
ddb5b488
PZ
1301
1302 bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
1303 for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
1304 if (bi->extra
4b7e6066 1305 && (struct bgp_path_info *)bi->extra->parent
ddb5b488
PZ
1306 == info_vpn) {
1307 break;
1308 }
1309 }
1310
1311 if (bi) {
1312 if (debug)
1313 zlog_debug("%s: deleting bi %p", __func__, bi);
1314 bgp_aggregate_decrement(bgp, p, bi, afi, safi);
18ee8310 1315 bgp_path_info_delete(bn, bi);
ddb5b488
PZ
1316 bgp_process(bgp, bn, afi, safi);
1317 }
1318 bgp_unlock_node(bn);
1319 }
1320}
1321
1322void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
1323 afi_t afi)
1324{
1325 struct bgp_node *bn;
4b7e6066 1326 struct bgp_path_info *bi;
ddb5b488
PZ
1327 safi_t safi = SAFI_UNICAST;
1328 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
ddb5b488
PZ
1329
1330 if (debug)
1331 zlog_debug("%s: entry", __func__);
1332 /*
d793761d 1333 * Walk vrf table, delete bi with bgp_orig in a different vrf
ddb5b488
PZ
1334 */
1335 for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
1336 bn = bgp_route_next(bn)) {
1337
1338 for (bi = bn->info; bi; bi = bi->next) {
d793761d 1339 if (bi->extra && bi->extra->bgp_orig != bgp_vrf) {
ddb5b488
PZ
1340
1341 /* delete route */
1342 bgp_aggregate_decrement(bgp_vrf, &bn->p, bi,
1343 afi, safi);
18ee8310 1344 bgp_path_info_delete(bn, bi);
ddb5b488
PZ
1345 bgp_process(bgp_vrf, bn, afi, safi);
1346 }
1347 }
1348 }
1349}
1350
1351void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
1352 struct bgp *bgp_vpn, /* from */
1353 afi_t afi)
1354{
1355 struct prefix_rd prd;
1356 struct bgp_node *prn;
1357 safi_t safi = SAFI_MPLS_VPN;
1358
3bd70bf8 1359 assert(bgp_vpn);
73aed584 1360
ddb5b488
PZ
1361 /*
1362 * Walk vpn table
1363 */
1364 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
1365 prn = bgp_route_next(prn)) {
1366
1367 struct bgp_table *table;
1368 struct bgp_node *bn;
4b7e6066 1369 struct bgp_path_info *bi;
ddb5b488
PZ
1370
1371 memset(&prd, 0, sizeof(prd));
1372 prd.family = AF_UNSPEC;
1373 prd.prefixlen = 64;
1374 memcpy(prd.val, prn->p.u.val, 8);
1375
1376 /* This is the per-RD table of prefixes */
1377 table = prn->info;
1378
1379 if (!table)
1380 continue;
1381
1382 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
1383
1384 for (bi = bn->info; bi; bi = bi->next) {
1385
1386 if (bi->extra && bi->extra->bgp_orig == bgp_vrf)
1387 continue;
1388
1389 vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
1390 bi);
1391 }
1392 }
1393 }
1394}
1395
d92a55df
PZ
1396/*
1397 * This function is called for definition/deletion/change to a route-map
1398 */
ddb5b488
PZ
1399static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
1400{
1401 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1402 afi_t afi;
1403 struct route_map *rmap;
1404
1405 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1406 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
1407
1408 return;
1409 }
1410
1411 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
1412
1413 for (afi = 0; afi < AFI_MAX; ++afi) {
1414
d92a55df
PZ
1415 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
1416 && !strcmp(rmap_name,
ddb5b488
PZ
1417 bgp->vpn_policy[afi]
1418 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
1419
1420 if (debug)
1421 zlog_debug(
1422 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1423 __func__, rmap_name, bgp->as,
1424 afi2str(afi));
1425
1426 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1427 bgp_get_default(), bgp);
1428 if (debug)
1429 zlog_debug("%s: after vpn_leak_prechange",
1430 __func__);
1431
d92a55df
PZ
1432 /* in case of definition/deletion */
1433 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN] =
1434 rmap;
ddb5b488
PZ
1435
1436 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1437 bgp_get_default(), bgp);
d92a55df 1438
ddb5b488
PZ
1439 if (debug)
1440 zlog_debug("%s: after vpn_leak_postchange",
1441 __func__);
1442 }
1443
d92a55df
PZ
1444 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]
1445 && !strcmp(rmap_name,
1446 bgp->vpn_policy[afi]
1447 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN])) {
b9c7bc5a
PZ
1448
1449 if (debug) {
1450 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
ddb5b488
PZ
1451 __func__, rmap_name, bgp->as,
1452 afi2str(afi));
b9c7bc5a 1453 }
ddb5b488
PZ
1454
1455 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1456 bgp_get_default(), bgp);
1457
d92a55df
PZ
1458 /* in case of definition/deletion */
1459 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
1460 rmap;
ddb5b488
PZ
1461
1462 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1463 bgp_get_default(), bgp);
1464 }
1465 }
1466}
1467
1468void vpn_policy_routemap_event(const char *rmap_name)
1469{
1470 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1471 struct listnode *mnode, *mnnode;
1472 struct bgp *bgp;
1473
1474 if (debug)
1475 zlog_debug("%s: entry", __func__);
1476
1477 if (bm->bgp == NULL) /* may be called during cleanup */
1478 return;
1479
1480 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
1481 vpn_policy_routemap_update(bgp, rmap_name);
1482}
1483
1d4e8b0d 1484void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 1485 afi_t afi, safi_t safi)
1486{
1487 const char *export_name;
1488 vpn_policy_direction_t idir, edir;
1489 char *vname;
1490 char buf[1000];
1491 struct ecommunity *ecom;
1492 bool first_export = false;
1493
a8dadcf6 1494 export_name = to_bgp->name ? to_bgp->name : BGP_DEFAULT_NAME;
44338987 1495 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1496 edir = BGP_VPN_POLICY_DIR_TOVPN;
1497
1d4e8b0d
DS
1498 /*
1499 * Cross-ref both VRFs. Also, note if this is the first time
44338987 1500 * any VRF is importing from "import_vrf".
1501 */
a8dadcf6
DS
1502 vname = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
1503 : XSTRDUP(MTYPE_TMP, BGP_DEFAULT_NAME));
1504
1d4e8b0d 1505 listnode_add(to_bgp->vpn_policy[afi].import_vrf, vname);
44338987 1506
1d4e8b0d 1507 if (!listcount(from_bgp->vpn_policy[afi].export_vrf))
44338987 1508 first_export = true;
1509 vname = XSTRDUP(MTYPE_TMP, export_name);
1d4e8b0d 1510 listnode_add(from_bgp->vpn_policy[afi].export_vrf, vname);
44338987 1511
1512 /* Update import RT for current VRF using export RT of the VRF we're
1513 * importing from. First though, make sure "import_vrf" has that
1514 * set.
1515 */
1516 if (first_export) {
1d4e8b0d
DS
1517 form_auto_rd(from_bgp->router_id, from_bgp->vrf_rd_id,
1518 &from_bgp->vrf_prd_auto);
1519 from_bgp->vpn_policy[afi].tovpn_rd = from_bgp->vrf_prd_auto;
1520 SET_FLAG(from_bgp->vpn_policy[afi].flags,
44338987 1521 BGP_VPN_POLICY_TOVPN_RD_SET);
1d4e8b0d 1522 prefix_rd2str(&from_bgp->vpn_policy[afi].tovpn_rd,
44338987 1523 buf, sizeof(buf));
1d4e8b0d 1524 from_bgp->vpn_policy[afi].rtlist[edir] =
44338987 1525 ecommunity_str2com(buf, ECOMMUNITY_ROUTE_TARGET, 0);
1d4e8b0d 1526 SET_FLAG(from_bgp->af_flags[afi][safi],
44338987 1527 BGP_CONFIG_VRF_TO_VRF_EXPORT);
13b7e7f0
DS
1528 from_bgp->vpn_policy[afi].tovpn_label =
1529 BGP_PREVENT_VRF_2_VRF_LEAK;
44338987 1530 }
1d4e8b0d
DS
1531 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
1532 if (to_bgp->vpn_policy[afi].rtlist[idir])
1533 to_bgp->vpn_policy[afi].rtlist[idir] =
1534 ecommunity_merge(to_bgp->vpn_policy[afi]
44338987 1535 .rtlist[idir], ecom);
1536 else
1d4e8b0d
DS
1537 to_bgp->vpn_policy[afi].rtlist[idir] = ecommunity_dup(ecom);
1538 SET_FLAG(to_bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT);
44338987 1539
1540 /* Does "import_vrf" first need to export its routes or that
1541 * is already done and we just need to import those routes
1542 * from the global table?
1543 */
1544 if (first_export)
1d4e8b0d 1545 vpn_leak_postchange(edir, afi, bgp_get_default(), from_bgp);
44338987 1546 else
1d4e8b0d 1547 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
44338987 1548}
1549
1d4e8b0d 1550void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 1551 afi_t afi, safi_t safi)
1552{
a8dadcf6 1553 const char *export_name, *tmp_name;
44338987 1554 vpn_policy_direction_t idir, edir;
1555 char *vname;
1556 struct ecommunity *ecom;
1557 struct listnode *node;
1558
a8dadcf6
DS
1559 export_name = to_bgp->name ? to_bgp->name : BGP_DEFAULT_NAME;
1560 tmp_name = from_bgp->name ? from_bgp->name : BGP_DEFAULT_NAME;
44338987 1561 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1562 edir = BGP_VPN_POLICY_DIR_TOVPN;
1563
1564 /* Were we importing from "import_vrf"? */
1d4e8b0d
DS
1565 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf, node,
1566 vname)) {
a8dadcf6 1567 if (strcmp(vname, tmp_name) == 0)
020a3f60 1568 break;
44338987 1569 }
1d4e8b0d
DS
1570
1571 /*
1572 * We do not check in the cli if the passed in bgp
1573 * instance is actually imported into us before
1574 * we call this function. As such if we do not
1575 * find this in the import_vrf list than
1576 * we just need to return safely.
1577 */
44338987 1578 if (!vname)
1579 return;
1580
1581 /* Remove "import_vrf" from our import list. */
1d4e8b0d 1582 listnode_delete(to_bgp->vpn_policy[afi].import_vrf, vname);
44338987 1583 XFREE(MTYPE_TMP, vname);
1584
1585 /* Remove routes imported from "import_vrf". */
1586 /* TODO: In the current logic, we have to first remove all
1587 * imported routes and then (if needed) import back routes
1588 */
1d4e8b0d 1589 vpn_leak_prechange(idir, afi, bgp_get_default(), to_bgp);
44338987 1590
1d4e8b0d
DS
1591 if (to_bgp->vpn_policy[afi].import_vrf->count == 0) {
1592 UNSET_FLAG(to_bgp->af_flags[afi][safi],
44338987 1593 BGP_CONFIG_VRF_TO_VRF_IMPORT);
1d4e8b0d 1594 ecommunity_free(&to_bgp->vpn_policy[afi].rtlist[idir]);
44338987 1595 } else {
1d4e8b0d
DS
1596 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
1597 ecommunity_del_val(to_bgp->vpn_policy[afi].rtlist[idir],
44338987 1598 (struct ecommunity_val *)ecom->val);
1d4e8b0d 1599 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
44338987 1600 }
1601
89d59347
DS
1602 /*
1603 * What?
1604 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
1605 * below is checking for NULL that export_vrf can be
1606 * NULL, consequently it is complaining( like a cabbage )
1607 * that we could dereference and crash in the listcount(..)
1608 * check below.
1609 * So make it happy, under protest, with liberty and justice
1610 * for all.
1611 */
1d4e8b0d 1612 assert(from_bgp->vpn_policy[afi].export_vrf);
89d59347 1613
44338987 1614 /* Remove us from "import_vrf's" export list. If no other VRF
1615 * is importing from "import_vrf", cleanup appropriately.
1616 */
1d4e8b0d 1617 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
44338987 1618 node, vname)) {
1619 if (strcmp(vname, export_name) == 0)
1620 break;
1621 }
1622
1d4e8b0d
DS
1623 /*
1624 * If we have gotten to this point then the vname must
1625 * exist. If not, we are in a world of trouble and
1626 * have slag sitting around.
1627 *
1628 * import_vrf and export_vrf must match in having
1629 * the in/out names as appropriate.
1630 */
1631 assert(vname);
1632
1633 listnode_delete(from_bgp->vpn_policy[afi].export_vrf, vname);
44338987 1634 XFREE(MTYPE_TMP, vname);
1635
1d4e8b0d
DS
1636 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
1637 vpn_leak_prechange(edir, afi, bgp_get_default(), from_bgp);
1638 ecommunity_free(&from_bgp->vpn_policy[afi].rtlist[edir]);
1639 UNSET_FLAG(from_bgp->af_flags[afi][safi],
44338987 1640 BGP_CONFIG_VRF_TO_VRF_EXPORT);
1d4e8b0d 1641 memset(&from_bgp->vpn_policy[afi].tovpn_rd, 0,
44338987 1642 sizeof(struct prefix_rd));
1d4e8b0d 1643 UNSET_FLAG(from_bgp->vpn_policy[afi].flags,
44338987 1644 BGP_VPN_POLICY_TOVPN_RD_SET);
13b7e7f0
DS
1645 from_bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE;
1646
44338987 1647 }
1648}
1649
718e3744 1650/* For testing purpose, static route of MPLS-VPN. */
1651DEFUN (vpnv4_network,
1652 vpnv4_network_cmd,
d114b977 1653 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1654 "Specify a network to announce via BGP\n"
0c7b1b01 1655 "IPv4 prefix\n"
718e3744 1656 "Specify Route Distinguisher\n"
1657 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1658 "VPN NLRI label (tag)\n"
1659 "VPN NLRI label (tag)\n"
1660 "Label value\n")
718e3744 1661{
d62a17ae 1662 int idx_ipv4_prefixlen = 1;
1663 int idx_ext_community = 3;
1664 int idx_label = 5;
1665 return bgp_static_set_safi(
1666 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1667 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
1668 NULL, NULL, NULL, NULL);
137446f9
LB
1669}
1670
1671DEFUN (vpnv4_network_route_map,
1672 vpnv4_network_route_map_cmd,
d114b977 1673 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
137446f9 1674 "Specify a network to announce via BGP\n"
0c7b1b01 1675 "IPv4 prefix\n"
137446f9
LB
1676 "Specify Route Distinguisher\n"
1677 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1678 "VPN NLRI label (tag)\n"
1679 "VPN NLRI label (tag)\n"
1680 "Label value\n"
137446f9
LB
1681 "route map\n"
1682 "route map name\n")
1683{
d62a17ae 1684 int idx_ipv4_prefixlen = 1;
1685 int idx_ext_community = 3;
1686 int idx_label = 5;
1687 int idx_word_2 = 7;
1688 return bgp_static_set_safi(
1689 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1690 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1691 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
718e3744 1692}
1693
1694/* For testing purpose, static route of MPLS-VPN. */
1695DEFUN (no_vpnv4_network,
1696 no_vpnv4_network_cmd,
d114b977 1697 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1698 NO_STR
1699 "Specify a network to announce via BGP\n"
0c7b1b01 1700 "IPv4 prefix\n"
718e3744 1701 "Specify Route Distinguisher\n"
1702 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1703 "VPN NLRI label (tag)\n"
1704 "VPN NLRI label (tag)\n"
1705 "Label value\n")
718e3744 1706{
d62a17ae 1707 int idx_ipv4_prefixlen = 2;
1708 int idx_ext_community = 4;
1709 int idx_label = 6;
1710 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
1711 argv[idx_ipv4_prefixlen]->arg,
1712 argv[idx_ext_community]->arg,
1713 argv[idx_label]->arg, 0, NULL, NULL, NULL);
718e3744 1714}
1715
c286be96
LX
1716DEFUN (vpnv6_network,
1717 vpnv6_network_cmd,
d114b977 1718 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
c286be96
LX
1719 "Specify a network to announce via BGP\n"
1720 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1721 "Specify Route Distinguisher\n"
1722 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1723 "VPN NLRI label (tag)\n"
1724 "VPN NLRI label (tag)\n"
1725 "Label value\n"
11daee81
DS
1726 "route map\n"
1727 "route map name\n")
c286be96 1728{
d62a17ae 1729 int idx_ipv6_prefix = 1;
1730 int idx_ext_community = 3;
1731 int idx_label = 5;
1732 int idx_word_2 = 7;
1733 if (argc == 8)
1734 return bgp_static_set_safi(
1735 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1736 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1737 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
1738 else
1739 return bgp_static_set_safi(
1740 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1741 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1742 NULL, 0, NULL, NULL, NULL, NULL);
c286be96
LX
1743}
1744
1745/* For testing purpose, static route of MPLS-VPN. */
1746DEFUN (no_vpnv6_network,
1747 no_vpnv6_network_cmd,
d114b977 1748 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
c286be96
LX
1749 NO_STR
1750 "Specify a network to announce via BGP\n"
1751 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1752 "Specify Route Distinguisher\n"
1753 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1754 "VPN NLRI label (tag)\n"
1755 "VPN NLRI label (tag)\n"
1756 "Label value\n")
c286be96 1757{
d62a17ae 1758 int idx_ipv6_prefix = 2;
1759 int idx_ext_community = 4;
1760 int idx_label = 6;
1761 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
1762 argv[idx_ipv6_prefix]->arg,
1763 argv[idx_ext_community]->arg,
1764 argv[idx_label]->arg, 0, NULL, NULL, NULL);
c286be96
LX
1765}
1766
d62a17ae 1767int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
1768 enum bgp_show_type type, void *output_arg, int tags,
9f049418 1769 bool use_json)
718e3744 1770{
d62a17ae 1771 struct bgp *bgp;
1772 struct bgp_table *table;
d62a17ae 1773
1774 bgp = bgp_get_default();
1775 if (bgp == NULL) {
1776 if (!use_json)
1777 vty_out(vty, "No BGP process is configured\n");
16307668
RW
1778 else
1779 vty_out(vty, "{}\n");
d62a17ae 1780 return CMD_WARNING;
1781 }
1ae44dfc 1782 table = bgp->rib[afi][SAFI_MPLS_VPN];
a4d82a8a
PZ
1783 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
1784 output_arg, use_json);
718e3744 1785}
1786
4f280b15
LB
1787DEFUN (show_bgp_ip_vpn_all_rd,
1788 show_bgp_ip_vpn_all_rd_cmd,
d114b977 1789 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
e3e29b32
LB
1790 SHOW_STR
1791 BGP_STR
05e588f4 1792 BGP_VPNVX_HELP_STR
e3e29b32 1793 "Display VPN NLRI specific information\n"
af8528fa 1794 "Display VPN NLRI specific information\n"
e3e29b32
LB
1795 "Display information for a route distinguisher\n"
1796 "VPN Route Distinguisher\n"
1797 JSON_STR)
1798{
d62a17ae 1799 int ret;
1800 struct prefix_rd prd;
1801 afi_t afi;
1802 int idx = 0;
1803
1804 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
3d7c4cd7 1805 if (argv_find(argv, argc, "rd", &idx)) {
a4d82a8a 1806 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
d62a17ae 1807 if (!ret) {
1808 vty_out(vty,
1809 "%% Malformed Route Distinguisher\n");
1810 return CMD_WARNING;
1811 }
1812 return bgp_show_mpls_vpn(vty, afi, &prd,
1813 bgp_show_type_normal, NULL, 0,
1814 use_json(argc, argv));
1815 } else {
1816 return bgp_show_mpls_vpn(vty, afi, NULL,
1817 bgp_show_type_normal, NULL, 0,
1818 use_json(argc, argv));
1819 }
1820 }
1821 return CMD_SUCCESS;
718e3744 1822}
1823
af8528fa
LB
1824ALIAS(show_bgp_ip_vpn_all_rd,
1825 show_bgp_ip_vpn_rd_cmd,
1826 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1827 SHOW_STR
1828 BGP_STR
1829 BGP_VPNVX_HELP_STR
1830 "Display VPN NLRI specific information\n"
1831 "Display information for a route distinguisher\n"
1832 "VPN Route Distinguisher\n"
1833 JSON_STR)
1834
1835#ifdef KEEP_OLD_VPN_COMMANDS
3f227172
PG
1836DEFUN (show_ip_bgp_vpn_rd,
1837 show_ip_bgp_vpn_rd_cmd,
af8528fa 1838 "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
718e3744 1839 SHOW_STR
1840 IP_STR
1841 BGP_STR
4f280b15 1842 BGP_AFI_HELP_STR
3517059b 1843 "Address Family modifier\n"
718e3744 1844 "Display information for a route distinguisher\n"
1845 "VPN Route Distinguisher\n")
1846{
d62a17ae 1847 int idx_ext_community = argc - 1;
1848 int ret;
1849 struct prefix_rd prd;
1850 afi_t afi;
1851 int idx = 0;
1852
1853 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1854 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1855 if (!ret) {
1856 vty_out(vty, "%% Malformed Route Distinguisher\n");
1857 return CMD_WARNING;
1858 }
1859 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1860 NULL, 0, 0);
1861 }
1862 return CMD_SUCCESS;
1863}
718e3744 1864
4f280b15
LB
1865DEFUN (show_ip_bgp_vpn_all,
1866 show_ip_bgp_vpn_all_cmd,
1867 "show [ip] bgp <vpnv4|vpnv6>",
1868 SHOW_STR
1869 IP_STR
1870 BGP_STR
1871 BGP_VPNVX_HELP_STR)
1872{
d62a17ae 1873 afi_t afi;
1874 int idx = 0;
4f280b15 1875
d62a17ae 1876 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1877 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1878 NULL, 0, 0);
1879 return CMD_SUCCESS;
4f280b15
LB
1880}
1881
3f227172
PG
1882DEFUN (show_ip_bgp_vpn_all_tags,
1883 show_ip_bgp_vpn_all_tags_cmd,
1884 "show [ip] bgp <vpnv4|vpnv6> all tags",
718e3744 1885 SHOW_STR
1886 IP_STR
1887 BGP_STR
3f227172
PG
1888 BGP_VPNVX_HELP_STR
1889 "Display information about all VPNv4/VPNV6 NLRIs\n"
718e3744 1890 "Display BGP tags for prefixes\n")
1891{
d62a17ae 1892 afi_t afi;
1893 int idx = 0;
3f227172 1894
d62a17ae 1895 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1896 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1897 NULL, 1, 0);
1898 return CMD_SUCCESS;
718e3744 1899}
1900
3f227172
PG
1901DEFUN (show_ip_bgp_vpn_rd_tags,
1902 show_ip_bgp_vpn_rd_tags_cmd,
d114b977 1903 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
718e3744 1904 SHOW_STR
1905 IP_STR
1906 BGP_STR
3f227172 1907 BGP_VPNVX_HELP_STR
718e3744 1908 "Display information for a route distinguisher\n"
1909 "VPN Route Distinguisher\n"
1910 "Display BGP tags for prefixes\n")
1911{
d62a17ae 1912 int idx_ext_community = 5;
1913 int ret;
1914 struct prefix_rd prd;
1915 afi_t afi;
1916 int idx = 0;
1917
1918 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1919 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1920 if (!ret) {
1921 vty_out(vty, "%% Malformed Route Distinguisher\n");
1922 return CMD_WARNING;
1923 }
1924 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1925 NULL, 1, 0);
1926 }
1927 return CMD_SUCCESS;
718e3744 1928}
1929
3f227172
PG
1930DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
1931 show_ip_bgp_vpn_all_neighbor_routes_cmd,
1932 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
718e3744 1933 SHOW_STR
1934 IP_STR
1935 BGP_STR
3f227172
PG
1936 BGP_VPNVX_HELP_STR
1937 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 1938 "Detailed information on TCP and BGP neighbor connections\n"
1939 "Neighbor to display information about\n"
856ca177 1940 "Display routes learned from neighbor\n"
9973d184 1941 JSON_STR)
718e3744 1942{
d62a17ae 1943 int idx_ipv4 = 6;
1944 union sockunion su;
1945 struct peer *peer;
1946 int ret;
9f049418 1947 bool uj = use_json(argc, argv);
d62a17ae 1948 afi_t afi;
1949 int idx = 0;
1950
1951 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1952 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1953 if (ret < 0) {
1954 if (uj) {
1955 json_object *json_no = NULL;
1956 json_no = json_object_new_object();
1957 json_object_string_add(json_no, "warning",
1958 "Malformed address");
1959 vty_out(vty, "%s\n",
1960 json_object_to_json_string(json_no));
1961 json_object_free(json_no);
1962 } else
1963 vty_out(vty, "Malformed address: %s\n",
1964 argv[idx_ipv4]->arg);
1965 return CMD_WARNING;
1966 }
1967
1968 peer = peer_lookup(NULL, &su);
1969 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1970 if (uj) {
1971 json_object *json_no = NULL;
1972 json_no = json_object_new_object();
1973 json_object_string_add(
1974 json_no, "warning",
1975 "No such neighbor or address family");
1976 vty_out(vty, "%s\n",
1977 json_object_to_json_string(json_no));
1978 json_object_free(json_no);
1979 } else
1980 vty_out(vty,
1981 "%% No such neighbor or address family\n");
1982 return CMD_WARNING;
1983 }
1984
1985 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
1986 &su, 0, uj);
1987 }
1988 return CMD_SUCCESS;
718e3744 1989}
1990
3f227172
PG
1991DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
1992 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
d114b977 1993 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
718e3744 1994 SHOW_STR
1995 IP_STR
1996 BGP_STR
3f227172 1997 BGP_VPNVX_HELP_STR
718e3744 1998 "Display information for a route distinguisher\n"
1999 "VPN Route Distinguisher\n"
2000 "Detailed information on TCP and BGP neighbor connections\n"
2001 "Neighbor to display information about\n"
856ca177 2002 "Display routes learned from neighbor\n"
9973d184 2003 JSON_STR)
718e3744 2004{
d62a17ae 2005 int idx_ext_community = 5;
2006 int idx_ipv4 = 7;
2007 int ret;
2008 union sockunion su;
2009 struct peer *peer;
2010 struct prefix_rd prd;
9f049418 2011 bool uj = use_json(argc, argv);
d62a17ae 2012 afi_t afi;
2013 int idx = 0;
2014
2015 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2016 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2017 if (!ret) {
2018 if (uj) {
2019 json_object *json_no = NULL;
2020 json_no = json_object_new_object();
2021 json_object_string_add(
2022 json_no, "warning",
2023 "Malformed Route Distinguisher");
2024 vty_out(vty, "%s\n",
2025 json_object_to_json_string(json_no));
2026 json_object_free(json_no);
2027 } else
2028 vty_out(vty,
2029 "%% Malformed Route Distinguisher\n");
2030 return CMD_WARNING;
2031 }
2032
2033 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2034 if (ret < 0) {
2035 if (uj) {
2036 json_object *json_no = NULL;
2037 json_no = json_object_new_object();
2038 json_object_string_add(json_no, "warning",
2039 "Malformed address");
2040 vty_out(vty, "%s\n",
2041 json_object_to_json_string(json_no));
2042 json_object_free(json_no);
2043 } else
2044 vty_out(vty, "Malformed address: %s\n",
2045 argv[idx_ext_community]->arg);
2046 return CMD_WARNING;
2047 }
2048
2049 peer = peer_lookup(NULL, &su);
2050 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2051 if (uj) {
2052 json_object *json_no = NULL;
2053 json_no = json_object_new_object();
2054 json_object_string_add(
2055 json_no, "warning",
2056 "No such neighbor or address family");
2057 vty_out(vty, "%s\n",
2058 json_object_to_json_string(json_no));
2059 json_object_free(json_no);
2060 } else
2061 vty_out(vty,
2062 "%% No such neighbor or address family\n");
2063 return CMD_WARNING;
2064 }
2065
2066 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_neighbor,
2067 &su, 0, uj);
2068 }
2069 return CMD_SUCCESS;
718e3744 2070}
2071
3f227172
PG
2072DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
2073 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
2074 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
718e3744 2075 SHOW_STR
2076 IP_STR
2077 BGP_STR
3f227172
PG
2078 BGP_VPNVX_HELP_STR
2079 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 2080 "Detailed information on TCP and BGP neighbor connections\n"
2081 "Neighbor to display information about\n"
856ca177 2082 "Display the routes advertised to a BGP neighbor\n"
9973d184 2083 JSON_STR)
718e3744 2084{
d62a17ae 2085 int idx_ipv4 = 6;
2086 int ret;
2087 struct peer *peer;
2088 union sockunion su;
9f049418 2089 bool uj = use_json(argc, argv);
d62a17ae 2090 afi_t afi;
2091 int idx = 0;
2092
2093 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2094 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2095 if (ret < 0) {
2096 if (uj) {
2097 json_object *json_no = NULL;
2098 json_no = json_object_new_object();
2099 json_object_string_add(json_no, "warning",
2100 "Malformed address");
2101 vty_out(vty, "%s\n",
2102 json_object_to_json_string(json_no));
2103 json_object_free(json_no);
2104 } else
2105 vty_out(vty, "Malformed address: %s\n",
2106 argv[idx_ipv4]->arg);
2107 return CMD_WARNING;
2108 }
2109 peer = peer_lookup(NULL, &su);
2110 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2111 if (uj) {
2112 json_object *json_no = NULL;
2113 json_no = json_object_new_object();
2114 json_object_string_add(
2115 json_no, "warning",
2116 "No such neighbor or address family");
2117 vty_out(vty, "%s\n",
2118 json_object_to_json_string(json_no));
2119 json_object_free(json_no);
2120 } else
2121 vty_out(vty,
2122 "%% No such neighbor or address family\n");
2123 return CMD_WARNING;
2124 }
2125 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
2126 SAFI_MPLS_VPN, uj);
2127 }
2128 return CMD_SUCCESS;
718e3744 2129}
2130
3f227172
PG
2131DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
2132 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
d114b977 2133 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
718e3744 2134 SHOW_STR
2135 IP_STR
2136 BGP_STR
3f227172 2137 BGP_VPNVX_HELP_STR
718e3744 2138 "Display information for a route distinguisher\n"
2139 "VPN Route Distinguisher\n"
2140 "Detailed information on TCP and BGP neighbor connections\n"
2141 "Neighbor to display information about\n"
856ca177 2142 "Display the routes advertised to a BGP neighbor\n"
9973d184 2143 JSON_STR)
718e3744 2144{
d62a17ae 2145 int idx_ext_community = 5;
2146 int idx_ipv4 = 7;
2147 int ret;
2148 struct peer *peer;
2149 struct prefix_rd prd;
2150 union sockunion su;
9f049418 2151 bool uj = use_json(argc, argv);
d62a17ae 2152 afi_t afi;
2153 int idx = 0;
2154
2155 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2156 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2157 if (ret < 0) {
2158 if (uj) {
2159 json_object *json_no = NULL;
2160 json_no = json_object_new_object();
2161 json_object_string_add(json_no, "warning",
2162 "Malformed address");
2163 vty_out(vty, "%s\n",
2164 json_object_to_json_string(json_no));
2165 json_object_free(json_no);
2166 } else
2167 vty_out(vty, "Malformed address: %s\n",
2168 argv[idx_ext_community]->arg);
2169 return CMD_WARNING;
2170 }
2171 peer = peer_lookup(NULL, &su);
2172 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2173 if (uj) {
2174 json_object *json_no = NULL;
2175 json_no = json_object_new_object();
2176 json_object_string_add(
2177 json_no, "warning",
2178 "No such neighbor or address family");
2179 vty_out(vty, "%s\n",
2180 json_object_to_json_string(json_no));
2181 json_object_free(json_no);
2182 } else
2183 vty_out(vty,
2184 "%% No such neighbor or address family\n");
2185 return CMD_WARNING;
2186 }
2187
2188 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2189 if (!ret) {
2190 if (uj) {
2191 json_object *json_no = NULL;
2192 json_no = json_object_new_object();
2193 json_object_string_add(
2194 json_no, "warning",
2195 "Malformed Route Distinguisher");
2196 vty_out(vty, "%s\n",
2197 json_object_to_json_string(json_no));
2198 json_object_free(json_no);
2199 } else
2200 vty_out(vty,
2201 "%% Malformed Route Distinguisher\n");
2202 return CMD_WARNING;
2203 }
2204
2205 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
2206 SAFI_MPLS_VPN, uj);
2207 }
2208 return CMD_SUCCESS;
718e3744 2209}
d6902373 2210#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2211
d62a17ae 2212void bgp_mplsvpn_init(void)
718e3744 2213{
d62a17ae 2214 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
2215 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
2216 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
718e3744 2217
d62a17ae 2218 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
2219 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
c286be96 2220
d62a17ae 2221 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
af8528fa 2222 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
d6902373 2223#ifdef KEEP_OLD_VPN_COMMANDS
af8528fa 2224 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
d62a17ae 2225 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
2226 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
2227 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
2228 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
2229 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
2230 install_element(VIEW_NODE,
2231 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
2232 install_element(VIEW_NODE,
2233 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
d6902373 2234#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2235}
301ad80a
PG
2236
2237vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
2238{
2239 struct listnode *mnode, *mnnode;
2240 struct bgp *bgp;
2241
2242 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2243 struct ecommunity *ec;
2244
2245 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2246 continue;
2247
2248 ec = bgp->vpn_policy[AFI_IP].import_redirect_rtlist;
2249
2250 if (ecom_intersect(ec, eckey))
2251 return bgp->vrf_id;
2252 }
2253 return VRF_UNKNOWN;
2254}
3bd70bf8
PZ
2255
2256/*
2257 * The purpose of this function is to process leaks that were deferred
2258 * from earlier per-vrf configuration due to not-yet-existing default
2259 * vrf, in other words, configuration such as:
2260 *
2261 * router bgp MMM vrf FOO
2262 * address-family ipv4 unicast
2263 * rd vpn export 1:1
2264 * exit-address-family
2265 *
2266 * router bgp NNN
2267 * ...
2268 *
2269 * This function gets called when the default instance ("router bgp NNN")
2270 * is created.
2271 */
2272void vpn_leak_postchange_all(void)
2273{
2274 struct listnode *next;
2275 struct bgp *bgp;
2276 struct bgp *bgp_default = bgp_get_default();
2277
2278 assert(bgp_default);
2279
2280 /* First, do any exporting from VRFs to the single VPN RIB */
2281 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
2282
2283 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2284 continue;
2285
2286 vpn_leak_postchange(
2287 BGP_VPN_POLICY_DIR_TOVPN,
2288 AFI_IP,
2289 bgp_default,
2290 bgp);
2291
2292 vpn_leak_postchange(
2293 BGP_VPN_POLICY_DIR_TOVPN,
2294 AFI_IP6,
2295 bgp_default,
2296 bgp);
2297 }
2298
2299 /* Now, do any importing to VRFs from the single VPN RIB */
2300 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
2301
2302 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2303 continue;
2304
2305 vpn_leak_postchange(
2306 BGP_VPN_POLICY_DIR_FROMVPN,
2307 AFI_IP,
2308 bgp_default,
2309 bgp);
2310
2311 vpn_leak_postchange(
2312 BGP_VPN_POLICY_DIR_FROMVPN,
2313 AFI_IP6,
2314 bgp_default,
2315 bgp);
2316 }
2317}