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