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