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