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