]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.c
Merge pull request #2043 from donaldsharp/v6_shenanigans
[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"
718e3744 36#include "bgpd/bgp_table.h"
37#include "bgpd/bgp_route.h"
38#include "bgpd/bgp_attr.h"
9bedbb1e 39#include "bgpd/bgp_label.h"
718e3744 40#include "bgpd/bgp_mplsvpn.h"
48a5452b 41#include "bgpd/bgp_packet.h"
3f227172 42#include "bgpd/bgp_vty.h"
784d3a42 43#include "bgpd/bgp_vpn.h"
ddb5b488
PZ
44#include "bgpd/bgp_ecommunity.h"
45#include "bgpd/bgp_zebra.h"
46#include "bgpd/bgp_nexthop.h"
960035b2 47#include "bgpd/bgp_nht.h"
718e3744 48
65efcfce 49#if ENABLE_BGP_VNC
f8b6f499 50#include "bgpd/rfapi/rfapi_backend.h"
65efcfce
LB
51#endif
52
ddb5b488
PZ
53/*
54 * Definitions and external declarations.
55 */
56extern struct zclient *zclient;
57
d62a17ae 58extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
59 int *index, afi_t *afi)
3f227172 60{
d62a17ae 61 int ret = 0;
62 if (argv_find(argv, argc, "vpnv4", index)) {
63 ret = 1;
64 if (afi)
65 *afi = AFI_IP;
66 } else if (argv_find(argv, argc, "vpnv6", index)) {
67 ret = 1;
68 if (afi)
69 *afi = AFI_IP6;
70 }
71 return ret;
3f227172
PG
72}
73
d7c0a89a 74uint32_t decode_label(mpls_label_t *label_pnt)
718e3744 75{
d7c0a89a
QY
76 uint32_t l;
77 uint8_t *pnt = (uint8_t *)label_pnt;
718e3744 78
d7c0a89a
QY
79 l = ((uint32_t)*pnt++ << 12);
80 l |= (uint32_t)*pnt++ << 4;
81 l |= (uint32_t)((*pnt & 0xf0) >> 4);
d62a17ae 82 return l;
718e3744 83}
84
d62a17ae 85void encode_label(mpls_label_t label, mpls_label_t *label_pnt)
65efcfce 86{
d7c0a89a 87 uint8_t *pnt = (uint8_t *)label_pnt;
d62a17ae 88 if (pnt == NULL)
89 return;
90 *pnt++ = (label >> 12) & 0xff;
91 *pnt++ = (label >> 4) & 0xff;
92 *pnt++ = ((label << 4) + 1) & 0xff; /* S=1 */
65efcfce
LB
93}
94
d62a17ae 95int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
96 struct bgp_nlri *packet)
718e3744 97{
d7c0a89a
QY
98 uint8_t *pnt;
99 uint8_t *lim;
d62a17ae 100 struct prefix p;
101 int psize = 0;
102 int prefixlen;
d7c0a89a 103 uint16_t type;
d62a17ae 104 struct rd_as rd_as;
105 struct rd_ip rd_ip;
106 struct prefix_rd prd;
ddb5b488 107 mpls_label_t label = {0};
d62a17ae 108 afi_t afi;
109 safi_t safi;
110 int addpath_encoded;
d7c0a89a 111 uint32_t addpath_id;
d62a17ae 112
d62a17ae 113 /* Make prefix_rd */
114 prd.family = AF_UNSPEC;
115 prd.prefixlen = 64;
116
117 pnt = packet->nlri;
118 lim = pnt + packet->length;
119 afi = packet->afi;
120 safi = packet->safi;
121 addpath_id = 0;
122
123 addpath_encoded =
124 (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
125 && CHECK_FLAG(peer->af_cap[afi][safi],
126 PEER_CAP_ADDPATH_AF_TX_RCV));
718e3744 127
50905aa2 128#define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
d62a17ae 129 for (; pnt < lim; pnt += psize) {
130 /* Clear prefix structure. */
131 memset(&p, 0, sizeof(struct prefix));
132
133 if (addpath_encoded) {
134
135 /* When packet overflow occurs return immediately. */
136 if (pnt + BGP_ADDPATH_ID_LEN > lim)
137 return -1;
138
139 addpath_id = ntohl(*((uint32_t *)pnt));
140 pnt += BGP_ADDPATH_ID_LEN;
141 }
142
143 /* Fetch prefix length. */
144 prefixlen = *pnt++;
145 p.family = afi2family(packet->afi);
146 psize = PSIZE(prefixlen);
147
148 if (prefixlen < VPN_PREFIXLEN_MIN_BYTES * 8) {
149 zlog_err(
150 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
151 peer->host, prefixlen);
152 return -1;
153 }
154
155 /* sanity check against packet data */
156 if ((pnt + psize) > lim) {
157 zlog_err(
158 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
159 peer->host, prefixlen, (uint)(lim - pnt));
160 return -1;
161 }
162
163 /* sanity check against storage for the IP address portion */
164 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t)sizeof(p.u)) {
165 zlog_err(
166 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
167 peer->host,
168 prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
169 sizeof(p.u));
170 return -1;
171 }
172
173 /* Sanity check against max bitlen of the address family */
174 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen(&p)) {
175 zlog_err(
176 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
177 peer->host,
178 prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
179 p.family, prefix_blen(&p));
180 return -1;
181 }
182
183 /* Copy label to prefix. */
184 memcpy(&label, pnt, BGP_LABEL_BYTES);
185 bgp_set_valid_label(&label);
186
187 /* Copy routing distinguisher to rd. */
188 memcpy(&prd.val, pnt + BGP_LABEL_BYTES, 8);
189
190 /* Decode RD type. */
191 type = decode_rd_type(pnt + BGP_LABEL_BYTES);
192
193 switch (type) {
194 case RD_TYPE_AS:
195 decode_rd_as(pnt + 5, &rd_as);
196 break;
197
198 case RD_TYPE_AS4:
199 decode_rd_as4(pnt + 5, &rd_as);
200 break;
201
202 case RD_TYPE_IP:
203 decode_rd_ip(pnt + 5, &rd_ip);
204 break;
fe770c88 205
65efcfce 206#if ENABLE_BGP_VNC
d62a17ae 207 case RD_TYPE_VNC_ETH:
208 break;
65efcfce
LB
209#endif
210
d62a17ae 211 default:
212 zlog_err("Unknown RD type %d", type);
213 break; /* just report */
214 }
215
216 p.prefixlen =
217 prefixlen
218 - VPN_PREFIXLEN_MIN_BYTES * 8; /* exclude label & RD */
219 memcpy(&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
220 psize - VPN_PREFIXLEN_MIN_BYTES);
221
222 if (attr) {
223 bgp_update(peer, &p, addpath_id, attr, packet->afi,
224 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
b57ba6d2 225 BGP_ROUTE_NORMAL, &prd, &label, 1, 0, NULL);
d62a17ae 226 } else {
227 bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
228 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
b57ba6d2 229 BGP_ROUTE_NORMAL, &prd, &label, 1, NULL);
d62a17ae 230 }
231 }
232 /* Packet length consistency check. */
233 if (pnt != lim) {
234 zlog_err(
235 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
236 peer->host, lim - pnt);
237 return -1;
238 }
239
240 return 0;
50905aa2 241#undef VPN_PREFIXLEN_MIN_BYTES
718e3744 242}
243
ddb5b488
PZ
244/*
245 * This function informs zebra of the label this vrf sets on routes
246 * leaked to VPN. Zebra should install this label in the kernel with
247 * an action of "pop label and then use this vrf's IP FIB to route the PDU."
248 *
249 * Sending this vrf-label association is qualified by a) whether vrf->vpn
250 * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list
251 * are set) and b) whether vpn-policy label is set.
252 *
253 * If any of these conditions do not hold, then we send MPLS_LABEL_NONE
254 * for this vrf, which zebra interprets to mean "delete this vrf-label
255 * association."
256 */
257void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi)
258{
259 mpls_label_t label = MPLS_LABEL_NONE;
ddb5b488
PZ
260 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
261
ddb5b488
PZ
262 if (bgp->vrf_id == VRF_UNKNOWN) {
263 if (debug) {
264 zlog_debug(
265 "%s: vrf %s: afi %s: vrf_id not set, "
266 "can't set zebra vrf label",
960035b2 267 __func__, bgp->name_pretty, afi2str(afi));
ddb5b488
PZ
268 }
269 return;
270 }
271
272 if (vpn_leak_to_vpn_active(bgp, afi, NULL)) {
273 label = bgp->vpn_policy[afi].tovpn_label;
274 }
275
276 if (debug) {
277 zlog_debug("%s: vrf %s: afi %s: setting label %d for vrf id %d",
960035b2
PZ
278 __func__, bgp->name_pretty, afi2str(afi), label,
279 bgp->vrf_id);
ddb5b488
PZ
280 }
281
282 zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
283 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
284}
285
286/*
287 * If zebra tells us vrf has become unconfigured, tell zebra not to
288 * use this label to forward to the vrf anymore
289 */
290void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi)
291{
292 mpls_label_t label = MPLS_LABEL_NONE;
293 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
294
295 if (bgp->vrf_id == VRF_UNKNOWN) {
296 if (debug) {
297 zlog_debug(
298 "%s: vrf_id not set, can't delete zebra vrf label",
299 __func__);
300 }
301 return;
302 }
303
304 if (debug) {
305 zlog_debug("%s: deleting label for vrf %s (id=%d)", __func__,
960035b2 306 bgp->name_pretty, bgp->vrf_id);
ddb5b488
PZ
307 }
308
309 zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
310 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
311}
312
313static int ecom_intersect(struct ecommunity *e1, struct ecommunity *e2)
314{
315 int i;
316 int j;
317
318 if (!e1 || !e2)
319 return 0;
320
321 for (i = 0; i < e1->size; ++i) {
322 for (j = 0; j < e2->size; ++j) {
323 if (!memcmp(e1->val + (i * ECOMMUNITY_SIZE),
324 e2->val + (j * ECOMMUNITY_SIZE),
325 ECOMMUNITY_SIZE)) {
326
327 return 1;
328 }
329 }
330 }
331 return 0;
332}
333
334/*
335 * returns pointer to new bgp_info upon success
336 */
337static struct bgp_info *
960035b2
PZ
338leak_update(
339 struct bgp *bgp, /* destination bgp instance */
340 struct bgp_node *bn,
341 struct attr *new_attr, /* already interned */
342 afi_t afi,
343 safi_t safi,
344 struct bgp_info *source_bi,
345 mpls_label_t *label,
346 int num_labels,
347 void *parent,
348 struct bgp *bgp_orig,
349 struct prefix *nexthop_orig,
350 int nexthop_self_flag,
351 int debug)
ddb5b488
PZ
352{
353 struct prefix *p = &bn->p;
354 struct bgp_info *bi;
355 struct bgp_info *new;
356 char buf_prefix[PREFIX_STRLEN];
ddb5b488
PZ
357
358 if (debug) {
359 prefix2str(&bn->p, buf_prefix, sizeof(buf_prefix));
960035b2
PZ
360 zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
361 __func__, bgp->name_pretty, buf_prefix,
362 source_bi->type, source_bi->sub_type);
ddb5b488
PZ
363 }
364
365 /*
366 * match parent
367 */
368 for (bi = bn->info; bi; bi = bi->next) {
369 if (bi->extra && bi->extra->parent == parent)
370 break;
371 }
372
373 if (bi) {
374 if (attrhash_cmp(bi->attr, new_attr)
375 && !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
376
377 bgp_attr_unintern(&new_attr);
378 if (debug)
379 zlog_debug(
380 "%s: ->%s: %s: Found route, no change",
960035b2 381 __func__, bgp->name_pretty,
ddb5b488
PZ
382 buf_prefix);
383 return NULL;
384 }
385
386 /* attr is changed */
387 bgp_info_set_flag(bn, bi, BGP_INFO_ATTR_CHANGED);
388
389 /* Rewrite BGP route information. */
390 if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
391 bgp_info_restore(bn, bi);
392 else
393 bgp_aggregate_decrement(bgp, p, bi, afi, safi);
394 bgp_attr_unintern(&bi->attr);
395 bi->attr = new_attr;
396 bi->uptime = bgp_clock();
397
960035b2
PZ
398 if (nexthop_self_flag)
399 bgp_info_set_flag(bn, bi, BGP_INFO_ANNC_NH_SELF);
400
401 struct bgp *bgp_nexthop = bgp;
402 int nh_valid;
403
404 if (bi->extra && bi->extra->bgp_orig)
405 bgp_nexthop = bi->extra->bgp_orig;
406
407 /* No nexthop tracking for redistributed routes */
408 if (source_bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
409 nh_valid = 1;
410 else
411 /*
412 * TBD do we need to do anything about the
413 * 'connected' parameter?
414 */
415 nh_valid = bgp_find_or_add_nexthop(
416 bgp, bgp_nexthop,
417 afi, bi, NULL, 0);
418
419 if (debug)
420 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
421 __func__, (nh_valid ? "" : "not "),
422 bgp_nexthop->name_pretty);
423
424 if (nh_valid)
425 bgp_info_set_flag(bn, bi, BGP_INFO_VALID);
426
ddb5b488
PZ
427 /* Process change. */
428 bgp_aggregate_increment(bgp, p, bi, afi, safi);
429 bgp_process(bgp, bn, afi, safi);
430 bgp_unlock_node(bn);
431
432 if (debug)
433 zlog_debug("%s: ->%s: %s Found route, changed attr",
960035b2 434 __func__, bgp->name_pretty, buf_prefix);
ddb5b488
PZ
435
436 return NULL;
437 }
438
960035b2
PZ
439 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
440 bgp->peer_self, new_attr, bn);
441
442 if (nexthop_self_flag)
443 bgp_info_set_flag(bn, new, BGP_INFO_ANNC_NH_SELF);
ddb5b488
PZ
444
445 bgp_info_extra_get(new);
446 if (label) {
447 int i;
448
449 for (i = 0; i < num_labels; ++i) {
450 new->extra->label[i] = label[i];
451 if (!bgp_is_valid_label(&label[i])) {
452 if (debug) {
453 zlog_debug(
454 "%s: %s: marking label %d valid",
455 __func__, buf_prefix, i);
456 }
457 bgp_set_valid_label(&new->extra->label[i]);
458 }
459 }
460 new->extra->num_labels = num_labels;
461 }
462 new->extra->parent = parent;
463
464 if (bgp_orig)
465 new->extra->bgp_orig = bgp_orig;
466 if (nexthop_orig)
467 new->extra->nexthop_orig = *nexthop_orig;
468
960035b2
PZ
469 /*
470 * nexthop tracking for unicast routes
471 */
472 struct bgp *bgp_nexthop = bgp;
473 int nh_valid;
474
475 if (new->extra && new->extra->bgp_orig)
476 bgp_nexthop = new->extra->bgp_orig;
477
478 /*
479 * No nexthop tracking for redistributed routes because
480 * their originating protocols will do the tracking and
481 * withdraw those routes if the nexthops become unreachable
482 */
483 if (source_bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
484 nh_valid = 1;
485 else
486 /*
487 * TBD do we need to do anything about the
488 * 'connected' parameter?
489 */
490 nh_valid = bgp_find_or_add_nexthop(bgp, bgp_nexthop,
491 afi, new, NULL, 0);
492
493 if (debug)
494 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
495 __func__, (nh_valid ? "" : "not "),
496 bgp_nexthop->name_pretty);
497 if (nh_valid)
498 bgp_info_set_flag(bn, new, BGP_INFO_VALID);
499
ddb5b488
PZ
500 bgp_aggregate_increment(bgp, p, new, afi, safi);
501 bgp_info_add(bn, new);
502
503 bgp_unlock_node(bn);
504 bgp_process(bgp, bn, afi, safi);
505
506 if (debug)
507 zlog_debug("%s: ->%s: %s: Added new route", __func__,
960035b2 508 bgp->name_pretty, buf_prefix);
ddb5b488
PZ
509
510 return new;
511}
512
513/* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
514void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
515 struct bgp *bgp_vrf, /* from */
516 struct bgp_info *info_vrf) /* route */
517{
518 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
519 struct prefix *p = &info_vrf->net->p;
520 afi_t afi = family2afi(p->family);
521 struct attr static_attr = {0};
522 struct attr *new_attr = NULL;
523 safi_t safi = SAFI_MPLS_VPN;
524 mpls_label_t label_val;
525 mpls_label_t label;
526 struct bgp_node *bn;
527 const char *debugmsg;
960035b2
PZ
528 int nexthop_self_flag = 0;
529
530 if (debug)
531 zlog_debug("%s: from vrf %s", __func__, bgp_vrf->name_pretty);
ddb5b488 532
c8f57349
DS
533 if (debug && info_vrf->attr->ecommunity) {
534 char *s = ecommunity_ecom2str(info_vrf->attr->ecommunity,
535 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488
PZ
536
537 zlog_debug("%s: info_vrf->type=%d, EC{%s}", __func__,
538 info_vrf->type, s);
c8f57349 539 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
540 }
541
542 if (!bgp_vpn)
543 return;
544
545 if (!afi) {
546 if (debug)
547 zlog_debug("%s: can't get afi of prefix", __func__);
548 return;
549 }
550
551 /* loop check */
552 if (info_vrf->extra && info_vrf->extra->bgp_orig == bgp_vpn)
553 return;
554
555
556 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
557 if (debug)
558 zlog_debug("%s: skipping: %s", __func__, debugmsg);
559 return;
560 }
561
562 bgp_attr_dup(&static_attr, info_vrf->attr); /* shallow copy */
563
564 /*
565 * route map handling
566 */
567 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
568 struct bgp_info info;
569 route_map_result_t ret;
570
571 memset(&info, 0, sizeof(info));
572 info.peer = bgp_vpn->peer_self;
573 info.attr = &static_attr;
574 ret = route_map_apply(
575 bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN],
576 p, RMAP_BGP, &info);
577 if (RMAP_DENYMATCH == ret) {
578 bgp_attr_flush(&static_attr); /* free any added parts */
579 if (debug)
580 zlog_debug(
581 "%s: vrf %s route map \"%s\" says DENY, returning",
960035b2 582 __func__, bgp_vrf->name_pretty,
ddb5b488
PZ
583 bgp_vrf->vpn_policy[afi]
584 .rmap[BGP_VPN_POLICY_DIR_TOVPN]
585 ->name);
586 return;
587 }
588 }
589
c8f57349
DS
590 if (debug && static_attr.ecommunity) {
591 char *s = ecommunity_ecom2str(static_attr.ecommunity,
592 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 593
ddb5b488
PZ
594 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
595 __func__, s);
c8f57349 596 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
597 }
598
599 /*
600 * Add the vpn-policy rt-list
601 */
602 struct ecommunity *old_ecom;
603 struct ecommunity *new_ecom;
604
605 old_ecom = static_attr.ecommunity;
606 if (old_ecom) {
607 new_ecom = ecommunity_merge(
608 ecommunity_dup(old_ecom),
609 bgp_vrf->vpn_policy[afi]
610 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
611 if (!old_ecom->refcnt)
612 ecommunity_free(&old_ecom);
613 } else {
614 new_ecom = ecommunity_dup(
615 bgp_vrf->vpn_policy[afi]
616 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
617 }
618 static_attr.ecommunity = new_ecom;
619 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
620
c8f57349
DS
621 if (debug && static_attr.ecommunity) {
622 char *s = ecommunity_ecom2str(static_attr.ecommunity,
623 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 624
ddb5b488
PZ
625 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
626 __func__, s);
c8f57349 627 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
628 }
629
630 /* Nexthop */
631 /* if policy nexthop not set, use 0 */
632 if (CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
633 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
634
635 struct prefix *nexthop =
636 &bgp_vrf->vpn_policy[afi].tovpn_nexthop;
637 switch (nexthop->family) {
638 case AF_INET:
639 /* prevent mp_nexthop_global_in <- self in bgp_route.c
640 */
641 static_attr.nexthop.s_addr = nexthop->u.prefix4.s_addr;
642
643 static_attr.mp_nexthop_global_in = nexthop->u.prefix4;
644 static_attr.mp_nexthop_len = 4;
645 break;
646
647 case AF_INET6:
648 static_attr.mp_nexthop_global = nexthop->u.prefix6;
649 static_attr.mp_nexthop_len = 16;
650 break;
651
652 default:
653 assert(0);
654 }
655 } else {
960035b2
PZ
656 if (afi == AFI_IP) {
657 /* For ipv4, copy to multiprotocol nexthop field */
658 static_attr.mp_nexthop_global_in = static_attr.nexthop;
ddb5b488 659 static_attr.mp_nexthop_len = 4;
960035b2
PZ
660 /* XXX Leave static_attr.nexthop intact for NHT */
661 static_attr.flag &= ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
ddb5b488 662 }
960035b2 663 nexthop_self_flag = 1;
ddb5b488
PZ
664 }
665
666 label_val = bgp_vrf->vpn_policy[afi].tovpn_label;
667 if (label_val == MPLS_LABEL_NONE) {
668 /* TBD get from label manager */
669 label = MPLS_LABEL_IMPLICIT_NULL;
670 } else {
671 encode_label(label_val, &label);
672 }
673
674 /* Set originator ID to "me" */
675 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID));
676 static_attr.originator_id = bgp_vpn->router_id;
677
678
679 new_attr = bgp_attr_intern(
680 &static_attr); /* hashed refcounted everything */
681 bgp_attr_flush(&static_attr); /* free locally-allocated parts */
682
c3e345b1
DS
683 if (debug && new_attr->ecommunity) {
684 char *s = ecommunity_ecom2str(new_attr->ecommunity,
685 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 686
ddb5b488 687 zlog_debug("%s: new_attr->ecommunity{%s}", __func__, s);
c3e345b1 688 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
689 }
690
691 /* Now new_attr is an allocated interned attr */
692
693 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
694 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
695
696 struct bgp_info *new_info;
697
698 new_info = leak_update(bgp_vpn, bn, new_attr, afi, safi, info_vrf,
960035b2
PZ
699 &label, 1, info_vrf, bgp_vrf, NULL,
700 nexthop_self_flag, debug);
ddb5b488
PZ
701
702 /*
703 * Routes actually installed in the vpn RIB must also be
704 * offered to all vrfs (because now they originate from
705 * the vpn RIB).
706 *
707 * Acceptance into other vrfs depends on rt-lists.
708 * Originating vrf will not accept the looped back route
709 * because of loop checking.
710 */
711 if (new_info)
712 vpn_leak_to_vrf_update(bgp_vrf, new_info);
713}
714
715void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
716 struct bgp *bgp_vrf, /* from */
717 struct bgp_info *info_vrf) /* route */
718{
719 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
720 struct prefix *p = &info_vrf->net->p;
721 afi_t afi = family2afi(p->family);
722 safi_t safi = SAFI_MPLS_VPN;
723 struct bgp_info *bi;
724 struct bgp_node *bn;
725 const char *debugmsg;
960035b2
PZ
726 char buf_prefix[PREFIX_STRLEN];
727
728 if (debug) {
729 prefix2str(p, buf_prefix, sizeof(buf_prefix));
730 zlog_debug(
731 "%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
732 __func__, bgp_vrf->name_pretty, buf_prefix,
733 info_vrf->type, info_vrf->sub_type);
734 }
ddb5b488
PZ
735
736 if (info_vrf->type != ZEBRA_ROUTE_BGP) {
737 if (debug)
738 zlog_debug("%s: wrong type %d", __func__,
739 info_vrf->type);
740 return;
741 }
742 if (info_vrf->sub_type != BGP_ROUTE_NORMAL
743 && info_vrf->sub_type != BGP_ROUTE_STATIC) {
744
745 if (debug)
746 zlog_debug("%s: wrong sub_type %d", __func__,
747 info_vrf->sub_type);
748 return;
749 }
750 if (!bgp_vpn)
751 return;
752
753 if (!afi) {
754 if (debug)
755 zlog_debug("%s: can't get afi of prefix", __func__);
756 return;
757 }
758
759 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
760 if (debug)
761 zlog_debug("%s: skipping: %s", __func__, debugmsg);
762 return;
763 }
764
765 if (debug)
766 zlog_debug("%s: withdrawing (info_vrf=%p)", __func__, info_vrf);
767
768 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
769 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
770
771 /*
772 * vrf -> vpn
773 * match original bi imported from
774 */
775 for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
776 if (bi->extra && bi->extra->parent == info_vrf) {
777 break;
778 }
779 }
780
781 if (bi) {
782 /* withdraw from looped vrfs as well */
783 vpn_leak_to_vrf_withdraw(bgp_vpn, bi);
784
785 bgp_aggregate_decrement(bgp_vpn, p, bi, afi, safi);
786 bgp_info_delete(bn, bi);
787 bgp_process(bgp_vpn, bn, afi, safi);
788 }
789 bgp_unlock_node(bn);
790}
791
792void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
793 struct bgp *bgp_vrf, /* from */
794 afi_t afi)
795{
796 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
797 struct bgp_node *prn;
798 safi_t safi = SAFI_MPLS_VPN;
799
800 /*
ddb5b488
PZ
801 * Walk vpn table, delete bi with bgp_orig == bgp_vrf
802 */
803 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
804 prn = bgp_route_next(prn)) {
805
806 struct bgp_table *table;
807 struct bgp_node *bn;
808 struct bgp_info *bi;
809
810 /* This is the per-RD table of prefixes */
811 table = prn->info;
812
813 if (!table)
814 continue;
815
816 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
817
818 char buf[PREFIX2STR_BUFFER];
819
820 if (debug && bn->info) {
821 zlog_debug(
822 "%s: looking at prefix %s", __func__,
823 prefix2str(&bn->p, buf, sizeof(buf)));
824 }
825
826 for (bi = bn->info; bi; bi = bi->next) {
827 if (debug)
828 zlog_debug("%s: type %d, sub_type %d",
829 __func__, bi->type,
830 bi->sub_type);
831 if (bi->sub_type != BGP_ROUTE_IMPORTED)
832 continue;
833 if (!bi->extra)
834 continue;
835 if ((struct bgp *)bi->extra->bgp_orig
836 == bgp_vrf) {
837 /* delete route */
838 if (debug)
839 zlog_debug("%s: deleting it\n",
840 __func__);
841 bgp_aggregate_decrement(bgp_vpn, &bn->p,
842 bi, afi, safi);
843 bgp_info_delete(bn, bi);
844 bgp_process(bgp_vpn, bn, afi, safi);
845 }
846 }
847 }
848 }
849}
850
851void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn, /* to */
852 struct bgp *bgp_vrf, /* from */
853 afi_t afi)
854{
855 struct bgp_node *bn;
856 struct bgp_info *bi;
857 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
858
859 if (debug)
860 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__, afi,
960035b2 861 bgp_vrf->name_pretty);
ddb5b488
PZ
862
863 for (bn = bgp_table_top(bgp_vrf->rib[afi][SAFI_UNICAST]); bn;
864 bn = bgp_route_next(bn)) {
865
866 if (debug)
867 zlog_debug("%s: node=%p", __func__, bn);
868
869 for (bi = bn->info; bi; bi = bi->next) {
870 if (debug)
871 zlog_debug(
872 "%s: calling vpn_leak_from_vrf_update",
873 __func__);
874 vpn_leak_from_vrf_update(bgp_vpn, bgp_vrf, bi);
875 }
876 }
877}
878
879static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
880 struct bgp *bgp_vpn, /* from */
881 struct bgp_info *info_vpn) /* route */
882{
883 struct prefix *p = &info_vpn->net->p;
884 afi_t afi = family2afi(p->family);
885
ddb5b488
PZ
886 struct attr static_attr = {0};
887 struct attr *new_attr = NULL;
888 struct bgp_node *bn;
889 safi_t safi = SAFI_UNICAST;
890 const char *debugmsg;
891 struct prefix nexthop_orig;
892 mpls_label_t *pLabels = NULL;
893 int num_labels = 0;
960035b2 894 int nexthop_self_flag = 1;
ddb5b488
PZ
895
896 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
897
b9c7bc5a 898 if (!vpn_leak_from_vpn_active(bgp_vrf, afi, &debugmsg)) {
ddb5b488
PZ
899 if (debug)
900 zlog_debug("%s: skipping: %s", __func__, debugmsg);
901 return;
902 }
903
904 /* Check for intersection of route targets */
905 if (!ecom_intersect(
906 bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
907 info_vpn->attr->ecommunity)) {
908
909 return;
910 }
911
912 if (debug)
960035b2
PZ
913 zlog_debug("%s: updating to vrf %s", __func__,
914 bgp_vrf->name_pretty);
ddb5b488
PZ
915
916 bgp_attr_dup(&static_attr, info_vpn->attr); /* shallow copy */
917
918 /*
919 * Nexthop: stash and clear
920 *
921 * Nexthop is valid in context of VPN core, but not in destination vrf.
922 * Stash it for later label resolution by vrf ingress path and then
923 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
924 */
925 uint8_t nhfamily = NEXTHOP_FAMILY(info_vpn->attr->mp_nexthop_len);
926
927 memset(&nexthop_orig, 0, sizeof(nexthop_orig));
928 nexthop_orig.family = nhfamily;
929
930 switch (nhfamily) {
931
932 case AF_INET:
933 /* save */
934 nexthop_orig.u.prefix4 = info_vpn->attr->mp_nexthop_global_in;
935 nexthop_orig.prefixlen = 32;
ddb5b488 936 static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
ddb5b488
PZ
937 break;
938
939 case AF_INET6:
940 /* save */
941 nexthop_orig.u.prefix6 = info_vpn->attr->mp_nexthop_global;
942 nexthop_orig.prefixlen = 128;
ddb5b488
PZ
943 break;
944 }
945
946
947 /*
948 * route map handling
ddb5b488 949 */
ddb5b488
PZ
950 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
951 struct bgp_info info;
952 route_map_result_t ret;
953
954 memset(&info, 0, sizeof(info));
955 info.peer = bgp_vrf->peer_self;
956 info.attr = &static_attr;
957 ret = route_map_apply(bgp_vrf->vpn_policy[afi]
958 .rmap[BGP_VPN_POLICY_DIR_FROMVPN],
959 p, RMAP_BGP, &info);
960 if (RMAP_DENYMATCH == ret) {
961 bgp_attr_flush(&static_attr); /* free any added parts */
962 if (debug)
963 zlog_debug(
964 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
960035b2 965 __func__, bgp_vrf->name_pretty,
ddb5b488
PZ
966 bgp_vrf->vpn_policy[afi]
967 .rmap[BGP_VPN_POLICY_DIR_FROMVPN]
968 ->name);
969 return;
970 }
960035b2
PZ
971 /*
972 * if route-map changed nexthop, don't nexthop-self on output
973 */
974 if (!CHECK_FLAG(static_attr.rmap_change_flags,
975 BATTR_RMAP_NEXTHOP_UNCHANGED))
976 nexthop_self_flag = 0;
ddb5b488
PZ
977 }
978
979 new_attr = bgp_attr_intern(&static_attr);
980 bgp_attr_flush(&static_attr);
981
982 bn = bgp_afi_node_get(bgp_vrf->rib[afi][safi], afi, safi, p, NULL);
983
984 /*
985 * ensure labels are copied
986 */
987 if (info_vpn->extra && info_vpn->extra->num_labels) {
988 num_labels = info_vpn->extra->num_labels;
989 if (num_labels > BGP_MAX_LABELS)
990 num_labels = BGP_MAX_LABELS;
991 pLabels = info_vpn->extra->label;
992 }
993 if (debug) {
994 char buf_prefix[PREFIX_STRLEN];
995 prefix2str(p, buf_prefix, sizeof(buf_prefix));
996 zlog_debug("%s: pfx %s: num_labels %d", __func__, buf_prefix,
997 num_labels);
998 }
999
960035b2
PZ
1000 leak_update(bgp_vrf, bn, new_attr, afi, safi, info_vpn,
1001 pLabels, num_labels,
1002 info_vpn, /* parent */
1003 bgp_vpn, &nexthop_orig, nexthop_self_flag, debug);
ddb5b488
PZ
1004}
1005
1006void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
1007 struct bgp_info *info_vpn) /* route */
1008{
1009 struct listnode *mnode, *mnnode;
1010 struct bgp *bgp;
1011
1012 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1013
1014 if (debug)
1015 zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
1016
1017 /* Loop over VRFs */
1018 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
1019
1020 if (!info_vpn->extra
1021 || info_vpn->extra->bgp_orig != bgp) { /* no loop */
1022 vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, info_vpn);
1023 }
1024 }
1025}
1026
1027void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
1028 struct bgp_info *info_vpn) /* route */
1029{
1b3510a0
PZ
1030 struct prefix *p;
1031 afi_t afi;
ddb5b488
PZ
1032 safi_t safi = SAFI_UNICAST;
1033 struct bgp *bgp;
1034 struct listnode *mnode, *mnnode;
ddb5b488
PZ
1035 struct bgp_node *bn;
1036 struct bgp_info *bi;
1037 const char *debugmsg;
960035b2 1038 char buf_prefix[PREFIX_STRLEN];
ddb5b488
PZ
1039
1040 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1041
960035b2
PZ
1042 if (debug) {
1043 prefix2str(&info_vpn->net->p, buf_prefix, sizeof(buf_prefix));
1044 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d",
1045 __func__, buf_prefix,
1046 info_vpn->type, info_vpn->sub_type);
1047 }
1048
ddb5b488
PZ
1049 if (debug)
1050 zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
1051
1b3510a0 1052 if (!info_vpn->net) {
56c2c080 1053#if ENABLE_BGP_VNC
1b3510a0
PZ
1054 /* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
1055 if (info_vpn->type == ZEBRA_ROUTE_BGP &&
1056 info_vpn->sub_type == BGP_ROUTE_RFP) {
1057
1058 return;
1059 }
56c2c080 1060#endif
1b3510a0
PZ
1061 if (debug)
1062 zlog_debug("%s: info_vpn->net unexpectedly NULL, no prefix, bailing",
1063 __func__);
1064 return;
1065 }
1066
1067 p = &info_vpn->net->p;
1068 afi = family2afi(p->family);
ddb5b488
PZ
1069
1070 /* Loop over VRFs */
1071 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
b9c7bc5a 1072 if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
ddb5b488
PZ
1073 if (debug)
1074 zlog_debug("%s: skipping: %s", __func__,
1075 debugmsg);
1076 continue;
1077 }
1078
1079 /* Check for intersection of route targets */
1080 if (!ecom_intersect(bgp->vpn_policy[afi]
1081 .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1082 info_vpn->attr->ecommunity)) {
1083
1084 continue;
1085 }
1086
1087 if (debug)
1088 zlog_debug("%s: withdrawing from vrf %s", __func__,
960035b2 1089 bgp->name_pretty);
ddb5b488
PZ
1090
1091 bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
1092 for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
1093 if (bi->extra
1094 && (struct bgp_info *)bi->extra->parent
1095 == info_vpn) {
1096 break;
1097 }
1098 }
1099
1100 if (bi) {
1101 if (debug)
1102 zlog_debug("%s: deleting bi %p", __func__, bi);
1103 bgp_aggregate_decrement(bgp, p, bi, afi, safi);
1104 bgp_info_delete(bn, bi);
1105 bgp_process(bgp, bn, afi, safi);
1106 }
1107 bgp_unlock_node(bn);
1108 }
1109}
1110
1111void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
1112 afi_t afi)
1113{
1114 struct bgp_node *bn;
1115 struct bgp_info *bi;
1116 safi_t safi = SAFI_UNICAST;
1117 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1118 struct bgp *bgp_vpn = bgp_get_default();
1119
1120 if (debug)
1121 zlog_debug("%s: entry", __func__);
1122 /*
1123 * Walk vrf table, delete bi with bgp_orig == bgp_vpn
1124 */
1125 for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
1126 bn = bgp_route_next(bn)) {
1127
1128 for (bi = bn->info; bi; bi = bi->next) {
1129 if (bi->extra && bi->extra->bgp_orig == bgp_vpn) {
1130
1131 /* delete route */
1132 bgp_aggregate_decrement(bgp_vrf, &bn->p, bi,
1133 afi, safi);
1134 bgp_info_delete(bn, bi);
1135 bgp_process(bgp_vrf, bn, afi, safi);
1136 }
1137 }
1138 }
1139}
1140
1141void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
1142 struct bgp *bgp_vpn, /* from */
1143 afi_t afi)
1144{
1145 struct prefix_rd prd;
1146 struct bgp_node *prn;
1147 safi_t safi = SAFI_MPLS_VPN;
1148
1149 /*
1150 * Walk vpn table
1151 */
1152 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
1153 prn = bgp_route_next(prn)) {
1154
1155 struct bgp_table *table;
1156 struct bgp_node *bn;
1157 struct bgp_info *bi;
1158
1159 memset(&prd, 0, sizeof(prd));
1160 prd.family = AF_UNSPEC;
1161 prd.prefixlen = 64;
1162 memcpy(prd.val, prn->p.u.val, 8);
1163
1164 /* This is the per-RD table of prefixes */
1165 table = prn->info;
1166
1167 if (!table)
1168 continue;
1169
1170 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
1171
1172 for (bi = bn->info; bi; bi = bi->next) {
1173
1174 if (bi->extra && bi->extra->bgp_orig == bgp_vrf)
1175 continue;
1176
1177 vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
1178 bi);
1179 }
1180 }
1181 }
1182}
1183
1184static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
1185{
1186 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1187 afi_t afi;
1188 struct route_map *rmap;
1189
1190 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1191 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
1192
1193 return;
1194 }
1195
1196 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
1197
1198 for (afi = 0; afi < AFI_MAX; ++afi) {
1199
1200 if (vpn_leak_to_vpn_active(bgp, afi, NULL)
1201 && bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
1202 && !strcmp(rmap_name,
1203 bgp->vpn_policy[afi]
1204 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
1205
1206 if (debug)
1207 zlog_debug(
1208 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1209 __func__, rmap_name, bgp->as,
1210 afi2str(afi));
1211
1212 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1213 bgp_get_default(), bgp);
1214 if (debug)
1215 zlog_debug("%s: after vpn_leak_prechange",
1216 __func__);
1217
1218 if (!rmap)
1219 bgp->vpn_policy[afi]
1220 .rmap[BGP_VPN_POLICY_DIR_TOVPN] = NULL;
1221
1222 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1223 bgp_get_default(), bgp);
1224 if (debug)
1225 zlog_debug("%s: after vpn_leak_postchange",
1226 __func__);
1227 }
1228
b9c7bc5a
PZ
1229 char *mapname = bgp->vpn_policy[afi]
1230 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN];
ddb5b488 1231
d555f3e9 1232 if (vpn_leak_from_vpn_active(bgp, afi, NULL) &&
b9c7bc5a
PZ
1233 mapname &&
1234 !strcmp(rmap_name, mapname)) {
1235
1236 if (debug) {
1237 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
ddb5b488
PZ
1238 __func__, rmap_name, bgp->as,
1239 afi2str(afi));
b9c7bc5a 1240 }
ddb5b488
PZ
1241
1242 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1243 bgp_get_default(), bgp);
1244
b9c7bc5a 1245 if (!rmap) {
ddb5b488
PZ
1246 bgp->vpn_policy[afi]
1247 .rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
1248 NULL;
b9c7bc5a 1249 }
ddb5b488
PZ
1250
1251 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1252 bgp_get_default(), bgp);
1253 }
1254 }
1255}
1256
1257void vpn_policy_routemap_event(const char *rmap_name)
1258{
1259 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1260 struct listnode *mnode, *mnnode;
1261 struct bgp *bgp;
1262
1263 if (debug)
1264 zlog_debug("%s: entry", __func__);
1265
1266 if (bm->bgp == NULL) /* may be called during cleanup */
1267 return;
1268
1269 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
1270 vpn_policy_routemap_update(bgp, rmap_name);
1271}
1272
718e3744 1273/* For testing purpose, static route of MPLS-VPN. */
1274DEFUN (vpnv4_network,
1275 vpnv4_network_cmd,
d114b977 1276 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1277 "Specify a network to announce via BGP\n"
0c7b1b01 1278 "IPv4 prefix\n"
718e3744 1279 "Specify Route Distinguisher\n"
1280 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1281 "VPN NLRI label (tag)\n"
1282 "VPN NLRI label (tag)\n"
1283 "Label value\n")
718e3744 1284{
d62a17ae 1285 int idx_ipv4_prefixlen = 1;
1286 int idx_ext_community = 3;
1287 int idx_label = 5;
1288 return bgp_static_set_safi(
1289 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1290 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
1291 NULL, NULL, NULL, NULL);
137446f9
LB
1292}
1293
1294DEFUN (vpnv4_network_route_map,
1295 vpnv4_network_route_map_cmd,
d114b977 1296 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
137446f9 1297 "Specify a network to announce via BGP\n"
0c7b1b01 1298 "IPv4 prefix\n"
137446f9
LB
1299 "Specify Route Distinguisher\n"
1300 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1301 "VPN NLRI label (tag)\n"
1302 "VPN NLRI label (tag)\n"
1303 "Label value\n"
137446f9
LB
1304 "route map\n"
1305 "route map name\n")
1306{
d62a17ae 1307 int idx_ipv4_prefixlen = 1;
1308 int idx_ext_community = 3;
1309 int idx_label = 5;
1310 int idx_word_2 = 7;
1311 return bgp_static_set_safi(
1312 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1313 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1314 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
718e3744 1315}
1316
1317/* For testing purpose, static route of MPLS-VPN. */
1318DEFUN (no_vpnv4_network,
1319 no_vpnv4_network_cmd,
d114b977 1320 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1321 NO_STR
1322 "Specify a network to announce via BGP\n"
0c7b1b01 1323 "IPv4 prefix\n"
718e3744 1324 "Specify Route Distinguisher\n"
1325 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1326 "VPN NLRI label (tag)\n"
1327 "VPN NLRI label (tag)\n"
1328 "Label value\n")
718e3744 1329{
d62a17ae 1330 int idx_ipv4_prefixlen = 2;
1331 int idx_ext_community = 4;
1332 int idx_label = 6;
1333 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
1334 argv[idx_ipv4_prefixlen]->arg,
1335 argv[idx_ext_community]->arg,
1336 argv[idx_label]->arg, 0, NULL, NULL, NULL);
718e3744 1337}
1338
c286be96
LX
1339DEFUN (vpnv6_network,
1340 vpnv6_network_cmd,
d114b977 1341 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
c286be96
LX
1342 "Specify a network to announce via BGP\n"
1343 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1344 "Specify Route Distinguisher\n"
1345 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1346 "VPN NLRI label (tag)\n"
1347 "VPN NLRI label (tag)\n"
1348 "Label value\n"
11daee81
DS
1349 "route map\n"
1350 "route map name\n")
c286be96 1351{
d62a17ae 1352 int idx_ipv6_prefix = 1;
1353 int idx_ext_community = 3;
1354 int idx_label = 5;
1355 int idx_word_2 = 7;
1356 if (argc == 8)
1357 return bgp_static_set_safi(
1358 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1359 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1360 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
1361 else
1362 return bgp_static_set_safi(
1363 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1364 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1365 NULL, 0, NULL, NULL, NULL, NULL);
c286be96
LX
1366}
1367
1368/* For testing purpose, static route of MPLS-VPN. */
1369DEFUN (no_vpnv6_network,
1370 no_vpnv6_network_cmd,
d114b977 1371 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
c286be96
LX
1372 NO_STR
1373 "Specify a network to announce via BGP\n"
1374 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1375 "Specify Route Distinguisher\n"
1376 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1377 "VPN NLRI label (tag)\n"
1378 "VPN NLRI label (tag)\n"
1379 "Label value\n")
c286be96 1380{
d62a17ae 1381 int idx_ipv6_prefix = 2;
1382 int idx_ext_community = 4;
1383 int idx_label = 6;
1384 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
1385 argv[idx_ipv6_prefix]->arg,
1386 argv[idx_ext_community]->arg,
1387 argv[idx_label]->arg, 0, NULL, NULL, NULL);
c286be96
LX
1388}
1389
d62a17ae 1390int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
1391 enum bgp_show_type type, void *output_arg, int tags,
d7c0a89a 1392 uint8_t use_json)
718e3744 1393{
d62a17ae 1394 struct bgp *bgp;
1395 struct bgp_table *table;
d62a17ae 1396
1397 bgp = bgp_get_default();
1398 if (bgp == NULL) {
1399 if (!use_json)
1400 vty_out(vty, "No BGP process is configured\n");
16307668
RW
1401 else
1402 vty_out(vty, "{}\n");
d62a17ae 1403 return CMD_WARNING;
1404 }
1ae44dfc 1405 table = bgp->rib[afi][SAFI_MPLS_VPN];
a4d82a8a
PZ
1406 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
1407 output_arg, use_json);
718e3744 1408}
1409
4f280b15
LB
1410DEFUN (show_bgp_ip_vpn_all_rd,
1411 show_bgp_ip_vpn_all_rd_cmd,
d114b977 1412 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
e3e29b32
LB
1413 SHOW_STR
1414 BGP_STR
05e588f4 1415 BGP_VPNVX_HELP_STR
e3e29b32 1416 "Display VPN NLRI specific information\n"
af8528fa 1417 "Display VPN NLRI specific information\n"
e3e29b32
LB
1418 "Display information for a route distinguisher\n"
1419 "VPN Route Distinguisher\n"
1420 JSON_STR)
1421{
d62a17ae 1422 int ret;
1423 struct prefix_rd prd;
1424 afi_t afi;
1425 int idx = 0;
1426
1427 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
3d7c4cd7 1428 if (argv_find(argv, argc, "rd", &idx)) {
a4d82a8a 1429 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
d62a17ae 1430 if (!ret) {
1431 vty_out(vty,
1432 "%% Malformed Route Distinguisher\n");
1433 return CMD_WARNING;
1434 }
1435 return bgp_show_mpls_vpn(vty, afi, &prd,
1436 bgp_show_type_normal, NULL, 0,
1437 use_json(argc, argv));
1438 } else {
1439 return bgp_show_mpls_vpn(vty, afi, NULL,
1440 bgp_show_type_normal, NULL, 0,
1441 use_json(argc, argv));
1442 }
1443 }
1444 return CMD_SUCCESS;
718e3744 1445}
1446
af8528fa
LB
1447ALIAS(show_bgp_ip_vpn_all_rd,
1448 show_bgp_ip_vpn_rd_cmd,
1449 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1450 SHOW_STR
1451 BGP_STR
1452 BGP_VPNVX_HELP_STR
1453 "Display VPN NLRI specific information\n"
1454 "Display information for a route distinguisher\n"
1455 "VPN Route Distinguisher\n"
1456 JSON_STR)
1457
1458#ifdef KEEP_OLD_VPN_COMMANDS
3f227172
PG
1459DEFUN (show_ip_bgp_vpn_rd,
1460 show_ip_bgp_vpn_rd_cmd,
af8528fa 1461 "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
718e3744 1462 SHOW_STR
1463 IP_STR
1464 BGP_STR
4f280b15 1465 BGP_AFI_HELP_STR
3517059b 1466 "Address Family modifier\n"
718e3744 1467 "Display information for a route distinguisher\n"
1468 "VPN Route Distinguisher\n")
1469{
d62a17ae 1470 int idx_ext_community = argc - 1;
1471 int ret;
1472 struct prefix_rd prd;
1473 afi_t afi;
1474 int idx = 0;
1475
1476 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1477 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1478 if (!ret) {
1479 vty_out(vty, "%% Malformed Route Distinguisher\n");
1480 return CMD_WARNING;
1481 }
1482 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1483 NULL, 0, 0);
1484 }
1485 return CMD_SUCCESS;
1486}
718e3744 1487
4f280b15
LB
1488DEFUN (show_ip_bgp_vpn_all,
1489 show_ip_bgp_vpn_all_cmd,
1490 "show [ip] bgp <vpnv4|vpnv6>",
1491 SHOW_STR
1492 IP_STR
1493 BGP_STR
1494 BGP_VPNVX_HELP_STR)
1495{
d62a17ae 1496 afi_t afi;
1497 int idx = 0;
4f280b15 1498
d62a17ae 1499 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1500 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1501 NULL, 0, 0);
1502 return CMD_SUCCESS;
4f280b15
LB
1503}
1504
3f227172
PG
1505DEFUN (show_ip_bgp_vpn_all_tags,
1506 show_ip_bgp_vpn_all_tags_cmd,
1507 "show [ip] bgp <vpnv4|vpnv6> all tags",
718e3744 1508 SHOW_STR
1509 IP_STR
1510 BGP_STR
3f227172
PG
1511 BGP_VPNVX_HELP_STR
1512 "Display information about all VPNv4/VPNV6 NLRIs\n"
718e3744 1513 "Display BGP tags for prefixes\n")
1514{
d62a17ae 1515 afi_t afi;
1516 int idx = 0;
3f227172 1517
d62a17ae 1518 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1519 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1520 NULL, 1, 0);
1521 return CMD_SUCCESS;
718e3744 1522}
1523
3f227172
PG
1524DEFUN (show_ip_bgp_vpn_rd_tags,
1525 show_ip_bgp_vpn_rd_tags_cmd,
d114b977 1526 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
718e3744 1527 SHOW_STR
1528 IP_STR
1529 BGP_STR
3f227172 1530 BGP_VPNVX_HELP_STR
718e3744 1531 "Display information for a route distinguisher\n"
1532 "VPN Route Distinguisher\n"
1533 "Display BGP tags for prefixes\n")
1534{
d62a17ae 1535 int idx_ext_community = 5;
1536 int ret;
1537 struct prefix_rd prd;
1538 afi_t afi;
1539 int idx = 0;
1540
1541 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1542 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1543 if (!ret) {
1544 vty_out(vty, "%% Malformed Route Distinguisher\n");
1545 return CMD_WARNING;
1546 }
1547 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1548 NULL, 1, 0);
1549 }
1550 return CMD_SUCCESS;
718e3744 1551}
1552
3f227172
PG
1553DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
1554 show_ip_bgp_vpn_all_neighbor_routes_cmd,
1555 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
718e3744 1556 SHOW_STR
1557 IP_STR
1558 BGP_STR
3f227172
PG
1559 BGP_VPNVX_HELP_STR
1560 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 1561 "Detailed information on TCP and BGP neighbor connections\n"
1562 "Neighbor to display information about\n"
856ca177 1563 "Display routes learned from neighbor\n"
9973d184 1564 JSON_STR)
718e3744 1565{
d62a17ae 1566 int idx_ipv4 = 6;
1567 union sockunion su;
1568 struct peer *peer;
1569 int ret;
d7c0a89a 1570 uint8_t uj = use_json(argc, argv);
d62a17ae 1571 afi_t afi;
1572 int idx = 0;
1573
1574 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1575 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1576 if (ret < 0) {
1577 if (uj) {
1578 json_object *json_no = NULL;
1579 json_no = json_object_new_object();
1580 json_object_string_add(json_no, "warning",
1581 "Malformed address");
1582 vty_out(vty, "%s\n",
1583 json_object_to_json_string(json_no));
1584 json_object_free(json_no);
1585 } else
1586 vty_out(vty, "Malformed address: %s\n",
1587 argv[idx_ipv4]->arg);
1588 return CMD_WARNING;
1589 }
1590
1591 peer = peer_lookup(NULL, &su);
1592 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1593 if (uj) {
1594 json_object *json_no = NULL;
1595 json_no = json_object_new_object();
1596 json_object_string_add(
1597 json_no, "warning",
1598 "No such neighbor or address family");
1599 vty_out(vty, "%s\n",
1600 json_object_to_json_string(json_no));
1601 json_object_free(json_no);
1602 } else
1603 vty_out(vty,
1604 "%% No such neighbor or address family\n");
1605 return CMD_WARNING;
1606 }
1607
1608 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
1609 &su, 0, uj);
1610 }
1611 return CMD_SUCCESS;
718e3744 1612}
1613
3f227172
PG
1614DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
1615 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
d114b977 1616 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
718e3744 1617 SHOW_STR
1618 IP_STR
1619 BGP_STR
3f227172 1620 BGP_VPNVX_HELP_STR
718e3744 1621 "Display information for a route distinguisher\n"
1622 "VPN Route Distinguisher\n"
1623 "Detailed information on TCP and BGP neighbor connections\n"
1624 "Neighbor to display information about\n"
856ca177 1625 "Display routes learned from neighbor\n"
9973d184 1626 JSON_STR)
718e3744 1627{
d62a17ae 1628 int idx_ext_community = 5;
1629 int idx_ipv4 = 7;
1630 int ret;
1631 union sockunion su;
1632 struct peer *peer;
1633 struct prefix_rd prd;
d7c0a89a 1634 uint8_t uj = use_json(argc, argv);
d62a17ae 1635 afi_t afi;
1636 int idx = 0;
1637
1638 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1639 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1640 if (!ret) {
1641 if (uj) {
1642 json_object *json_no = NULL;
1643 json_no = json_object_new_object();
1644 json_object_string_add(
1645 json_no, "warning",
1646 "Malformed Route Distinguisher");
1647 vty_out(vty, "%s\n",
1648 json_object_to_json_string(json_no));
1649 json_object_free(json_no);
1650 } else
1651 vty_out(vty,
1652 "%% Malformed Route Distinguisher\n");
1653 return CMD_WARNING;
1654 }
1655
1656 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1657 if (ret < 0) {
1658 if (uj) {
1659 json_object *json_no = NULL;
1660 json_no = json_object_new_object();
1661 json_object_string_add(json_no, "warning",
1662 "Malformed address");
1663 vty_out(vty, "%s\n",
1664 json_object_to_json_string(json_no));
1665 json_object_free(json_no);
1666 } else
1667 vty_out(vty, "Malformed address: %s\n",
1668 argv[idx_ext_community]->arg);
1669 return CMD_WARNING;
1670 }
1671
1672 peer = peer_lookup(NULL, &su);
1673 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1674 if (uj) {
1675 json_object *json_no = NULL;
1676 json_no = json_object_new_object();
1677 json_object_string_add(
1678 json_no, "warning",
1679 "No such neighbor or address family");
1680 vty_out(vty, "%s\n",
1681 json_object_to_json_string(json_no));
1682 json_object_free(json_no);
1683 } else
1684 vty_out(vty,
1685 "%% No such neighbor or address family\n");
1686 return CMD_WARNING;
1687 }
1688
1689 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_neighbor,
1690 &su, 0, uj);
1691 }
1692 return CMD_SUCCESS;
718e3744 1693}
1694
3f227172
PG
1695DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
1696 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
1697 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
718e3744 1698 SHOW_STR
1699 IP_STR
1700 BGP_STR
3f227172
PG
1701 BGP_VPNVX_HELP_STR
1702 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 1703 "Detailed information on TCP and BGP neighbor connections\n"
1704 "Neighbor to display information about\n"
856ca177 1705 "Display the routes advertised to a BGP neighbor\n"
9973d184 1706 JSON_STR)
718e3744 1707{
d62a17ae 1708 int idx_ipv4 = 6;
1709 int ret;
1710 struct peer *peer;
1711 union sockunion su;
d7c0a89a 1712 uint8_t uj = use_json(argc, argv);
d62a17ae 1713 afi_t afi;
1714 int idx = 0;
1715
1716 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1717 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1718 if (ret < 0) {
1719 if (uj) {
1720 json_object *json_no = NULL;
1721 json_no = json_object_new_object();
1722 json_object_string_add(json_no, "warning",
1723 "Malformed address");
1724 vty_out(vty, "%s\n",
1725 json_object_to_json_string(json_no));
1726 json_object_free(json_no);
1727 } else
1728 vty_out(vty, "Malformed address: %s\n",
1729 argv[idx_ipv4]->arg);
1730 return CMD_WARNING;
1731 }
1732 peer = peer_lookup(NULL, &su);
1733 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1734 if (uj) {
1735 json_object *json_no = NULL;
1736 json_no = json_object_new_object();
1737 json_object_string_add(
1738 json_no, "warning",
1739 "No such neighbor or address family");
1740 vty_out(vty, "%s\n",
1741 json_object_to_json_string(json_no));
1742 json_object_free(json_no);
1743 } else
1744 vty_out(vty,
1745 "%% No such neighbor or address family\n");
1746 return CMD_WARNING;
1747 }
1748 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
1749 SAFI_MPLS_VPN, uj);
1750 }
1751 return CMD_SUCCESS;
718e3744 1752}
1753
3f227172
PG
1754DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
1755 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
d114b977 1756 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
718e3744 1757 SHOW_STR
1758 IP_STR
1759 BGP_STR
3f227172 1760 BGP_VPNVX_HELP_STR
718e3744 1761 "Display information for a route distinguisher\n"
1762 "VPN Route Distinguisher\n"
1763 "Detailed information on TCP and BGP neighbor connections\n"
1764 "Neighbor to display information about\n"
856ca177 1765 "Display the routes advertised to a BGP neighbor\n"
9973d184 1766 JSON_STR)
718e3744 1767{
d62a17ae 1768 int idx_ext_community = 5;
1769 int idx_ipv4 = 7;
1770 int ret;
1771 struct peer *peer;
1772 struct prefix_rd prd;
1773 union sockunion su;
d7c0a89a 1774 uint8_t uj = use_json(argc, argv);
d62a17ae 1775 afi_t afi;
1776 int idx = 0;
1777
1778 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1779 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1780 if (ret < 0) {
1781 if (uj) {
1782 json_object *json_no = NULL;
1783 json_no = json_object_new_object();
1784 json_object_string_add(json_no, "warning",
1785 "Malformed address");
1786 vty_out(vty, "%s\n",
1787 json_object_to_json_string(json_no));
1788 json_object_free(json_no);
1789 } else
1790 vty_out(vty, "Malformed address: %s\n",
1791 argv[idx_ext_community]->arg);
1792 return CMD_WARNING;
1793 }
1794 peer = peer_lookup(NULL, &su);
1795 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1796 if (uj) {
1797 json_object *json_no = NULL;
1798 json_no = json_object_new_object();
1799 json_object_string_add(
1800 json_no, "warning",
1801 "No such neighbor or address family");
1802 vty_out(vty, "%s\n",
1803 json_object_to_json_string(json_no));
1804 json_object_free(json_no);
1805 } else
1806 vty_out(vty,
1807 "%% No such neighbor or address family\n");
1808 return CMD_WARNING;
1809 }
1810
1811 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1812 if (!ret) {
1813 if (uj) {
1814 json_object *json_no = NULL;
1815 json_no = json_object_new_object();
1816 json_object_string_add(
1817 json_no, "warning",
1818 "Malformed Route Distinguisher");
1819 vty_out(vty, "%s\n",
1820 json_object_to_json_string(json_no));
1821 json_object_free(json_no);
1822 } else
1823 vty_out(vty,
1824 "%% Malformed Route Distinguisher\n");
1825 return CMD_WARNING;
1826 }
1827
1828 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
1829 SAFI_MPLS_VPN, uj);
1830 }
1831 return CMD_SUCCESS;
718e3744 1832}
d6902373 1833#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 1834
d62a17ae 1835void bgp_mplsvpn_init(void)
718e3744 1836{
d62a17ae 1837 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
1838 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
1839 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
718e3744 1840
d62a17ae 1841 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
1842 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
c286be96 1843
d62a17ae 1844 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
af8528fa 1845 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
d6902373 1846#ifdef KEEP_OLD_VPN_COMMANDS
af8528fa 1847 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
d62a17ae 1848 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
1849 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
1850 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
1851 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
1852 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
1853 install_element(VIEW_NODE,
1854 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
1855 install_element(VIEW_NODE,
1856 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
d6902373 1857#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 1858}
301ad80a
PG
1859
1860vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
1861{
1862 struct listnode *mnode, *mnnode;
1863 struct bgp *bgp;
1864
1865 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
1866 struct ecommunity *ec;
1867
1868 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
1869 continue;
1870
1871 ec = bgp->vpn_policy[AFI_IP].import_redirect_rtlist;
1872
1873 if (ecom_intersect(ec, eckey))
1874 return bgp->vrf_id;
1875 }
1876 return VRF_UNKNOWN;
1877}