]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.c
Merge pull request #3909 from AnuradhaKaruppiah/l3-vni-0
[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
1dcc9e5b
CS
1076 if (debug) {
1077 char buf_prefix[PREFIX_STRLEN];
1078
1079 prefix2str(p, buf_prefix, sizeof(buf_prefix));
1080 zlog_debug("%s: updating %s to vrf %s", __func__,
1081 buf_prefix, bgp_vrf->name_pretty);
1082 }
ddb5b488 1083
40381db7 1084 bgp_attr_dup(&static_attr, path_vpn->attr); /* shallow copy */
ddb5b488
PZ
1085
1086 /*
1087 * Nexthop: stash and clear
1088 *
1089 * Nexthop is valid in context of VPN core, but not in destination vrf.
1090 * Stash it for later label resolution by vrf ingress path and then
1091 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1092 */
40381db7 1093 uint8_t nhfamily = NEXTHOP_FAMILY(path_vpn->attr->mp_nexthop_len);
ddb5b488
PZ
1094
1095 memset(&nexthop_orig, 0, sizeof(nexthop_orig));
1096 nexthop_orig.family = nhfamily;
1097
1098 switch (nhfamily) {
ddb5b488
PZ
1099 case AF_INET:
1100 /* save */
40381db7 1101 nexthop_orig.u.prefix4 = path_vpn->attr->mp_nexthop_global_in;
ddb5b488 1102 nexthop_orig.prefixlen = 32;
12a844a5
DS
1103
1104 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1105 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1106 static_attr.nexthop.s_addr =
1107 nexthop_orig.u.prefix4.s_addr;
1108
1109 static_attr.mp_nexthop_global_in =
40381db7 1110 path_vpn->attr->mp_nexthop_global_in;
12a844a5 1111 static_attr.mp_nexthop_len =
40381db7 1112 path_vpn->attr->mp_nexthop_len;
12a844a5 1113 }
de4d0a51 1114 static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
ddb5b488 1115 break;
ddb5b488
PZ
1116 case AF_INET6:
1117 /* save */
40381db7 1118 nexthop_orig.u.prefix6 = path_vpn->attr->mp_nexthop_global;
ddb5b488 1119 nexthop_orig.prefixlen = 128;
12a844a5
DS
1120
1121 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1122 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1123 static_attr.mp_nexthop_global = nexthop_orig.u.prefix6;
12a844a5 1124 }
ddb5b488
PZ
1125 break;
1126 }
1127
ddb5b488
PZ
1128 /*
1129 * route map handling
ddb5b488 1130 */
ddb5b488 1131 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
4b7e6066 1132 struct bgp_path_info info;
ddb5b488
PZ
1133 route_map_result_t ret;
1134
1135 memset(&info, 0, sizeof(info));
1136 info.peer = bgp_vrf->peer_self;
1137 info.attr = &static_attr;
1dcc9e5b 1138 info.extra = path_vpn->extra; /* Used for source-vrf filter */
ddb5b488
PZ
1139 ret = route_map_apply(bgp_vrf->vpn_policy[afi]
1140 .rmap[BGP_VPN_POLICY_DIR_FROMVPN],
1141 p, RMAP_BGP, &info);
1142 if (RMAP_DENYMATCH == ret) {
1143 bgp_attr_flush(&static_attr); /* free any added parts */
1144 if (debug)
1145 zlog_debug(
1146 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
960035b2 1147 __func__, bgp_vrf->name_pretty,
ddb5b488
PZ
1148 bgp_vrf->vpn_policy[afi]
1149 .rmap[BGP_VPN_POLICY_DIR_FROMVPN]
1150 ->name);
1151 return;
1152 }
960035b2
PZ
1153 /*
1154 * if route-map changed nexthop, don't nexthop-self on output
1155 */
1156 if (!CHECK_FLAG(static_attr.rmap_change_flags,
1157 BATTR_RMAP_NEXTHOP_UNCHANGED))
1158 nexthop_self_flag = 0;
ddb5b488
PZ
1159 }
1160
1161 new_attr = bgp_attr_intern(&static_attr);
1162 bgp_attr_flush(&static_attr);
1163
1164 bn = bgp_afi_node_get(bgp_vrf->rib[afi][safi], afi, safi, p, NULL);
1165
1166 /*
1167 * ensure labels are copied
513bf8d6
PZ
1168 *
1169 * However, there is a special case: if the route originated in
1170 * another local VRF (as opposed to arriving via VPN), then the
1171 * nexthop is reached by hairpinning through this router (me)
1172 * using IP forwarding only (no LSP). Therefore, the route
1173 * imported to the VRF should not have labels attached. Note
1174 * that nexthop tracking is also involved: eliminating the
1175 * labels for these routes enables the non-labeled nexthops
1176 * from the originating VRF to be considered valid for this route.
ddb5b488 1177 */
12a844a5
DS
1178 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1179 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1180 /* work back to original route */
40381db7
DS
1181 for (bpi_ultimate = path_vpn;
1182 bpi_ultimate->extra && bpi_ultimate->extra->parent;
1183 bpi_ultimate = bpi_ultimate->extra->parent)
12a844a5 1184 ;
513bf8d6 1185
12a844a5
DS
1186 /*
1187 * if original route was unicast,
1188 * then it did not arrive over vpn
1189 */
40381db7 1190 if (bpi_ultimate->net) {
12a844a5 1191 struct bgp_table *table;
513bf8d6 1192
40381db7 1193 table = bgp_node_table(bpi_ultimate->net);
12a844a5
DS
1194 if (table && (table->safi == SAFI_UNICAST))
1195 origin_local = 1;
1196 }
513bf8d6 1197
12a844a5 1198 /* copy labels */
40381db7
DS
1199 if (!origin_local && path_vpn->extra
1200 && path_vpn->extra->num_labels) {
1201 num_labels = path_vpn->extra->num_labels;
12a844a5
DS
1202 if (num_labels > BGP_MAX_LABELS)
1203 num_labels = BGP_MAX_LABELS;
40381db7 1204 pLabels = path_vpn->extra->label;
12a844a5 1205 }
ddb5b488 1206 }
513bf8d6 1207
ddb5b488
PZ
1208 if (debug) {
1209 char buf_prefix[PREFIX_STRLEN];
1210 prefix2str(p, buf_prefix, sizeof(buf_prefix));
1211 zlog_debug("%s: pfx %s: num_labels %d", __func__, buf_prefix,
1212 num_labels);
1213 }
1214
44338987 1215 /*
1d4e8b0d
DS
1216 * For VRF-2-VRF route-leaking,
1217 * the source will be the originating VRF.
44338987 1218 */
40381db7
DS
1219 if (path_vpn->extra && path_vpn->extra->bgp_orig)
1220 src_vrf = path_vpn->extra->bgp_orig;
d6632478
PZ
1221 else
1222 src_vrf = bgp_vpn;
1223
40381db7
DS
1224 leak_update(bgp_vrf, bn, new_attr, afi, safi, path_vpn, pLabels,
1225 num_labels, path_vpn, /* parent */
1226 src_vrf, &nexthop_orig, nexthop_self_flag, debug);
ddb5b488
PZ
1227}
1228
4b7e6066 1229void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
40381db7 1230 struct bgp_path_info *path_vpn) /* route */
ddb5b488
PZ
1231{
1232 struct listnode *mnode, *mnnode;
1233 struct bgp *bgp;
1234
1235 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1236
1237 if (debug)
40381db7 1238 zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
ddb5b488
PZ
1239
1240 /* Loop over VRFs */
1241 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
1242
40381db7
DS
1243 if (!path_vpn->extra
1244 || path_vpn->extra->bgp_orig != bgp) { /* no loop */
1245 vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, path_vpn);
ddb5b488
PZ
1246 }
1247 }
1248}
1249
4b7e6066 1250void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
40381db7 1251 struct bgp_path_info *path_vpn) /* route */
ddb5b488 1252{
1b3510a0
PZ
1253 struct prefix *p;
1254 afi_t afi;
ddb5b488
PZ
1255 safi_t safi = SAFI_UNICAST;
1256 struct bgp *bgp;
1257 struct listnode *mnode, *mnnode;
ddb5b488 1258 struct bgp_node *bn;
40381db7 1259 struct bgp_path_info *bpi;
ddb5b488 1260 const char *debugmsg;
960035b2 1261 char buf_prefix[PREFIX_STRLEN];
ddb5b488
PZ
1262
1263 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1264
960035b2 1265 if (debug) {
40381db7
DS
1266 prefix2str(&path_vpn->net->p, buf_prefix, sizeof(buf_prefix));
1267 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d", __func__,
1268 buf_prefix, path_vpn->type, path_vpn->sub_type);
960035b2
PZ
1269 }
1270
ddb5b488 1271 if (debug)
40381db7 1272 zlog_debug("%s: start (path_vpn=%p)", __func__, path_vpn);
ddb5b488 1273
40381db7 1274 if (!path_vpn->net) {
56c2c080 1275#if ENABLE_BGP_VNC
40381db7
DS
1276 /* BGP_ROUTE_RFP routes do not have path_vpn->net set (yet) */
1277 if (path_vpn->type == ZEBRA_ROUTE_BGP
1278 && path_vpn->sub_type == BGP_ROUTE_RFP) {
1b3510a0
PZ
1279
1280 return;
1281 }
56c2c080 1282#endif
1b3510a0 1283 if (debug)
40381db7
DS
1284 zlog_debug(
1285 "%s: path_vpn->net unexpectedly NULL, no prefix, bailing",
1b3510a0
PZ
1286 __func__);
1287 return;
1288 }
1289
40381db7 1290 p = &path_vpn->net->p;
1b3510a0 1291 afi = family2afi(p->family);
ddb5b488
PZ
1292
1293 /* Loop over VRFs */
1294 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
b9c7bc5a 1295 if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
ddb5b488
PZ
1296 if (debug)
1297 zlog_debug("%s: skipping: %s", __func__,
1298 debugmsg);
1299 continue;
1300 }
1301
1302 /* Check for intersection of route targets */
1303 if (!ecom_intersect(bgp->vpn_policy[afi]
1304 .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
40381db7 1305 path_vpn->attr->ecommunity)) {
ddb5b488
PZ
1306
1307 continue;
1308 }
1309
1310 if (debug)
1311 zlog_debug("%s: withdrawing from vrf %s", __func__,
960035b2 1312 bgp->name_pretty);
ddb5b488
PZ
1313
1314 bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6f94b685
DS
1315
1316 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
1317 bpi = bpi->next) {
40381db7
DS
1318 if (bpi->extra
1319 && (struct bgp_path_info *)bpi->extra->parent
1320 == path_vpn) {
ddb5b488
PZ
1321 break;
1322 }
1323 }
1324
40381db7 1325 if (bpi) {
ddb5b488 1326 if (debug)
40381db7
DS
1327 zlog_debug("%s: deleting bpi %p", __func__,
1328 bpi);
1329 bgp_aggregate_decrement(bgp, p, bpi, afi, safi);
1330 bgp_path_info_delete(bn, bpi);
ddb5b488
PZ
1331 bgp_process(bgp, bn, afi, safi);
1332 }
1333 bgp_unlock_node(bn);
1334 }
1335}
1336
1337void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
1338 afi_t afi)
1339{
1340 struct bgp_node *bn;
40381db7 1341 struct bgp_path_info *bpi;
ddb5b488
PZ
1342 safi_t safi = SAFI_UNICAST;
1343 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
ddb5b488
PZ
1344
1345 if (debug)
1346 zlog_debug("%s: entry", __func__);
1347 /*
40381db7 1348 * Walk vrf table, delete bpi with bgp_orig in a different vrf
ddb5b488
PZ
1349 */
1350 for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
1351 bn = bgp_route_next(bn)) {
1352
6f94b685
DS
1353 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
1354 bpi = bpi->next) {
40381db7 1355 if (bpi->extra && bpi->extra->bgp_orig != bgp_vrf) {
ddb5b488
PZ
1356
1357 /* delete route */
40381db7 1358 bgp_aggregate_decrement(bgp_vrf, &bn->p, bpi,
ddb5b488 1359 afi, safi);
40381db7 1360 bgp_path_info_delete(bn, bpi);
ddb5b488
PZ
1361 bgp_process(bgp_vrf, bn, afi, safi);
1362 }
1363 }
1364 }
1365}
1366
1367void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
1368 struct bgp *bgp_vpn, /* from */
1369 afi_t afi)
1370{
1371 struct prefix_rd prd;
1372 struct bgp_node *prn;
1373 safi_t safi = SAFI_MPLS_VPN;
1374
3bd70bf8 1375 assert(bgp_vpn);
73aed584 1376
ddb5b488
PZ
1377 /*
1378 * Walk vpn table
1379 */
1380 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
1381 prn = bgp_route_next(prn)) {
1382
1383 struct bgp_table *table;
1384 struct bgp_node *bn;
40381db7 1385 struct bgp_path_info *bpi;
ddb5b488
PZ
1386
1387 memset(&prd, 0, sizeof(prd));
1388 prd.family = AF_UNSPEC;
1389 prd.prefixlen = 64;
1390 memcpy(prd.val, prn->p.u.val, 8);
1391
1392 /* This is the per-RD table of prefixes */
67009e22 1393 table = bgp_node_get_bgp_table_info(prn);
ddb5b488
PZ
1394
1395 if (!table)
1396 continue;
1397
1398 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
1399
6f94b685
DS
1400 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
1401 bpi = bpi->next) {
ddb5b488 1402
40381db7
DS
1403 if (bpi->extra
1404 && bpi->extra->bgp_orig == bgp_vrf)
ddb5b488
PZ
1405 continue;
1406
1407 vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
40381db7 1408 bpi);
ddb5b488
PZ
1409 }
1410 }
1411 }
1412}
1413
d92a55df
PZ
1414/*
1415 * This function is called for definition/deletion/change to a route-map
1416 */
ddb5b488
PZ
1417static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
1418{
1419 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1420 afi_t afi;
1421 struct route_map *rmap;
1422
1423 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1424 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
1425
1426 return;
1427 }
1428
1429 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
1430
1431 for (afi = 0; afi < AFI_MAX; ++afi) {
1432
d92a55df
PZ
1433 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
1434 && !strcmp(rmap_name,
ddb5b488
PZ
1435 bgp->vpn_policy[afi]
1436 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
1437
1438 if (debug)
1439 zlog_debug(
1440 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1441 __func__, rmap_name, bgp->as,
1442 afi2str(afi));
1443
1444 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1445 bgp_get_default(), bgp);
1446 if (debug)
1447 zlog_debug("%s: after vpn_leak_prechange",
1448 __func__);
1449
d92a55df
PZ
1450 /* in case of definition/deletion */
1451 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN] =
1452 rmap;
ddb5b488
PZ
1453
1454 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1455 bgp_get_default(), bgp);
d92a55df 1456
ddb5b488
PZ
1457 if (debug)
1458 zlog_debug("%s: after vpn_leak_postchange",
1459 __func__);
1460 }
1461
d92a55df
PZ
1462 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]
1463 && !strcmp(rmap_name,
1464 bgp->vpn_policy[afi]
1465 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN])) {
b9c7bc5a
PZ
1466
1467 if (debug) {
1468 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
ddb5b488
PZ
1469 __func__, rmap_name, bgp->as,
1470 afi2str(afi));
b9c7bc5a 1471 }
ddb5b488
PZ
1472
1473 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1474 bgp_get_default(), bgp);
1475
d92a55df
PZ
1476 /* in case of definition/deletion */
1477 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
1478 rmap;
ddb5b488
PZ
1479
1480 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1481 bgp_get_default(), bgp);
1482 }
1483 }
1484}
1485
1486void vpn_policy_routemap_event(const char *rmap_name)
1487{
1488 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1489 struct listnode *mnode, *mnnode;
1490 struct bgp *bgp;
1491
1492 if (debug)
1493 zlog_debug("%s: entry", __func__);
1494
1495 if (bm->bgp == NULL) /* may be called during cleanup */
1496 return;
1497
1498 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
1499 vpn_policy_routemap_update(bgp, rmap_name);
1500}
1501
1d4e8b0d 1502void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 1503 afi_t afi, safi_t safi)
1504{
1505 const char *export_name;
1506 vpn_policy_direction_t idir, edir;
1507 char *vname;
1508 char buf[1000];
1509 struct ecommunity *ecom;
1510 bool first_export = false;
1511
5742e42b 1512 export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
44338987 1513 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1514 edir = BGP_VPN_POLICY_DIR_TOVPN;
1515
1d4e8b0d
DS
1516 /*
1517 * Cross-ref both VRFs. Also, note if this is the first time
44338987 1518 * any VRF is importing from "import_vrf".
1519 */
a8dadcf6 1520 vname = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
5742e42b 1521 : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME));
a8dadcf6 1522
1d4e8b0d 1523 listnode_add(to_bgp->vpn_policy[afi].import_vrf, vname);
44338987 1524
1d4e8b0d 1525 if (!listcount(from_bgp->vpn_policy[afi].export_vrf))
44338987 1526 first_export = true;
1527 vname = XSTRDUP(MTYPE_TMP, export_name);
1d4e8b0d 1528 listnode_add(from_bgp->vpn_policy[afi].export_vrf, vname);
44338987 1529
1530 /* Update import RT for current VRF using export RT of the VRF we're
1531 * importing from. First though, make sure "import_vrf" has that
1532 * set.
1533 */
1534 if (first_export) {
1d4e8b0d
DS
1535 form_auto_rd(from_bgp->router_id, from_bgp->vrf_rd_id,
1536 &from_bgp->vrf_prd_auto);
1537 from_bgp->vpn_policy[afi].tovpn_rd = from_bgp->vrf_prd_auto;
1538 SET_FLAG(from_bgp->vpn_policy[afi].flags,
44338987 1539 BGP_VPN_POLICY_TOVPN_RD_SET);
1d4e8b0d 1540 prefix_rd2str(&from_bgp->vpn_policy[afi].tovpn_rd,
44338987 1541 buf, sizeof(buf));
1d4e8b0d 1542 from_bgp->vpn_policy[afi].rtlist[edir] =
44338987 1543 ecommunity_str2com(buf, ECOMMUNITY_ROUTE_TARGET, 0);
1d4e8b0d 1544 SET_FLAG(from_bgp->af_flags[afi][safi],
44338987 1545 BGP_CONFIG_VRF_TO_VRF_EXPORT);
13b7e7f0
DS
1546 from_bgp->vpn_policy[afi].tovpn_label =
1547 BGP_PREVENT_VRF_2_VRF_LEAK;
44338987 1548 }
1d4e8b0d
DS
1549 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
1550 if (to_bgp->vpn_policy[afi].rtlist[idir])
1551 to_bgp->vpn_policy[afi].rtlist[idir] =
1552 ecommunity_merge(to_bgp->vpn_policy[afi]
44338987 1553 .rtlist[idir], ecom);
1554 else
1d4e8b0d
DS
1555 to_bgp->vpn_policy[afi].rtlist[idir] = ecommunity_dup(ecom);
1556 SET_FLAG(to_bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT);
44338987 1557
1558 /* Does "import_vrf" first need to export its routes or that
1559 * is already done and we just need to import those routes
1560 * from the global table?
1561 */
1562 if (first_export)
1d4e8b0d 1563 vpn_leak_postchange(edir, afi, bgp_get_default(), from_bgp);
44338987 1564 else
1d4e8b0d 1565 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
44338987 1566}
1567
1d4e8b0d 1568void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 1569 afi_t afi, safi_t safi)
1570{
a8dadcf6 1571 const char *export_name, *tmp_name;
44338987 1572 vpn_policy_direction_t idir, edir;
1573 char *vname;
1574 struct ecommunity *ecom;
1575 struct listnode *node;
1576
5742e42b
DS
1577 export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
1578 tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
44338987 1579 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1580 edir = BGP_VPN_POLICY_DIR_TOVPN;
1581
1582 /* Were we importing from "import_vrf"? */
1d4e8b0d
DS
1583 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf, node,
1584 vname)) {
a8dadcf6 1585 if (strcmp(vname, tmp_name) == 0)
020a3f60 1586 break;
44338987 1587 }
1d4e8b0d
DS
1588
1589 /*
1590 * We do not check in the cli if the passed in bgp
1591 * instance is actually imported into us before
1592 * we call this function. As such if we do not
1593 * find this in the import_vrf list than
1594 * we just need to return safely.
1595 */
44338987 1596 if (!vname)
1597 return;
1598
1599 /* Remove "import_vrf" from our import list. */
1d4e8b0d 1600 listnode_delete(to_bgp->vpn_policy[afi].import_vrf, vname);
44338987 1601 XFREE(MTYPE_TMP, vname);
1602
1603 /* Remove routes imported from "import_vrf". */
1604 /* TODO: In the current logic, we have to first remove all
1605 * imported routes and then (if needed) import back routes
1606 */
1d4e8b0d 1607 vpn_leak_prechange(idir, afi, bgp_get_default(), to_bgp);
44338987 1608
1d4e8b0d
DS
1609 if (to_bgp->vpn_policy[afi].import_vrf->count == 0) {
1610 UNSET_FLAG(to_bgp->af_flags[afi][safi],
44338987 1611 BGP_CONFIG_VRF_TO_VRF_IMPORT);
1d4e8b0d 1612 ecommunity_free(&to_bgp->vpn_policy[afi].rtlist[idir]);
44338987 1613 } else {
1d4e8b0d
DS
1614 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
1615 ecommunity_del_val(to_bgp->vpn_policy[afi].rtlist[idir],
44338987 1616 (struct ecommunity_val *)ecom->val);
1d4e8b0d 1617 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
44338987 1618 }
1619
89d59347
DS
1620 /*
1621 * What?
1622 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
1623 * below is checking for NULL that export_vrf can be
1624 * NULL, consequently it is complaining( like a cabbage )
1625 * that we could dereference and crash in the listcount(..)
1626 * check below.
1627 * So make it happy, under protest, with liberty and justice
1628 * for all.
1629 */
1d4e8b0d 1630 assert(from_bgp->vpn_policy[afi].export_vrf);
89d59347 1631
44338987 1632 /* Remove us from "import_vrf's" export list. If no other VRF
1633 * is importing from "import_vrf", cleanup appropriately.
1634 */
1d4e8b0d 1635 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
44338987 1636 node, vname)) {
1637 if (strcmp(vname, export_name) == 0)
1638 break;
1639 }
1640
1d4e8b0d
DS
1641 /*
1642 * If we have gotten to this point then the vname must
1643 * exist. If not, we are in a world of trouble and
1644 * have slag sitting around.
1645 *
1646 * import_vrf and export_vrf must match in having
1647 * the in/out names as appropriate.
1648 */
1649 assert(vname);
1650
1651 listnode_delete(from_bgp->vpn_policy[afi].export_vrf, vname);
44338987 1652 XFREE(MTYPE_TMP, vname);
1653
1d4e8b0d
DS
1654 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
1655 vpn_leak_prechange(edir, afi, bgp_get_default(), from_bgp);
1656 ecommunity_free(&from_bgp->vpn_policy[afi].rtlist[edir]);
1657 UNSET_FLAG(from_bgp->af_flags[afi][safi],
44338987 1658 BGP_CONFIG_VRF_TO_VRF_EXPORT);
1d4e8b0d 1659 memset(&from_bgp->vpn_policy[afi].tovpn_rd, 0,
44338987 1660 sizeof(struct prefix_rd));
1d4e8b0d 1661 UNSET_FLAG(from_bgp->vpn_policy[afi].flags,
44338987 1662 BGP_VPN_POLICY_TOVPN_RD_SET);
13b7e7f0
DS
1663 from_bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE;
1664
44338987 1665 }
1666}
1667
718e3744 1668/* For testing purpose, static route of MPLS-VPN. */
1669DEFUN (vpnv4_network,
1670 vpnv4_network_cmd,
d114b977 1671 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1672 "Specify a network to announce via BGP\n"
0c7b1b01 1673 "IPv4 prefix\n"
718e3744 1674 "Specify Route Distinguisher\n"
1675 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1676 "VPN NLRI label (tag)\n"
1677 "VPN NLRI label (tag)\n"
1678 "Label value\n")
718e3744 1679{
d62a17ae 1680 int idx_ipv4_prefixlen = 1;
1681 int idx_ext_community = 3;
1682 int idx_label = 5;
1683 return bgp_static_set_safi(
1684 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1685 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
1686 NULL, NULL, NULL, NULL);
137446f9
LB
1687}
1688
1689DEFUN (vpnv4_network_route_map,
1690 vpnv4_network_route_map_cmd,
d114b977 1691 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
137446f9 1692 "Specify a network to announce via BGP\n"
0c7b1b01 1693 "IPv4 prefix\n"
137446f9
LB
1694 "Specify Route Distinguisher\n"
1695 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1696 "VPN NLRI label (tag)\n"
1697 "VPN NLRI label (tag)\n"
1698 "Label value\n"
137446f9
LB
1699 "route map\n"
1700 "route map name\n")
1701{
d62a17ae 1702 int idx_ipv4_prefixlen = 1;
1703 int idx_ext_community = 3;
1704 int idx_label = 5;
1705 int idx_word_2 = 7;
1706 return bgp_static_set_safi(
1707 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1708 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1709 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
718e3744 1710}
1711
1712/* For testing purpose, static route of MPLS-VPN. */
1713DEFUN (no_vpnv4_network,
1714 no_vpnv4_network_cmd,
d114b977 1715 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1716 NO_STR
1717 "Specify a network to announce via BGP\n"
0c7b1b01 1718 "IPv4 prefix\n"
718e3744 1719 "Specify Route Distinguisher\n"
1720 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1721 "VPN NLRI label (tag)\n"
1722 "VPN NLRI label (tag)\n"
1723 "Label value\n")
718e3744 1724{
d62a17ae 1725 int idx_ipv4_prefixlen = 2;
1726 int idx_ext_community = 4;
1727 int idx_label = 6;
1728 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
1729 argv[idx_ipv4_prefixlen]->arg,
1730 argv[idx_ext_community]->arg,
1731 argv[idx_label]->arg, 0, NULL, NULL, NULL);
718e3744 1732}
1733
c286be96
LX
1734DEFUN (vpnv6_network,
1735 vpnv6_network_cmd,
d114b977 1736 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
c286be96
LX
1737 "Specify a network to announce via BGP\n"
1738 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1739 "Specify Route Distinguisher\n"
1740 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1741 "VPN NLRI label (tag)\n"
1742 "VPN NLRI label (tag)\n"
1743 "Label value\n"
11daee81
DS
1744 "route map\n"
1745 "route map name\n")
c286be96 1746{
d62a17ae 1747 int idx_ipv6_prefix = 1;
1748 int idx_ext_community = 3;
1749 int idx_label = 5;
1750 int idx_word_2 = 7;
1751 if (argc == 8)
1752 return bgp_static_set_safi(
1753 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1754 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1755 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
1756 else
1757 return bgp_static_set_safi(
1758 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1759 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1760 NULL, 0, NULL, NULL, NULL, NULL);
c286be96
LX
1761}
1762
1763/* For testing purpose, static route of MPLS-VPN. */
1764DEFUN (no_vpnv6_network,
1765 no_vpnv6_network_cmd,
d114b977 1766 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
c286be96
LX
1767 NO_STR
1768 "Specify a network to announce via BGP\n"
1769 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1770 "Specify Route Distinguisher\n"
1771 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1772 "VPN NLRI label (tag)\n"
1773 "VPN NLRI label (tag)\n"
1774 "Label value\n")
c286be96 1775{
d62a17ae 1776 int idx_ipv6_prefix = 2;
1777 int idx_ext_community = 4;
1778 int idx_label = 6;
1779 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
1780 argv[idx_ipv6_prefix]->arg,
1781 argv[idx_ext_community]->arg,
1782 argv[idx_label]->arg, 0, NULL, NULL, NULL);
c286be96
LX
1783}
1784
d62a17ae 1785int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
1786 enum bgp_show_type type, void *output_arg, int tags,
9f049418 1787 bool use_json)
718e3744 1788{
d62a17ae 1789 struct bgp *bgp;
1790 struct bgp_table *table;
d62a17ae 1791
1792 bgp = bgp_get_default();
1793 if (bgp == NULL) {
1794 if (!use_json)
1795 vty_out(vty, "No BGP process is configured\n");
16307668
RW
1796 else
1797 vty_out(vty, "{}\n");
d62a17ae 1798 return CMD_WARNING;
1799 }
1ae44dfc 1800 table = bgp->rib[afi][SAFI_MPLS_VPN];
a4d82a8a
PZ
1801 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
1802 output_arg, use_json);
718e3744 1803}
1804
4f280b15
LB
1805DEFUN (show_bgp_ip_vpn_all_rd,
1806 show_bgp_ip_vpn_all_rd_cmd,
d114b977 1807 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
e3e29b32
LB
1808 SHOW_STR
1809 BGP_STR
05e588f4 1810 BGP_VPNVX_HELP_STR
e3e29b32 1811 "Display VPN NLRI specific information\n"
af8528fa 1812 "Display VPN NLRI specific information\n"
e3e29b32
LB
1813 "Display information for a route distinguisher\n"
1814 "VPN Route Distinguisher\n"
1815 JSON_STR)
1816{
d62a17ae 1817 int ret;
1818 struct prefix_rd prd;
1819 afi_t afi;
1820 int idx = 0;
1821
1822 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
3d7c4cd7 1823 if (argv_find(argv, argc, "rd", &idx)) {
a4d82a8a 1824 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
d62a17ae 1825 if (!ret) {
1826 vty_out(vty,
1827 "%% Malformed Route Distinguisher\n");
1828 return CMD_WARNING;
1829 }
1830 return bgp_show_mpls_vpn(vty, afi, &prd,
1831 bgp_show_type_normal, NULL, 0,
1832 use_json(argc, argv));
1833 } else {
1834 return bgp_show_mpls_vpn(vty, afi, NULL,
1835 bgp_show_type_normal, NULL, 0,
1836 use_json(argc, argv));
1837 }
1838 }
1839 return CMD_SUCCESS;
718e3744 1840}
1841
af8528fa
LB
1842ALIAS(show_bgp_ip_vpn_all_rd,
1843 show_bgp_ip_vpn_rd_cmd,
1844 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1845 SHOW_STR
1846 BGP_STR
1847 BGP_VPNVX_HELP_STR
1848 "Display VPN NLRI specific information\n"
1849 "Display information for a route distinguisher\n"
1850 "VPN Route Distinguisher\n"
1851 JSON_STR)
1852
1853#ifdef KEEP_OLD_VPN_COMMANDS
3f227172
PG
1854DEFUN (show_ip_bgp_vpn_rd,
1855 show_ip_bgp_vpn_rd_cmd,
af8528fa 1856 "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
718e3744 1857 SHOW_STR
1858 IP_STR
1859 BGP_STR
4f280b15 1860 BGP_AFI_HELP_STR
3517059b 1861 "Address Family modifier\n"
718e3744 1862 "Display information for a route distinguisher\n"
1863 "VPN Route Distinguisher\n")
1864{
d62a17ae 1865 int idx_ext_community = argc - 1;
1866 int ret;
1867 struct prefix_rd prd;
1868 afi_t afi;
1869 int idx = 0;
1870
1871 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1872 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1873 if (!ret) {
1874 vty_out(vty, "%% Malformed Route Distinguisher\n");
1875 return CMD_WARNING;
1876 }
1877 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1878 NULL, 0, 0);
1879 }
1880 return CMD_SUCCESS;
1881}
718e3744 1882
4f280b15
LB
1883DEFUN (show_ip_bgp_vpn_all,
1884 show_ip_bgp_vpn_all_cmd,
1885 "show [ip] bgp <vpnv4|vpnv6>",
1886 SHOW_STR
1887 IP_STR
1888 BGP_STR
1889 BGP_VPNVX_HELP_STR)
1890{
d62a17ae 1891 afi_t afi;
1892 int idx = 0;
4f280b15 1893
d62a17ae 1894 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1895 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1896 NULL, 0, 0);
1897 return CMD_SUCCESS;
4f280b15
LB
1898}
1899
3f227172
PG
1900DEFUN (show_ip_bgp_vpn_all_tags,
1901 show_ip_bgp_vpn_all_tags_cmd,
1902 "show [ip] bgp <vpnv4|vpnv6> all tags",
718e3744 1903 SHOW_STR
1904 IP_STR
1905 BGP_STR
3f227172
PG
1906 BGP_VPNVX_HELP_STR
1907 "Display information about all VPNv4/VPNV6 NLRIs\n"
718e3744 1908 "Display BGP tags for prefixes\n")
1909{
d62a17ae 1910 afi_t afi;
1911 int idx = 0;
3f227172 1912
d62a17ae 1913 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1914 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1915 NULL, 1, 0);
1916 return CMD_SUCCESS;
718e3744 1917}
1918
3f227172
PG
1919DEFUN (show_ip_bgp_vpn_rd_tags,
1920 show_ip_bgp_vpn_rd_tags_cmd,
d114b977 1921 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
718e3744 1922 SHOW_STR
1923 IP_STR
1924 BGP_STR
3f227172 1925 BGP_VPNVX_HELP_STR
718e3744 1926 "Display information for a route distinguisher\n"
1927 "VPN Route Distinguisher\n"
1928 "Display BGP tags for prefixes\n")
1929{
d62a17ae 1930 int idx_ext_community = 5;
1931 int ret;
1932 struct prefix_rd prd;
1933 afi_t afi;
1934 int idx = 0;
1935
1936 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1937 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1938 if (!ret) {
1939 vty_out(vty, "%% Malformed Route Distinguisher\n");
1940 return CMD_WARNING;
1941 }
1942 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1943 NULL, 1, 0);
1944 }
1945 return CMD_SUCCESS;
718e3744 1946}
1947
3f227172
PG
1948DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
1949 show_ip_bgp_vpn_all_neighbor_routes_cmd,
1950 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
718e3744 1951 SHOW_STR
1952 IP_STR
1953 BGP_STR
3f227172
PG
1954 BGP_VPNVX_HELP_STR
1955 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 1956 "Detailed information on TCP and BGP neighbor connections\n"
1957 "Neighbor to display information about\n"
856ca177 1958 "Display routes learned from neighbor\n"
9973d184 1959 JSON_STR)
718e3744 1960{
d62a17ae 1961 int idx_ipv4 = 6;
1962 union sockunion su;
1963 struct peer *peer;
1964 int ret;
9f049418 1965 bool uj = use_json(argc, argv);
d62a17ae 1966 afi_t afi;
1967 int idx = 0;
1968
1969 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1970 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1971 if (ret < 0) {
1972 if (uj) {
1973 json_object *json_no = NULL;
1974 json_no = json_object_new_object();
1975 json_object_string_add(json_no, "warning",
1976 "Malformed address");
1977 vty_out(vty, "%s\n",
1978 json_object_to_json_string(json_no));
1979 json_object_free(json_no);
1980 } else
1981 vty_out(vty, "Malformed address: %s\n",
1982 argv[idx_ipv4]->arg);
1983 return CMD_WARNING;
1984 }
1985
1986 peer = peer_lookup(NULL, &su);
1987 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1988 if (uj) {
1989 json_object *json_no = NULL;
1990 json_no = json_object_new_object();
1991 json_object_string_add(
1992 json_no, "warning",
1993 "No such neighbor or address family");
1994 vty_out(vty, "%s\n",
1995 json_object_to_json_string(json_no));
1996 json_object_free(json_no);
1997 } else
1998 vty_out(vty,
1999 "%% No such neighbor or address family\n");
2000 return CMD_WARNING;
2001 }
2002
2003 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
2004 &su, 0, uj);
2005 }
2006 return CMD_SUCCESS;
718e3744 2007}
2008
3f227172
PG
2009DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
2010 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
d114b977 2011 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
718e3744 2012 SHOW_STR
2013 IP_STR
2014 BGP_STR
3f227172 2015 BGP_VPNVX_HELP_STR
718e3744 2016 "Display information for a route distinguisher\n"
2017 "VPN Route Distinguisher\n"
2018 "Detailed information on TCP and BGP neighbor connections\n"
2019 "Neighbor to display information about\n"
856ca177 2020 "Display routes learned from neighbor\n"
9973d184 2021 JSON_STR)
718e3744 2022{
d62a17ae 2023 int idx_ext_community = 5;
2024 int idx_ipv4 = 7;
2025 int ret;
2026 union sockunion su;
2027 struct peer *peer;
2028 struct prefix_rd prd;
9f049418 2029 bool uj = use_json(argc, argv);
d62a17ae 2030 afi_t afi;
2031 int idx = 0;
2032
2033 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2034 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2035 if (!ret) {
2036 if (uj) {
2037 json_object *json_no = NULL;
2038 json_no = json_object_new_object();
2039 json_object_string_add(
2040 json_no, "warning",
2041 "Malformed Route Distinguisher");
2042 vty_out(vty, "%s\n",
2043 json_object_to_json_string(json_no));
2044 json_object_free(json_no);
2045 } else
2046 vty_out(vty,
2047 "%% Malformed Route Distinguisher\n");
2048 return CMD_WARNING;
2049 }
2050
2051 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2052 if (ret < 0) {
2053 if (uj) {
2054 json_object *json_no = NULL;
2055 json_no = json_object_new_object();
2056 json_object_string_add(json_no, "warning",
2057 "Malformed address");
2058 vty_out(vty, "%s\n",
2059 json_object_to_json_string(json_no));
2060 json_object_free(json_no);
2061 } else
2062 vty_out(vty, "Malformed address: %s\n",
2063 argv[idx_ext_community]->arg);
2064 return CMD_WARNING;
2065 }
2066
2067 peer = peer_lookup(NULL, &su);
2068 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2069 if (uj) {
2070 json_object *json_no = NULL;
2071 json_no = json_object_new_object();
2072 json_object_string_add(
2073 json_no, "warning",
2074 "No such neighbor or address family");
2075 vty_out(vty, "%s\n",
2076 json_object_to_json_string(json_no));
2077 json_object_free(json_no);
2078 } else
2079 vty_out(vty,
2080 "%% No such neighbor or address family\n");
2081 return CMD_WARNING;
2082 }
2083
2084 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_neighbor,
2085 &su, 0, uj);
2086 }
2087 return CMD_SUCCESS;
718e3744 2088}
2089
3f227172
PG
2090DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
2091 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
2092 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
718e3744 2093 SHOW_STR
2094 IP_STR
2095 BGP_STR
3f227172
PG
2096 BGP_VPNVX_HELP_STR
2097 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 2098 "Detailed information on TCP and BGP neighbor connections\n"
2099 "Neighbor to display information about\n"
856ca177 2100 "Display the routes advertised to a BGP neighbor\n"
9973d184 2101 JSON_STR)
718e3744 2102{
d62a17ae 2103 int idx_ipv4 = 6;
2104 int ret;
2105 struct peer *peer;
2106 union sockunion su;
9f049418 2107 bool uj = use_json(argc, argv);
d62a17ae 2108 afi_t afi;
2109 int idx = 0;
2110
2111 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2112 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2113 if (ret < 0) {
2114 if (uj) {
2115 json_object *json_no = NULL;
2116 json_no = json_object_new_object();
2117 json_object_string_add(json_no, "warning",
2118 "Malformed address");
2119 vty_out(vty, "%s\n",
2120 json_object_to_json_string(json_no));
2121 json_object_free(json_no);
2122 } else
2123 vty_out(vty, "Malformed address: %s\n",
2124 argv[idx_ipv4]->arg);
2125 return CMD_WARNING;
2126 }
2127 peer = peer_lookup(NULL, &su);
2128 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2129 if (uj) {
2130 json_object *json_no = NULL;
2131 json_no = json_object_new_object();
2132 json_object_string_add(
2133 json_no, "warning",
2134 "No such neighbor or address family");
2135 vty_out(vty, "%s\n",
2136 json_object_to_json_string(json_no));
2137 json_object_free(json_no);
2138 } else
2139 vty_out(vty,
2140 "%% No such neighbor or address family\n");
2141 return CMD_WARNING;
2142 }
2143 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
2144 SAFI_MPLS_VPN, uj);
2145 }
2146 return CMD_SUCCESS;
718e3744 2147}
2148
3f227172
PG
2149DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
2150 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
d114b977 2151 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
718e3744 2152 SHOW_STR
2153 IP_STR
2154 BGP_STR
3f227172 2155 BGP_VPNVX_HELP_STR
718e3744 2156 "Display information for a route distinguisher\n"
2157 "VPN Route Distinguisher\n"
2158 "Detailed information on TCP and BGP neighbor connections\n"
2159 "Neighbor to display information about\n"
856ca177 2160 "Display the routes advertised to a BGP neighbor\n"
9973d184 2161 JSON_STR)
718e3744 2162{
d62a17ae 2163 int idx_ext_community = 5;
2164 int idx_ipv4 = 7;
2165 int ret;
2166 struct peer *peer;
2167 struct prefix_rd prd;
2168 union sockunion su;
9f049418 2169 bool uj = use_json(argc, argv);
d62a17ae 2170 afi_t afi;
2171 int idx = 0;
2172
2173 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2174 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2175 if (ret < 0) {
2176 if (uj) {
2177 json_object *json_no = NULL;
2178 json_no = json_object_new_object();
2179 json_object_string_add(json_no, "warning",
2180 "Malformed address");
2181 vty_out(vty, "%s\n",
2182 json_object_to_json_string(json_no));
2183 json_object_free(json_no);
2184 } else
2185 vty_out(vty, "Malformed address: %s\n",
2186 argv[idx_ext_community]->arg);
2187 return CMD_WARNING;
2188 }
2189 peer = peer_lookup(NULL, &su);
2190 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2191 if (uj) {
2192 json_object *json_no = NULL;
2193 json_no = json_object_new_object();
2194 json_object_string_add(
2195 json_no, "warning",
2196 "No such neighbor or address family");
2197 vty_out(vty, "%s\n",
2198 json_object_to_json_string(json_no));
2199 json_object_free(json_no);
2200 } else
2201 vty_out(vty,
2202 "%% No such neighbor or address family\n");
2203 return CMD_WARNING;
2204 }
2205
2206 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2207 if (!ret) {
2208 if (uj) {
2209 json_object *json_no = NULL;
2210 json_no = json_object_new_object();
2211 json_object_string_add(
2212 json_no, "warning",
2213 "Malformed Route Distinguisher");
2214 vty_out(vty, "%s\n",
2215 json_object_to_json_string(json_no));
2216 json_object_free(json_no);
2217 } else
2218 vty_out(vty,
2219 "%% Malformed Route Distinguisher\n");
2220 return CMD_WARNING;
2221 }
2222
2223 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
2224 SAFI_MPLS_VPN, uj);
2225 }
2226 return CMD_SUCCESS;
718e3744 2227}
d6902373 2228#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2229
d62a17ae 2230void bgp_mplsvpn_init(void)
718e3744 2231{
d62a17ae 2232 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
2233 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
2234 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
718e3744 2235
d62a17ae 2236 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
2237 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
c286be96 2238
d62a17ae 2239 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
af8528fa 2240 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
d6902373 2241#ifdef KEEP_OLD_VPN_COMMANDS
af8528fa 2242 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
d62a17ae 2243 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
2244 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
2245 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
2246 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
2247 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
2248 install_element(VIEW_NODE,
2249 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
2250 install_element(VIEW_NODE,
2251 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
d6902373 2252#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2253}
301ad80a
PG
2254
2255vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
2256{
2257 struct listnode *mnode, *mnnode;
2258 struct bgp *bgp;
2259
2260 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2261 struct ecommunity *ec;
2262
2263 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2264 continue;
2265
2266 ec = bgp->vpn_policy[AFI_IP].import_redirect_rtlist;
2267
2268 if (ecom_intersect(ec, eckey))
2269 return bgp->vrf_id;
2270 }
2271 return VRF_UNKNOWN;
2272}
3bd70bf8
PZ
2273
2274/*
2275 * The purpose of this function is to process leaks that were deferred
2276 * from earlier per-vrf configuration due to not-yet-existing default
2277 * vrf, in other words, configuration such as:
2278 *
2279 * router bgp MMM vrf FOO
2280 * address-family ipv4 unicast
2281 * rd vpn export 1:1
2282 * exit-address-family
2283 *
2284 * router bgp NNN
2285 * ...
2286 *
2287 * This function gets called when the default instance ("router bgp NNN")
2288 * is created.
2289 */
2290void vpn_leak_postchange_all(void)
2291{
2292 struct listnode *next;
2293 struct bgp *bgp;
2294 struct bgp *bgp_default = bgp_get_default();
2295
2296 assert(bgp_default);
2297
2298 /* First, do any exporting from VRFs to the single VPN RIB */
2299 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
2300
2301 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2302 continue;
2303
2304 vpn_leak_postchange(
2305 BGP_VPN_POLICY_DIR_TOVPN,
2306 AFI_IP,
2307 bgp_default,
2308 bgp);
2309
2310 vpn_leak_postchange(
2311 BGP_VPN_POLICY_DIR_TOVPN,
2312 AFI_IP6,
2313 bgp_default,
2314 bgp);
2315 }
2316
2317 /* Now, do any importing to VRFs from the single VPN RIB */
2318 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
2319
2320 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2321 continue;
2322
2323 vpn_leak_postchange(
2324 BGP_VPN_POLICY_DIR_FROMVPN,
2325 AFI_IP,
2326 bgp_default,
2327 bgp);
2328
2329 vpn_leak_postchange(
2330 BGP_VPN_POLICY_DIR_FROMVPN,
2331 AFI_IP6,
2332 bgp_default,
2333 bgp);
2334 }
2335}