]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.c
bgpd: Implement vrf - vrf route leaking cli
[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
e70e9f8e
PZ
313int vpn_leak_label_callback(
314 mpls_label_t label,
315 void *labelid,
316 bool allocated)
317{
318 struct vpn_policy *vp = (struct vpn_policy *)labelid;
319 int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
320
321 if (debug)
322 zlog_debug("%s: label=%u, allocated=%d",
323 __func__, label, allocated);
324
325 if (!allocated) {
326 /*
327 * previously-allocated label is now invalid
328 */
329 if (CHECK_FLAG(vp->flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO) &&
330 (vp->tovpn_label != MPLS_LABEL_NONE)) {
331
332 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
333 vp->afi, bgp_get_default(), vp->bgp);
334 vp->tovpn_label = MPLS_LABEL_NONE;
335 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
336 vp->afi, bgp_get_default(), vp->bgp);
337 }
338 return 0;
339 }
340
341 /*
342 * New label allocation
343 */
344 if (!CHECK_FLAG(vp->flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) {
345
346 /*
347 * not currently configured for auto label, reject allocation
348 */
349 return -1;
350 }
351
352 if (vp->tovpn_label != MPLS_LABEL_NONE) {
353 if (label == vp->tovpn_label) {
354 /* already have same label, accept but do nothing */
355 return 0;
356 }
357 /* Shouldn't happen: different label allocation */
358 zlog_err("%s: %s had label %u but got new assignment %u",
359 __func__, vp->bgp->name_pretty, vp->tovpn_label, label);
360 /* use new one */
361 }
362
363 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
364 vp->afi, bgp_get_default(), vp->bgp);
365 vp->tovpn_label = label;
366 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
367 vp->afi, bgp_get_default(), vp->bgp);
368
369 return 0;
370}
371
ddb5b488
PZ
372static int ecom_intersect(struct ecommunity *e1, struct ecommunity *e2)
373{
374 int i;
375 int j;
376
377 if (!e1 || !e2)
378 return 0;
379
380 for (i = 0; i < e1->size; ++i) {
381 for (j = 0; j < e2->size; ++j) {
382 if (!memcmp(e1->val + (i * ECOMMUNITY_SIZE),
383 e2->val + (j * ECOMMUNITY_SIZE),
384 ECOMMUNITY_SIZE)) {
385
386 return 1;
387 }
388 }
389 }
390 return 0;
391}
392
e37fb4bf
PZ
393static bool labels_same(struct bgp_info *bi, mpls_label_t *label, uint32_t n)
394{
395 uint32_t i;
396
397 if (!bi->extra) {
398 if (!n)
399 return true;
400 else
401 return false;
402 }
403
404 if (n != bi->extra->num_labels)
405 return false;
406
407 for (i = 0; i < n; ++i) {
408 if (label[i] != bi->extra->label[i])
409 return false;
410 }
411 return true;
412}
413
414/*
415 * make encoded route labels match specified encoded label set
416 */
417static void setlabels(
418 struct bgp_info *bi,
419 mpls_label_t *label, /* array of labels */
420 uint32_t num_labels)
421{
422 if (num_labels)
423 assert(label);
424 assert(num_labels <= BGP_MAX_LABELS);
425
426 if (!num_labels) {
427 if (bi->extra)
428 bi->extra->num_labels = 0;
429 return;
430 }
431
432 struct bgp_info_extra *extra = bgp_info_extra_get(bi);
433 uint32_t i;
434
435 for (i = 0; i < num_labels; ++i) {
436 extra->label[i] = label[i];
437 if (!bgp_is_valid_label(&label[i])) {
438 bgp_set_valid_label(&extra->label[i]);
439 }
440 }
441 extra->num_labels = num_labels;
442}
443
ddb5b488
PZ
444/*
445 * returns pointer to new bgp_info upon success
446 */
447static struct bgp_info *
960035b2
PZ
448leak_update(
449 struct bgp *bgp, /* destination bgp instance */
450 struct bgp_node *bn,
451 struct attr *new_attr, /* already interned */
452 afi_t afi,
453 safi_t safi,
454 struct bgp_info *source_bi,
455 mpls_label_t *label,
e37fb4bf 456 uint32_t num_labels,
960035b2
PZ
457 void *parent,
458 struct bgp *bgp_orig,
459 struct prefix *nexthop_orig,
460 int nexthop_self_flag,
461 int debug)
ddb5b488
PZ
462{
463 struct prefix *p = &bn->p;
464 struct bgp_info *bi;
465 struct bgp_info *new;
466 char buf_prefix[PREFIX_STRLEN];
ddb5b488
PZ
467
468 if (debug) {
469 prefix2str(&bn->p, buf_prefix, sizeof(buf_prefix));
960035b2
PZ
470 zlog_debug("%s: entry: leak-to=%s, p=%s, type=%d, sub_type=%d",
471 __func__, bgp->name_pretty, buf_prefix,
472 source_bi->type, source_bi->sub_type);
ddb5b488
PZ
473 }
474
475 /*
476 * match parent
477 */
478 for (bi = bn->info; bi; bi = bi->next) {
479 if (bi->extra && bi->extra->parent == parent)
480 break;
481 }
482
483 if (bi) {
e37fb4bf
PZ
484 bool labelssame = labels_same(bi, label, num_labels);
485
ddb5b488 486 if (attrhash_cmp(bi->attr, new_attr)
e37fb4bf 487 && labelssame
ddb5b488
PZ
488 && !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
489
490 bgp_attr_unintern(&new_attr);
491 if (debug)
492 zlog_debug(
493 "%s: ->%s: %s: Found route, no change",
960035b2 494 __func__, bgp->name_pretty,
ddb5b488
PZ
495 buf_prefix);
496 return NULL;
497 }
498
499 /* attr is changed */
500 bgp_info_set_flag(bn, bi, BGP_INFO_ATTR_CHANGED);
501
502 /* Rewrite BGP route information. */
503 if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
504 bgp_info_restore(bn, bi);
505 else
506 bgp_aggregate_decrement(bgp, p, bi, afi, safi);
507 bgp_attr_unintern(&bi->attr);
508 bi->attr = new_attr;
509 bi->uptime = bgp_clock();
510
e37fb4bf
PZ
511 /*
512 * rewrite labels
513 */
514 if (!labelssame)
515 setlabels(bi, label, num_labels);
516
960035b2
PZ
517 if (nexthop_self_flag)
518 bgp_info_set_flag(bn, bi, BGP_INFO_ANNC_NH_SELF);
519
520 struct bgp *bgp_nexthop = bgp;
521 int nh_valid;
522
523 if (bi->extra && bi->extra->bgp_orig)
524 bgp_nexthop = bi->extra->bgp_orig;
525
526 /* No nexthop tracking for redistributed routes */
527 if (source_bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
528 nh_valid = 1;
529 else
530 /*
531 * TBD do we need to do anything about the
532 * 'connected' parameter?
533 */
534 nh_valid = bgp_find_or_add_nexthop(
535 bgp, bgp_nexthop,
536 afi, bi, NULL, 0);
537
538 if (debug)
539 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
540 __func__, (nh_valid ? "" : "not "),
541 bgp_nexthop->name_pretty);
542
543 if (nh_valid)
544 bgp_info_set_flag(bn, bi, BGP_INFO_VALID);
545
ddb5b488
PZ
546 /* Process change. */
547 bgp_aggregate_increment(bgp, p, bi, afi, safi);
548 bgp_process(bgp, bn, afi, safi);
549 bgp_unlock_node(bn);
550
551 if (debug)
552 zlog_debug("%s: ->%s: %s Found route, changed attr",
960035b2 553 __func__, bgp->name_pretty, buf_prefix);
ddb5b488
PZ
554
555 return NULL;
556 }
557
960035b2
PZ
558 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
559 bgp->peer_self, new_attr, bn);
560
561 if (nexthop_self_flag)
562 bgp_info_set_flag(bn, new, BGP_INFO_ANNC_NH_SELF);
ddb5b488 563
e37fb4bf
PZ
564 if (num_labels)
565 setlabels(new, label, num_labels);
566
ddb5b488 567 bgp_info_extra_get(new);
ddb5b488
PZ
568 new->extra->parent = parent;
569
570 if (bgp_orig)
571 new->extra->bgp_orig = bgp_orig;
572 if (nexthop_orig)
573 new->extra->nexthop_orig = *nexthop_orig;
574
960035b2
PZ
575 /*
576 * nexthop tracking for unicast routes
577 */
578 struct bgp *bgp_nexthop = bgp;
579 int nh_valid;
580
581 if (new->extra && new->extra->bgp_orig)
582 bgp_nexthop = new->extra->bgp_orig;
583
584 /*
585 * No nexthop tracking for redistributed routes because
586 * their originating protocols will do the tracking and
587 * withdraw those routes if the nexthops become unreachable
588 */
589 if (source_bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
590 nh_valid = 1;
591 else
592 /*
593 * TBD do we need to do anything about the
594 * 'connected' parameter?
595 */
596 nh_valid = bgp_find_or_add_nexthop(bgp, bgp_nexthop,
597 afi, new, NULL, 0);
598
599 if (debug)
600 zlog_debug("%s: nexthop is %svalid (in vrf %s)",
601 __func__, (nh_valid ? "" : "not "),
602 bgp_nexthop->name_pretty);
603 if (nh_valid)
604 bgp_info_set_flag(bn, new, BGP_INFO_VALID);
605
ddb5b488
PZ
606 bgp_aggregate_increment(bgp, p, new, afi, safi);
607 bgp_info_add(bn, new);
608
609 bgp_unlock_node(bn);
610 bgp_process(bgp, bn, afi, safi);
611
612 if (debug)
613 zlog_debug("%s: ->%s: %s: Added new route", __func__,
960035b2 614 bgp->name_pretty, buf_prefix);
ddb5b488
PZ
615
616 return new;
617}
618
619/* cf vnc_import_bgp_add_route_mode_nvegroup() and add_vnc_route() */
620void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
621 struct bgp *bgp_vrf, /* from */
622 struct bgp_info *info_vrf) /* route */
623{
624 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
625 struct prefix *p = &info_vrf->net->p;
626 afi_t afi = family2afi(p->family);
627 struct attr static_attr = {0};
628 struct attr *new_attr = NULL;
629 safi_t safi = SAFI_MPLS_VPN;
630 mpls_label_t label_val;
631 mpls_label_t label;
632 struct bgp_node *bn;
633 const char *debugmsg;
960035b2
PZ
634 int nexthop_self_flag = 0;
635
636 if (debug)
637 zlog_debug("%s: from vrf %s", __func__, bgp_vrf->name_pretty);
ddb5b488 638
c8f57349
DS
639 if (debug && info_vrf->attr->ecommunity) {
640 char *s = ecommunity_ecom2str(info_vrf->attr->ecommunity,
641 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 642
12a844a5
DS
643 zlog_debug("%s: %s info_vrf->type=%d, EC{%s}", __func__,
644 bgp_vrf->name, info_vrf->type, s);
c8f57349 645 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
646 }
647
648 if (!bgp_vpn)
649 return;
650
651 if (!afi) {
652 if (debug)
653 zlog_debug("%s: can't get afi of prefix", __func__);
654 return;
655 }
656
657 /* loop check */
658 if (info_vrf->extra && info_vrf->extra->bgp_orig == bgp_vpn)
659 return;
660
661
662 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
663 if (debug)
12a844a5
DS
664 zlog_debug("%s: %s skipping: %s", __func__,
665 bgp_vrf->name, debugmsg);
ddb5b488
PZ
666 return;
667 }
668
669 bgp_attr_dup(&static_attr, info_vrf->attr); /* shallow copy */
670
671 /*
672 * route map handling
673 */
674 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
675 struct bgp_info info;
676 route_map_result_t ret;
677
678 memset(&info, 0, sizeof(info));
679 info.peer = bgp_vpn->peer_self;
680 info.attr = &static_attr;
681 ret = route_map_apply(
682 bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN],
683 p, RMAP_BGP, &info);
684 if (RMAP_DENYMATCH == ret) {
685 bgp_attr_flush(&static_attr); /* free any added parts */
686 if (debug)
687 zlog_debug(
688 "%s: vrf %s route map \"%s\" says DENY, returning",
960035b2 689 __func__, bgp_vrf->name_pretty,
ddb5b488
PZ
690 bgp_vrf->vpn_policy[afi]
691 .rmap[BGP_VPN_POLICY_DIR_TOVPN]
692 ->name);
693 return;
694 }
695 }
696
c8f57349
DS
697 if (debug && static_attr.ecommunity) {
698 char *s = ecommunity_ecom2str(static_attr.ecommunity,
699 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 700
ddb5b488
PZ
701 zlog_debug("%s: post route map static_attr.ecommunity{%s}",
702 __func__, s);
c8f57349 703 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
704 }
705
706 /*
707 * Add the vpn-policy rt-list
708 */
709 struct ecommunity *old_ecom;
710 struct ecommunity *new_ecom;
711
712 old_ecom = static_attr.ecommunity;
713 if (old_ecom) {
714 new_ecom = ecommunity_merge(
715 ecommunity_dup(old_ecom),
716 bgp_vrf->vpn_policy[afi]
717 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
718 if (!old_ecom->refcnt)
719 ecommunity_free(&old_ecom);
720 } else {
721 new_ecom = ecommunity_dup(
722 bgp_vrf->vpn_policy[afi]
723 .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
724 }
725 static_attr.ecommunity = new_ecom;
726 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
727
c8f57349
DS
728 if (debug && static_attr.ecommunity) {
729 char *s = ecommunity_ecom2str(static_attr.ecommunity,
730 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 731
ddb5b488
PZ
732 zlog_debug("%s: post merge static_attr.ecommunity{%s}",
733 __func__, s);
c8f57349 734 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
735 }
736
737 /* Nexthop */
738 /* if policy nexthop not set, use 0 */
739 if (CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
740 BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
ddb5b488
PZ
741 struct prefix *nexthop =
742 &bgp_vrf->vpn_policy[afi].tovpn_nexthop;
12a844a5 743
ddb5b488
PZ
744 switch (nexthop->family) {
745 case AF_INET:
746 /* prevent mp_nexthop_global_in <- self in bgp_route.c
747 */
748 static_attr.nexthop.s_addr = nexthop->u.prefix4.s_addr;
749
750 static_attr.mp_nexthop_global_in = nexthop->u.prefix4;
751 static_attr.mp_nexthop_len = 4;
752 break;
753
754 case AF_INET6:
755 static_attr.mp_nexthop_global = nexthop->u.prefix6;
756 static_attr.mp_nexthop_len = 16;
757 break;
758
759 default:
760 assert(0);
761 }
762 } else {
12a844a5
DS
763 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
764 BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
765 if (afi == AFI_IP) {
766 /* For ipv4, copy to multiprotocol nexthop field */
767 static_attr.mp_nexthop_global_in = static_attr.nexthop;
768 static_attr.mp_nexthop_len = 4;
769 /* XXX Leave static_attr.nexthop intact for NHT */
770 static_attr.flag &= ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
771 }
772 } else {
773 switch (afi) {
774 case AFI_IP:
775 static_attr.mp_nexthop_global_in.s_addr =
776 static_attr.nexthop.s_addr;
777 static_attr.mp_nexthop_len = 4;
778 static_attr.flag |=
779 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
780 break;
781 case AFI_IP6:
782 break;
783 case AFI_L2VPN:
784 case AFI_MAX:
785 assert(!"Unexpected AFI to process");
786 break;
787 }
ddb5b488 788 }
960035b2 789 nexthop_self_flag = 1;
ddb5b488
PZ
790 }
791
792 label_val = bgp_vrf->vpn_policy[afi].tovpn_label;
793 if (label_val == MPLS_LABEL_NONE) {
291e32c3 794 encode_label(MPLS_LABEL_IMPLICIT_NULL, &label);
ddb5b488
PZ
795 } else {
796 encode_label(label_val, &label);
797 }
798
799 /* Set originator ID to "me" */
800 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID));
801 static_attr.originator_id = bgp_vpn->router_id;
802
803
804 new_attr = bgp_attr_intern(
805 &static_attr); /* hashed refcounted everything */
806 bgp_attr_flush(&static_attr); /* free locally-allocated parts */
807
c3e345b1
DS
808 if (debug && new_attr->ecommunity) {
809 char *s = ecommunity_ecom2str(new_attr->ecommunity,
810 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 811
ddb5b488 812 zlog_debug("%s: new_attr->ecommunity{%s}", __func__, s);
c3e345b1 813 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
814 }
815
816 /* Now new_attr is an allocated interned attr */
817
818 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
819 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
820
821 struct bgp_info *new_info;
822
823 new_info = leak_update(bgp_vpn, bn, new_attr, afi, safi, info_vrf,
960035b2
PZ
824 &label, 1, info_vrf, bgp_vrf, NULL,
825 nexthop_self_flag, debug);
ddb5b488
PZ
826
827 /*
828 * Routes actually installed in the vpn RIB must also be
829 * offered to all vrfs (because now they originate from
830 * the vpn RIB).
831 *
832 * Acceptance into other vrfs depends on rt-lists.
833 * Originating vrf will not accept the looped back route
834 * because of loop checking.
835 */
836 if (new_info)
837 vpn_leak_to_vrf_update(bgp_vrf, new_info);
838}
839
840void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
841 struct bgp *bgp_vrf, /* from */
842 struct bgp_info *info_vrf) /* route */
843{
844 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
845 struct prefix *p = &info_vrf->net->p;
846 afi_t afi = family2afi(p->family);
847 safi_t safi = SAFI_MPLS_VPN;
848 struct bgp_info *bi;
849 struct bgp_node *bn;
850 const char *debugmsg;
960035b2
PZ
851 char buf_prefix[PREFIX_STRLEN];
852
853 if (debug) {
854 prefix2str(p, buf_prefix, sizeof(buf_prefix));
855 zlog_debug(
856 "%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
857 __func__, bgp_vrf->name_pretty, buf_prefix,
858 info_vrf->type, info_vrf->sub_type);
859 }
ddb5b488
PZ
860
861 if (info_vrf->type != ZEBRA_ROUTE_BGP) {
862 if (debug)
863 zlog_debug("%s: wrong type %d", __func__,
864 info_vrf->type);
865 return;
866 }
867 if (info_vrf->sub_type != BGP_ROUTE_NORMAL
868 && info_vrf->sub_type != BGP_ROUTE_STATIC) {
869
870 if (debug)
871 zlog_debug("%s: wrong sub_type %d", __func__,
872 info_vrf->sub_type);
873 return;
874 }
875 if (!bgp_vpn)
876 return;
877
878 if (!afi) {
879 if (debug)
880 zlog_debug("%s: can't get afi of prefix", __func__);
881 return;
882 }
883
884 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
885 if (debug)
886 zlog_debug("%s: skipping: %s", __func__, debugmsg);
887 return;
888 }
889
890 if (debug)
891 zlog_debug("%s: withdrawing (info_vrf=%p)", __func__, info_vrf);
892
893 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
894 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
895
896 /*
897 * vrf -> vpn
898 * match original bi imported from
899 */
900 for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
901 if (bi->extra && bi->extra->parent == info_vrf) {
902 break;
903 }
904 }
905
906 if (bi) {
907 /* withdraw from looped vrfs as well */
908 vpn_leak_to_vrf_withdraw(bgp_vpn, bi);
909
910 bgp_aggregate_decrement(bgp_vpn, p, bi, afi, safi);
911 bgp_info_delete(bn, bi);
912 bgp_process(bgp_vpn, bn, afi, safi);
913 }
914 bgp_unlock_node(bn);
915}
916
917void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
918 struct bgp *bgp_vrf, /* from */
919 afi_t afi)
920{
921 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
922 struct bgp_node *prn;
923 safi_t safi = SAFI_MPLS_VPN;
924
925 /*
ddb5b488
PZ
926 * Walk vpn table, delete bi with bgp_orig == bgp_vrf
927 */
928 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
929 prn = bgp_route_next(prn)) {
930
931 struct bgp_table *table;
932 struct bgp_node *bn;
933 struct bgp_info *bi;
934
935 /* This is the per-RD table of prefixes */
936 table = prn->info;
937
938 if (!table)
939 continue;
940
941 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
942
943 char buf[PREFIX2STR_BUFFER];
944
945 if (debug && bn->info) {
946 zlog_debug(
947 "%s: looking at prefix %s", __func__,
948 prefix2str(&bn->p, buf, sizeof(buf)));
949 }
950
951 for (bi = bn->info; bi; bi = bi->next) {
952 if (debug)
953 zlog_debug("%s: type %d, sub_type %d",
954 __func__, bi->type,
955 bi->sub_type);
956 if (bi->sub_type != BGP_ROUTE_IMPORTED)
957 continue;
958 if (!bi->extra)
959 continue;
960 if ((struct bgp *)bi->extra->bgp_orig
961 == bgp_vrf) {
962 /* delete route */
963 if (debug)
964 zlog_debug("%s: deleting it\n",
965 __func__);
966 bgp_aggregate_decrement(bgp_vpn, &bn->p,
967 bi, afi, safi);
968 bgp_info_delete(bn, bi);
969 bgp_process(bgp_vpn, bn, afi, safi);
970 }
971 }
972 }
973 }
974}
975
976void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn, /* to */
977 struct bgp *bgp_vrf, /* from */
978 afi_t afi)
979{
980 struct bgp_node *bn;
981 struct bgp_info *bi;
982 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
983
984 if (debug)
985 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__, afi,
960035b2 986 bgp_vrf->name_pretty);
ddb5b488
PZ
987
988 for (bn = bgp_table_top(bgp_vrf->rib[afi][SAFI_UNICAST]); bn;
989 bn = bgp_route_next(bn)) {
990
991 if (debug)
992 zlog_debug("%s: node=%p", __func__, bn);
993
994 for (bi = bn->info; bi; bi = bi->next) {
995 if (debug)
996 zlog_debug(
997 "%s: calling vpn_leak_from_vrf_update",
998 __func__);
999 vpn_leak_from_vrf_update(bgp_vpn, bgp_vrf, bi);
1000 }
1001 }
1002}
1003
1004static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
1005 struct bgp *bgp_vpn, /* from */
1006 struct bgp_info *info_vpn) /* route */
1007{
1008 struct prefix *p = &info_vpn->net->p;
1009 afi_t afi = family2afi(p->family);
1010
ddb5b488
PZ
1011 struct attr static_attr = {0};
1012 struct attr *new_attr = NULL;
1013 struct bgp_node *bn;
1014 safi_t safi = SAFI_UNICAST;
1015 const char *debugmsg;
1016 struct prefix nexthop_orig;
1017 mpls_label_t *pLabels = NULL;
e37fb4bf 1018 uint32_t num_labels = 0;
960035b2 1019 int nexthop_self_flag = 1;
513bf8d6
PZ
1020 struct bgp_info *bi_ultimate = NULL;
1021 int origin_local = 0;
d6632478 1022 struct bgp *src_vrf;
ddb5b488
PZ
1023
1024 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1025
b9c7bc5a 1026 if (!vpn_leak_from_vpn_active(bgp_vrf, afi, &debugmsg)) {
ddb5b488
PZ
1027 if (debug)
1028 zlog_debug("%s: skipping: %s", __func__, debugmsg);
1029 return;
1030 }
1031
1032 /* Check for intersection of route targets */
1033 if (!ecom_intersect(
1034 bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1035 info_vpn->attr->ecommunity)) {
1036
1037 return;
1038 }
1039
1040 if (debug)
960035b2
PZ
1041 zlog_debug("%s: updating to vrf %s", __func__,
1042 bgp_vrf->name_pretty);
ddb5b488
PZ
1043
1044 bgp_attr_dup(&static_attr, info_vpn->attr); /* shallow copy */
1045
1046 /*
1047 * Nexthop: stash and clear
1048 *
1049 * Nexthop is valid in context of VPN core, but not in destination vrf.
1050 * Stash it for later label resolution by vrf ingress path and then
1051 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1052 */
1053 uint8_t nhfamily = NEXTHOP_FAMILY(info_vpn->attr->mp_nexthop_len);
1054
1055 memset(&nexthop_orig, 0, sizeof(nexthop_orig));
1056 nexthop_orig.family = nhfamily;
1057
1058 switch (nhfamily) {
ddb5b488
PZ
1059 case AF_INET:
1060 /* save */
1061 nexthop_orig.u.prefix4 = info_vpn->attr->mp_nexthop_global_in;
1062 nexthop_orig.prefixlen = 32;
12a844a5
DS
1063
1064 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1065 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1066 static_attr.nexthop.s_addr =
1067 nexthop_orig.u.prefix4.s_addr;
1068
1069 static_attr.mp_nexthop_global_in =
1070 info_vpn->attr->mp_nexthop_global_in;
1071 static_attr.mp_nexthop_len =
1072 info_vpn->attr->mp_nexthop_len;
1073 }
ddb5b488 1074 static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
ddb5b488 1075 break;
ddb5b488
PZ
1076 case AF_INET6:
1077 /* save */
1078 nexthop_orig.u.prefix6 = info_vpn->attr->mp_nexthop_global;
1079 nexthop_orig.prefixlen = 128;
12a844a5
DS
1080
1081 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1082 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1083 static_attr.mp_nexthop_global = nexthop_orig.u.prefix6;
1084 static_attr.mp_nexthop_len = 16;
1085 }
ddb5b488
PZ
1086 break;
1087 }
1088
ddb5b488
PZ
1089 /*
1090 * route map handling
ddb5b488 1091 */
ddb5b488
PZ
1092 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
1093 struct bgp_info info;
1094 route_map_result_t ret;
1095
1096 memset(&info, 0, sizeof(info));
1097 info.peer = bgp_vrf->peer_self;
1098 info.attr = &static_attr;
1099 ret = route_map_apply(bgp_vrf->vpn_policy[afi]
1100 .rmap[BGP_VPN_POLICY_DIR_FROMVPN],
1101 p, RMAP_BGP, &info);
1102 if (RMAP_DENYMATCH == ret) {
1103 bgp_attr_flush(&static_attr); /* free any added parts */
1104 if (debug)
1105 zlog_debug(
1106 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
960035b2 1107 __func__, bgp_vrf->name_pretty,
ddb5b488
PZ
1108 bgp_vrf->vpn_policy[afi]
1109 .rmap[BGP_VPN_POLICY_DIR_FROMVPN]
1110 ->name);
1111 return;
1112 }
960035b2
PZ
1113 /*
1114 * if route-map changed nexthop, don't nexthop-self on output
1115 */
1116 if (!CHECK_FLAG(static_attr.rmap_change_flags,
1117 BATTR_RMAP_NEXTHOP_UNCHANGED))
1118 nexthop_self_flag = 0;
ddb5b488
PZ
1119 }
1120
1121 new_attr = bgp_attr_intern(&static_attr);
1122 bgp_attr_flush(&static_attr);
1123
1124 bn = bgp_afi_node_get(bgp_vrf->rib[afi][safi], afi, safi, p, NULL);
1125
1126 /*
1127 * ensure labels are copied
513bf8d6
PZ
1128 *
1129 * However, there is a special case: if the route originated in
1130 * another local VRF (as opposed to arriving via VPN), then the
1131 * nexthop is reached by hairpinning through this router (me)
1132 * using IP forwarding only (no LSP). Therefore, the route
1133 * imported to the VRF should not have labels attached. Note
1134 * that nexthop tracking is also involved: eliminating the
1135 * labels for these routes enables the non-labeled nexthops
1136 * from the originating VRF to be considered valid for this route.
ddb5b488 1137 */
12a844a5
DS
1138 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1139 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1140 /* work back to original route */
1141 for (bi_ultimate = info_vpn;
1142 bi_ultimate->extra && bi_ultimate->extra->parent;
1143 bi_ultimate = bi_ultimate->extra->parent)
1144 ;
513bf8d6 1145
12a844a5
DS
1146 /*
1147 * if original route was unicast,
1148 * then it did not arrive over vpn
1149 */
1150 if (bi_ultimate->net) {
1151 struct bgp_table *table;
513bf8d6 1152
12a844a5
DS
1153 table = bgp_node_table(bi_ultimate->net);
1154 if (table && (table->safi == SAFI_UNICAST))
1155 origin_local = 1;
1156 }
513bf8d6 1157
12a844a5
DS
1158 /* copy labels */
1159 if (!origin_local &&
1160 info_vpn->extra && info_vpn->extra->num_labels) {
1161 num_labels = info_vpn->extra->num_labels;
1162 if (num_labels > BGP_MAX_LABELS)
1163 num_labels = BGP_MAX_LABELS;
1164 pLabels = info_vpn->extra->label;
1165 }
ddb5b488 1166 }
513bf8d6 1167
ddb5b488
PZ
1168 if (debug) {
1169 char buf_prefix[PREFIX_STRLEN];
1170 prefix2str(p, buf_prefix, sizeof(buf_prefix));
1171 zlog_debug("%s: pfx %s: num_labels %d", __func__, buf_prefix,
1172 num_labels);
1173 }
1174
d6632478
PZ
1175 if (info_vpn->extra && info_vpn->extra->bgp_orig)
1176 src_vrf = info_vpn->extra->bgp_orig;
1177 else
1178 src_vrf = bgp_vpn;
1179
960035b2
PZ
1180 leak_update(bgp_vrf, bn, new_attr, afi, safi, info_vpn,
1181 pLabels, num_labels,
1182 info_vpn, /* parent */
d6632478 1183 src_vrf, &nexthop_orig, nexthop_self_flag, debug);
ddb5b488
PZ
1184}
1185
1186void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
1187 struct bgp_info *info_vpn) /* route */
1188{
1189 struct listnode *mnode, *mnnode;
1190 struct bgp *bgp;
1191
1192 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1193
1194 if (debug)
1195 zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
1196
1197 /* Loop over VRFs */
1198 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
1199
1200 if (!info_vpn->extra
1201 || info_vpn->extra->bgp_orig != bgp) { /* no loop */
1202 vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, info_vpn);
1203 }
1204 }
1205}
1206
1207void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
1208 struct bgp_info *info_vpn) /* route */
1209{
1b3510a0
PZ
1210 struct prefix *p;
1211 afi_t afi;
ddb5b488
PZ
1212 safi_t safi = SAFI_UNICAST;
1213 struct bgp *bgp;
1214 struct listnode *mnode, *mnnode;
ddb5b488
PZ
1215 struct bgp_node *bn;
1216 struct bgp_info *bi;
1217 const char *debugmsg;
960035b2 1218 char buf_prefix[PREFIX_STRLEN];
ddb5b488
PZ
1219
1220 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1221
960035b2
PZ
1222 if (debug) {
1223 prefix2str(&info_vpn->net->p, buf_prefix, sizeof(buf_prefix));
1224 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d",
1225 __func__, buf_prefix,
1226 info_vpn->type, info_vpn->sub_type);
1227 }
1228
ddb5b488
PZ
1229 if (debug)
1230 zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
1231
1b3510a0 1232 if (!info_vpn->net) {
56c2c080 1233#if ENABLE_BGP_VNC
1b3510a0
PZ
1234 /* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
1235 if (info_vpn->type == ZEBRA_ROUTE_BGP &&
1236 info_vpn->sub_type == BGP_ROUTE_RFP) {
1237
1238 return;
1239 }
56c2c080 1240#endif
1b3510a0
PZ
1241 if (debug)
1242 zlog_debug("%s: info_vpn->net unexpectedly NULL, no prefix, bailing",
1243 __func__);
1244 return;
1245 }
1246
1247 p = &info_vpn->net->p;
1248 afi = family2afi(p->family);
ddb5b488
PZ
1249
1250 /* Loop over VRFs */
1251 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
b9c7bc5a 1252 if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
ddb5b488
PZ
1253 if (debug)
1254 zlog_debug("%s: skipping: %s", __func__,
1255 debugmsg);
1256 continue;
1257 }
1258
1259 /* Check for intersection of route targets */
1260 if (!ecom_intersect(bgp->vpn_policy[afi]
1261 .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1262 info_vpn->attr->ecommunity)) {
1263
1264 continue;
1265 }
1266
1267 if (debug)
1268 zlog_debug("%s: withdrawing from vrf %s", __func__,
960035b2 1269 bgp->name_pretty);
ddb5b488
PZ
1270
1271 bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
1272 for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
1273 if (bi->extra
1274 && (struct bgp_info *)bi->extra->parent
1275 == info_vpn) {
1276 break;
1277 }
1278 }
1279
1280 if (bi) {
1281 if (debug)
1282 zlog_debug("%s: deleting bi %p", __func__, bi);
1283 bgp_aggregate_decrement(bgp, p, bi, afi, safi);
1284 bgp_info_delete(bn, bi);
1285 bgp_process(bgp, bn, afi, safi);
1286 }
1287 bgp_unlock_node(bn);
1288 }
1289}
1290
1291void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
1292 afi_t afi)
1293{
1294 struct bgp_node *bn;
1295 struct bgp_info *bi;
1296 safi_t safi = SAFI_UNICAST;
1297 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1298 struct bgp *bgp_vpn = bgp_get_default();
1299
1300 if (debug)
1301 zlog_debug("%s: entry", __func__);
1302 /*
1303 * Walk vrf table, delete bi with bgp_orig == bgp_vpn
1304 */
1305 for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
1306 bn = bgp_route_next(bn)) {
1307
1308 for (bi = bn->info; bi; bi = bi->next) {
1309 if (bi->extra && bi->extra->bgp_orig == bgp_vpn) {
1310
1311 /* delete route */
1312 bgp_aggregate_decrement(bgp_vrf, &bn->p, bi,
1313 afi, safi);
1314 bgp_info_delete(bn, bi);
1315 bgp_process(bgp_vrf, bn, afi, safi);
1316 }
1317 }
1318 }
1319}
1320
1321void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
1322 struct bgp *bgp_vpn, /* from */
1323 afi_t afi)
1324{
1325 struct prefix_rd prd;
1326 struct bgp_node *prn;
1327 safi_t safi = SAFI_MPLS_VPN;
1328
1329 /*
1330 * Walk vpn table
1331 */
1332 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
1333 prn = bgp_route_next(prn)) {
1334
1335 struct bgp_table *table;
1336 struct bgp_node *bn;
1337 struct bgp_info *bi;
1338
1339 memset(&prd, 0, sizeof(prd));
1340 prd.family = AF_UNSPEC;
1341 prd.prefixlen = 64;
1342 memcpy(prd.val, prn->p.u.val, 8);
1343
1344 /* This is the per-RD table of prefixes */
1345 table = prn->info;
1346
1347 if (!table)
1348 continue;
1349
1350 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
1351
1352 for (bi = bn->info; bi; bi = bi->next) {
1353
1354 if (bi->extra && bi->extra->bgp_orig == bgp_vrf)
1355 continue;
1356
1357 vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
1358 bi);
1359 }
1360 }
1361 }
1362}
1363
d92a55df
PZ
1364/*
1365 * This function is called for definition/deletion/change to a route-map
1366 */
ddb5b488
PZ
1367static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
1368{
1369 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1370 afi_t afi;
1371 struct route_map *rmap;
1372
1373 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1374 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
1375
1376 return;
1377 }
1378
1379 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
1380
1381 for (afi = 0; afi < AFI_MAX; ++afi) {
1382
d92a55df
PZ
1383 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
1384 && !strcmp(rmap_name,
ddb5b488
PZ
1385 bgp->vpn_policy[afi]
1386 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
1387
1388 if (debug)
1389 zlog_debug(
1390 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1391 __func__, rmap_name, bgp->as,
1392 afi2str(afi));
1393
1394 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1395 bgp_get_default(), bgp);
1396 if (debug)
1397 zlog_debug("%s: after vpn_leak_prechange",
1398 __func__);
1399
d92a55df
PZ
1400 /* in case of definition/deletion */
1401 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN] =
1402 rmap;
ddb5b488
PZ
1403
1404 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1405 bgp_get_default(), bgp);
d92a55df 1406
ddb5b488
PZ
1407 if (debug)
1408 zlog_debug("%s: after vpn_leak_postchange",
1409 __func__);
1410 }
1411
d92a55df
PZ
1412 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]
1413 && !strcmp(rmap_name,
1414 bgp->vpn_policy[afi]
1415 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN])) {
b9c7bc5a
PZ
1416
1417 if (debug) {
1418 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
ddb5b488
PZ
1419 __func__, rmap_name, bgp->as,
1420 afi2str(afi));
b9c7bc5a 1421 }
ddb5b488
PZ
1422
1423 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1424 bgp_get_default(), bgp);
1425
d92a55df
PZ
1426 /* in case of definition/deletion */
1427 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
1428 rmap;
ddb5b488
PZ
1429
1430 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1431 bgp_get_default(), bgp);
1432 }
1433 }
1434}
1435
1436void vpn_policy_routemap_event(const char *rmap_name)
1437{
1438 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1439 struct listnode *mnode, *mnnode;
1440 struct bgp *bgp;
1441
1442 if (debug)
1443 zlog_debug("%s: entry", __func__);
1444
1445 if (bm->bgp == NULL) /* may be called during cleanup */
1446 return;
1447
1448 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
1449 vpn_policy_routemap_update(bgp, rmap_name);
1450}
1451
718e3744 1452/* For testing purpose, static route of MPLS-VPN. */
1453DEFUN (vpnv4_network,
1454 vpnv4_network_cmd,
d114b977 1455 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1456 "Specify a network to announce via BGP\n"
0c7b1b01 1457 "IPv4 prefix\n"
718e3744 1458 "Specify Route Distinguisher\n"
1459 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1460 "VPN NLRI label (tag)\n"
1461 "VPN NLRI label (tag)\n"
1462 "Label value\n")
718e3744 1463{
d62a17ae 1464 int idx_ipv4_prefixlen = 1;
1465 int idx_ext_community = 3;
1466 int idx_label = 5;
1467 return bgp_static_set_safi(
1468 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1469 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
1470 NULL, NULL, NULL, NULL);
137446f9
LB
1471}
1472
1473DEFUN (vpnv4_network_route_map,
1474 vpnv4_network_route_map_cmd,
d114b977 1475 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
137446f9 1476 "Specify a network to announce via BGP\n"
0c7b1b01 1477 "IPv4 prefix\n"
137446f9
LB
1478 "Specify Route Distinguisher\n"
1479 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1480 "VPN NLRI label (tag)\n"
1481 "VPN NLRI label (tag)\n"
1482 "Label value\n"
137446f9
LB
1483 "route map\n"
1484 "route map name\n")
1485{
d62a17ae 1486 int idx_ipv4_prefixlen = 1;
1487 int idx_ext_community = 3;
1488 int idx_label = 5;
1489 int idx_word_2 = 7;
1490 return bgp_static_set_safi(
1491 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1492 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1493 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
718e3744 1494}
1495
1496/* For testing purpose, static route of MPLS-VPN. */
1497DEFUN (no_vpnv4_network,
1498 no_vpnv4_network_cmd,
d114b977 1499 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1500 NO_STR
1501 "Specify a network to announce via BGP\n"
0c7b1b01 1502 "IPv4 prefix\n"
718e3744 1503 "Specify Route Distinguisher\n"
1504 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1505 "VPN NLRI label (tag)\n"
1506 "VPN NLRI label (tag)\n"
1507 "Label value\n")
718e3744 1508{
d62a17ae 1509 int idx_ipv4_prefixlen = 2;
1510 int idx_ext_community = 4;
1511 int idx_label = 6;
1512 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
1513 argv[idx_ipv4_prefixlen]->arg,
1514 argv[idx_ext_community]->arg,
1515 argv[idx_label]->arg, 0, NULL, NULL, NULL);
718e3744 1516}
1517
c286be96
LX
1518DEFUN (vpnv6_network,
1519 vpnv6_network_cmd,
d114b977 1520 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
c286be96
LX
1521 "Specify a network to announce via BGP\n"
1522 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1523 "Specify Route Distinguisher\n"
1524 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1525 "VPN NLRI label (tag)\n"
1526 "VPN NLRI label (tag)\n"
1527 "Label value\n"
11daee81
DS
1528 "route map\n"
1529 "route map name\n")
c286be96 1530{
d62a17ae 1531 int idx_ipv6_prefix = 1;
1532 int idx_ext_community = 3;
1533 int idx_label = 5;
1534 int idx_word_2 = 7;
1535 if (argc == 8)
1536 return bgp_static_set_safi(
1537 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1538 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1539 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
1540 else
1541 return bgp_static_set_safi(
1542 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1543 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1544 NULL, 0, NULL, NULL, NULL, NULL);
c286be96
LX
1545}
1546
1547/* For testing purpose, static route of MPLS-VPN. */
1548DEFUN (no_vpnv6_network,
1549 no_vpnv6_network_cmd,
d114b977 1550 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
c286be96
LX
1551 NO_STR
1552 "Specify a network to announce via BGP\n"
1553 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1554 "Specify Route Distinguisher\n"
1555 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1556 "VPN NLRI label (tag)\n"
1557 "VPN NLRI label (tag)\n"
1558 "Label value\n")
c286be96 1559{
d62a17ae 1560 int idx_ipv6_prefix = 2;
1561 int idx_ext_community = 4;
1562 int idx_label = 6;
1563 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
1564 argv[idx_ipv6_prefix]->arg,
1565 argv[idx_ext_community]->arg,
1566 argv[idx_label]->arg, 0, NULL, NULL, NULL);
c286be96
LX
1567}
1568
d62a17ae 1569int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
1570 enum bgp_show_type type, void *output_arg, int tags,
d7c0a89a 1571 uint8_t use_json)
718e3744 1572{
d62a17ae 1573 struct bgp *bgp;
1574 struct bgp_table *table;
d62a17ae 1575
1576 bgp = bgp_get_default();
1577 if (bgp == NULL) {
1578 if (!use_json)
1579 vty_out(vty, "No BGP process is configured\n");
16307668
RW
1580 else
1581 vty_out(vty, "{}\n");
d62a17ae 1582 return CMD_WARNING;
1583 }
1ae44dfc 1584 table = bgp->rib[afi][SAFI_MPLS_VPN];
a4d82a8a
PZ
1585 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
1586 output_arg, use_json);
718e3744 1587}
1588
4f280b15
LB
1589DEFUN (show_bgp_ip_vpn_all_rd,
1590 show_bgp_ip_vpn_all_rd_cmd,
d114b977 1591 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
e3e29b32
LB
1592 SHOW_STR
1593 BGP_STR
05e588f4 1594 BGP_VPNVX_HELP_STR
e3e29b32 1595 "Display VPN NLRI specific information\n"
af8528fa 1596 "Display VPN NLRI specific information\n"
e3e29b32
LB
1597 "Display information for a route distinguisher\n"
1598 "VPN Route Distinguisher\n"
1599 JSON_STR)
1600{
d62a17ae 1601 int ret;
1602 struct prefix_rd prd;
1603 afi_t afi;
1604 int idx = 0;
1605
1606 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
3d7c4cd7 1607 if (argv_find(argv, argc, "rd", &idx)) {
a4d82a8a 1608 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
d62a17ae 1609 if (!ret) {
1610 vty_out(vty,
1611 "%% Malformed Route Distinguisher\n");
1612 return CMD_WARNING;
1613 }
1614 return bgp_show_mpls_vpn(vty, afi, &prd,
1615 bgp_show_type_normal, NULL, 0,
1616 use_json(argc, argv));
1617 } else {
1618 return bgp_show_mpls_vpn(vty, afi, NULL,
1619 bgp_show_type_normal, NULL, 0,
1620 use_json(argc, argv));
1621 }
1622 }
1623 return CMD_SUCCESS;
718e3744 1624}
1625
af8528fa
LB
1626ALIAS(show_bgp_ip_vpn_all_rd,
1627 show_bgp_ip_vpn_rd_cmd,
1628 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1629 SHOW_STR
1630 BGP_STR
1631 BGP_VPNVX_HELP_STR
1632 "Display VPN NLRI specific information\n"
1633 "Display information for a route distinguisher\n"
1634 "VPN Route Distinguisher\n"
1635 JSON_STR)
1636
1637#ifdef KEEP_OLD_VPN_COMMANDS
3f227172
PG
1638DEFUN (show_ip_bgp_vpn_rd,
1639 show_ip_bgp_vpn_rd_cmd,
af8528fa 1640 "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
718e3744 1641 SHOW_STR
1642 IP_STR
1643 BGP_STR
4f280b15 1644 BGP_AFI_HELP_STR
3517059b 1645 "Address Family modifier\n"
718e3744 1646 "Display information for a route distinguisher\n"
1647 "VPN Route Distinguisher\n")
1648{
d62a17ae 1649 int idx_ext_community = argc - 1;
1650 int ret;
1651 struct prefix_rd prd;
1652 afi_t afi;
1653 int idx = 0;
1654
1655 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1656 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1657 if (!ret) {
1658 vty_out(vty, "%% Malformed Route Distinguisher\n");
1659 return CMD_WARNING;
1660 }
1661 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1662 NULL, 0, 0);
1663 }
1664 return CMD_SUCCESS;
1665}
718e3744 1666
4f280b15
LB
1667DEFUN (show_ip_bgp_vpn_all,
1668 show_ip_bgp_vpn_all_cmd,
1669 "show [ip] bgp <vpnv4|vpnv6>",
1670 SHOW_STR
1671 IP_STR
1672 BGP_STR
1673 BGP_VPNVX_HELP_STR)
1674{
d62a17ae 1675 afi_t afi;
1676 int idx = 0;
4f280b15 1677
d62a17ae 1678 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1679 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1680 NULL, 0, 0);
1681 return CMD_SUCCESS;
4f280b15
LB
1682}
1683
3f227172
PG
1684DEFUN (show_ip_bgp_vpn_all_tags,
1685 show_ip_bgp_vpn_all_tags_cmd,
1686 "show [ip] bgp <vpnv4|vpnv6> all tags",
718e3744 1687 SHOW_STR
1688 IP_STR
1689 BGP_STR
3f227172
PG
1690 BGP_VPNVX_HELP_STR
1691 "Display information about all VPNv4/VPNV6 NLRIs\n"
718e3744 1692 "Display BGP tags for prefixes\n")
1693{
d62a17ae 1694 afi_t afi;
1695 int idx = 0;
3f227172 1696
d62a17ae 1697 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1698 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1699 NULL, 1, 0);
1700 return CMD_SUCCESS;
718e3744 1701}
1702
3f227172
PG
1703DEFUN (show_ip_bgp_vpn_rd_tags,
1704 show_ip_bgp_vpn_rd_tags_cmd,
d114b977 1705 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
718e3744 1706 SHOW_STR
1707 IP_STR
1708 BGP_STR
3f227172 1709 BGP_VPNVX_HELP_STR
718e3744 1710 "Display information for a route distinguisher\n"
1711 "VPN Route Distinguisher\n"
1712 "Display BGP tags for prefixes\n")
1713{
d62a17ae 1714 int idx_ext_community = 5;
1715 int ret;
1716 struct prefix_rd prd;
1717 afi_t afi;
1718 int idx = 0;
1719
1720 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1721 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1722 if (!ret) {
1723 vty_out(vty, "%% Malformed Route Distinguisher\n");
1724 return CMD_WARNING;
1725 }
1726 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1727 NULL, 1, 0);
1728 }
1729 return CMD_SUCCESS;
718e3744 1730}
1731
3f227172
PG
1732DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
1733 show_ip_bgp_vpn_all_neighbor_routes_cmd,
1734 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
718e3744 1735 SHOW_STR
1736 IP_STR
1737 BGP_STR
3f227172
PG
1738 BGP_VPNVX_HELP_STR
1739 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 1740 "Detailed information on TCP and BGP neighbor connections\n"
1741 "Neighbor to display information about\n"
856ca177 1742 "Display routes learned from neighbor\n"
9973d184 1743 JSON_STR)
718e3744 1744{
d62a17ae 1745 int idx_ipv4 = 6;
1746 union sockunion su;
1747 struct peer *peer;
1748 int ret;
d7c0a89a 1749 uint8_t uj = use_json(argc, argv);
d62a17ae 1750 afi_t afi;
1751 int idx = 0;
1752
1753 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1754 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1755 if (ret < 0) {
1756 if (uj) {
1757 json_object *json_no = NULL;
1758 json_no = json_object_new_object();
1759 json_object_string_add(json_no, "warning",
1760 "Malformed address");
1761 vty_out(vty, "%s\n",
1762 json_object_to_json_string(json_no));
1763 json_object_free(json_no);
1764 } else
1765 vty_out(vty, "Malformed address: %s\n",
1766 argv[idx_ipv4]->arg);
1767 return CMD_WARNING;
1768 }
1769
1770 peer = peer_lookup(NULL, &su);
1771 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1772 if (uj) {
1773 json_object *json_no = NULL;
1774 json_no = json_object_new_object();
1775 json_object_string_add(
1776 json_no, "warning",
1777 "No such neighbor or address family");
1778 vty_out(vty, "%s\n",
1779 json_object_to_json_string(json_no));
1780 json_object_free(json_no);
1781 } else
1782 vty_out(vty,
1783 "%% No such neighbor or address family\n");
1784 return CMD_WARNING;
1785 }
1786
1787 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
1788 &su, 0, uj);
1789 }
1790 return CMD_SUCCESS;
718e3744 1791}
1792
3f227172
PG
1793DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
1794 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
d114b977 1795 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
718e3744 1796 SHOW_STR
1797 IP_STR
1798 BGP_STR
3f227172 1799 BGP_VPNVX_HELP_STR
718e3744 1800 "Display information for a route distinguisher\n"
1801 "VPN Route Distinguisher\n"
1802 "Detailed information on TCP and BGP neighbor connections\n"
1803 "Neighbor to display information about\n"
856ca177 1804 "Display routes learned from neighbor\n"
9973d184 1805 JSON_STR)
718e3744 1806{
d62a17ae 1807 int idx_ext_community = 5;
1808 int idx_ipv4 = 7;
1809 int ret;
1810 union sockunion su;
1811 struct peer *peer;
1812 struct prefix_rd prd;
d7c0a89a 1813 uint8_t uj = use_json(argc, argv);
d62a17ae 1814 afi_t afi;
1815 int idx = 0;
1816
1817 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1818 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1819 if (!ret) {
1820 if (uj) {
1821 json_object *json_no = NULL;
1822 json_no = json_object_new_object();
1823 json_object_string_add(
1824 json_no, "warning",
1825 "Malformed Route Distinguisher");
1826 vty_out(vty, "%s\n",
1827 json_object_to_json_string(json_no));
1828 json_object_free(json_no);
1829 } else
1830 vty_out(vty,
1831 "%% Malformed Route Distinguisher\n");
1832 return CMD_WARNING;
1833 }
1834
1835 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1836 if (ret < 0) {
1837 if (uj) {
1838 json_object *json_no = NULL;
1839 json_no = json_object_new_object();
1840 json_object_string_add(json_no, "warning",
1841 "Malformed address");
1842 vty_out(vty, "%s\n",
1843 json_object_to_json_string(json_no));
1844 json_object_free(json_no);
1845 } else
1846 vty_out(vty, "Malformed address: %s\n",
1847 argv[idx_ext_community]->arg);
1848 return CMD_WARNING;
1849 }
1850
1851 peer = peer_lookup(NULL, &su);
1852 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1853 if (uj) {
1854 json_object *json_no = NULL;
1855 json_no = json_object_new_object();
1856 json_object_string_add(
1857 json_no, "warning",
1858 "No such neighbor or address family");
1859 vty_out(vty, "%s\n",
1860 json_object_to_json_string(json_no));
1861 json_object_free(json_no);
1862 } else
1863 vty_out(vty,
1864 "%% No such neighbor or address family\n");
1865 return CMD_WARNING;
1866 }
1867
1868 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_neighbor,
1869 &su, 0, uj);
1870 }
1871 return CMD_SUCCESS;
718e3744 1872}
1873
3f227172
PG
1874DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
1875 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
1876 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
718e3744 1877 SHOW_STR
1878 IP_STR
1879 BGP_STR
3f227172
PG
1880 BGP_VPNVX_HELP_STR
1881 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 1882 "Detailed information on TCP and BGP neighbor connections\n"
1883 "Neighbor to display information about\n"
856ca177 1884 "Display the routes advertised to a BGP neighbor\n"
9973d184 1885 JSON_STR)
718e3744 1886{
d62a17ae 1887 int idx_ipv4 = 6;
1888 int ret;
1889 struct peer *peer;
1890 union sockunion su;
d7c0a89a 1891 uint8_t uj = use_json(argc, argv);
d62a17ae 1892 afi_t afi;
1893 int idx = 0;
1894
1895 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1896 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1897 if (ret < 0) {
1898 if (uj) {
1899 json_object *json_no = NULL;
1900 json_no = json_object_new_object();
1901 json_object_string_add(json_no, "warning",
1902 "Malformed address");
1903 vty_out(vty, "%s\n",
1904 json_object_to_json_string(json_no));
1905 json_object_free(json_no);
1906 } else
1907 vty_out(vty, "Malformed address: %s\n",
1908 argv[idx_ipv4]->arg);
1909 return CMD_WARNING;
1910 }
1911 peer = peer_lookup(NULL, &su);
1912 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1913 if (uj) {
1914 json_object *json_no = NULL;
1915 json_no = json_object_new_object();
1916 json_object_string_add(
1917 json_no, "warning",
1918 "No such neighbor or address family");
1919 vty_out(vty, "%s\n",
1920 json_object_to_json_string(json_no));
1921 json_object_free(json_no);
1922 } else
1923 vty_out(vty,
1924 "%% No such neighbor or address family\n");
1925 return CMD_WARNING;
1926 }
1927 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
1928 SAFI_MPLS_VPN, uj);
1929 }
1930 return CMD_SUCCESS;
718e3744 1931}
1932
3f227172
PG
1933DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
1934 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
d114b977 1935 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
718e3744 1936 SHOW_STR
1937 IP_STR
1938 BGP_STR
3f227172 1939 BGP_VPNVX_HELP_STR
718e3744 1940 "Display information for a route distinguisher\n"
1941 "VPN Route Distinguisher\n"
1942 "Detailed information on TCP and BGP neighbor connections\n"
1943 "Neighbor to display information about\n"
856ca177 1944 "Display the routes advertised to a BGP neighbor\n"
9973d184 1945 JSON_STR)
718e3744 1946{
d62a17ae 1947 int idx_ext_community = 5;
1948 int idx_ipv4 = 7;
1949 int ret;
1950 struct peer *peer;
1951 struct prefix_rd prd;
1952 union sockunion su;
d7c0a89a 1953 uint8_t uj = use_json(argc, argv);
d62a17ae 1954 afi_t afi;
1955 int idx = 0;
1956
1957 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1958 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1959 if (ret < 0) {
1960 if (uj) {
1961 json_object *json_no = NULL;
1962 json_no = json_object_new_object();
1963 json_object_string_add(json_no, "warning",
1964 "Malformed address");
1965 vty_out(vty, "%s\n",
1966 json_object_to_json_string(json_no));
1967 json_object_free(json_no);
1968 } else
1969 vty_out(vty, "Malformed address: %s\n",
1970 argv[idx_ext_community]->arg);
1971 return CMD_WARNING;
1972 }
1973 peer = peer_lookup(NULL, &su);
1974 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1975 if (uj) {
1976 json_object *json_no = NULL;
1977 json_no = json_object_new_object();
1978 json_object_string_add(
1979 json_no, "warning",
1980 "No such neighbor or address family");
1981 vty_out(vty, "%s\n",
1982 json_object_to_json_string(json_no));
1983 json_object_free(json_no);
1984 } else
1985 vty_out(vty,
1986 "%% No such neighbor or address family\n");
1987 return CMD_WARNING;
1988 }
1989
1990 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1991 if (!ret) {
1992 if (uj) {
1993 json_object *json_no = NULL;
1994 json_no = json_object_new_object();
1995 json_object_string_add(
1996 json_no, "warning",
1997 "Malformed Route Distinguisher");
1998 vty_out(vty, "%s\n",
1999 json_object_to_json_string(json_no));
2000 json_object_free(json_no);
2001 } else
2002 vty_out(vty,
2003 "%% Malformed Route Distinguisher\n");
2004 return CMD_WARNING;
2005 }
2006
2007 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
2008 SAFI_MPLS_VPN, uj);
2009 }
2010 return CMD_SUCCESS;
718e3744 2011}
d6902373 2012#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2013
d62a17ae 2014void bgp_mplsvpn_init(void)
718e3744 2015{
d62a17ae 2016 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
2017 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
2018 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
718e3744 2019
d62a17ae 2020 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
2021 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
c286be96 2022
d62a17ae 2023 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
af8528fa 2024 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
d6902373 2025#ifdef KEEP_OLD_VPN_COMMANDS
af8528fa 2026 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
d62a17ae 2027 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
2028 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
2029 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
2030 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
2031 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
2032 install_element(VIEW_NODE,
2033 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
2034 install_element(VIEW_NODE,
2035 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
d6902373 2036#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2037}
301ad80a
PG
2038
2039vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
2040{
2041 struct listnode *mnode, *mnnode;
2042 struct bgp *bgp;
2043
2044 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2045 struct ecommunity *ec;
2046
2047 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2048 continue;
2049
2050 ec = bgp->vpn_policy[AFI_IP].import_redirect_rtlist;
2051
2052 if (ecom_intersect(ec, eckey))
2053 return bgp->vrf_id;
2054 }
2055 return VRF_UNKNOWN;
2056}