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