]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.c
bgpd: Auto RD definitions and encoding
[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)
d793761d 837 vpn_leak_to_vrf_update(bgp_vpn, new_info);
ddb5b488
PZ
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);
ddb5b488
PZ
1298
1299 if (debug)
1300 zlog_debug("%s: entry", __func__);
1301 /*
d793761d 1302 * Walk vrf table, delete bi with bgp_orig in a different vrf
ddb5b488
PZ
1303 */
1304 for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
1305 bn = bgp_route_next(bn)) {
1306
1307 for (bi = bn->info; bi; bi = bi->next) {
d793761d 1308 if (bi->extra && bi->extra->bgp_orig != bgp_vrf) {
ddb5b488
PZ
1309
1310 /* delete route */
1311 bgp_aggregate_decrement(bgp_vrf, &bn->p, bi,
1312 afi, safi);
1313 bgp_info_delete(bn, bi);
1314 bgp_process(bgp_vrf, bn, afi, safi);
1315 }
1316 }
1317 }
1318}
1319
1320void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
1321 struct bgp *bgp_vpn, /* from */
1322 afi_t afi)
1323{
1324 struct prefix_rd prd;
1325 struct bgp_node *prn;
1326 safi_t safi = SAFI_MPLS_VPN;
1327
1328 /*
1329 * Walk vpn table
1330 */
1331 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
1332 prn = bgp_route_next(prn)) {
1333
1334 struct bgp_table *table;
1335 struct bgp_node *bn;
1336 struct bgp_info *bi;
1337
1338 memset(&prd, 0, sizeof(prd));
1339 prd.family = AF_UNSPEC;
1340 prd.prefixlen = 64;
1341 memcpy(prd.val, prn->p.u.val, 8);
1342
1343 /* This is the per-RD table of prefixes */
1344 table = prn->info;
1345
1346 if (!table)
1347 continue;
1348
1349 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
1350
1351 for (bi = bn->info; bi; bi = bi->next) {
1352
1353 if (bi->extra && bi->extra->bgp_orig == bgp_vrf)
1354 continue;
1355
1356 vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
1357 bi);
1358 }
1359 }
1360 }
1361}
1362
d92a55df
PZ
1363/*
1364 * This function is called for definition/deletion/change to a route-map
1365 */
ddb5b488
PZ
1366static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
1367{
1368 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1369 afi_t afi;
1370 struct route_map *rmap;
1371
1372 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1373 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
1374
1375 return;
1376 }
1377
1378 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
1379
1380 for (afi = 0; afi < AFI_MAX; ++afi) {
1381
d92a55df
PZ
1382 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
1383 && !strcmp(rmap_name,
ddb5b488
PZ
1384 bgp->vpn_policy[afi]
1385 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
1386
1387 if (debug)
1388 zlog_debug(
1389 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1390 __func__, rmap_name, bgp->as,
1391 afi2str(afi));
1392
1393 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1394 bgp_get_default(), bgp);
1395 if (debug)
1396 zlog_debug("%s: after vpn_leak_prechange",
1397 __func__);
1398
d92a55df
PZ
1399 /* in case of definition/deletion */
1400 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN] =
1401 rmap;
ddb5b488
PZ
1402
1403 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1404 bgp_get_default(), bgp);
d92a55df 1405
ddb5b488
PZ
1406 if (debug)
1407 zlog_debug("%s: after vpn_leak_postchange",
1408 __func__);
1409 }
1410
d92a55df
PZ
1411 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]
1412 && !strcmp(rmap_name,
1413 bgp->vpn_policy[afi]
1414 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN])) {
b9c7bc5a
PZ
1415
1416 if (debug) {
1417 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
ddb5b488
PZ
1418 __func__, rmap_name, bgp->as,
1419 afi2str(afi));
b9c7bc5a 1420 }
ddb5b488
PZ
1421
1422 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1423 bgp_get_default(), bgp);
1424
d92a55df
PZ
1425 /* in case of definition/deletion */
1426 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
1427 rmap;
ddb5b488
PZ
1428
1429 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1430 bgp_get_default(), bgp);
1431 }
1432 }
1433}
1434
1435void vpn_policy_routemap_event(const char *rmap_name)
1436{
1437 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1438 struct listnode *mnode, *mnnode;
1439 struct bgp *bgp;
1440
1441 if (debug)
1442 zlog_debug("%s: entry", __func__);
1443
1444 if (bm->bgp == NULL) /* may be called during cleanup */
1445 return;
1446
1447 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
1448 vpn_policy_routemap_update(bgp, rmap_name);
1449}
1450
718e3744 1451/* For testing purpose, static route of MPLS-VPN. */
1452DEFUN (vpnv4_network,
1453 vpnv4_network_cmd,
d114b977 1454 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1455 "Specify a network to announce via BGP\n"
0c7b1b01 1456 "IPv4 prefix\n"
718e3744 1457 "Specify Route Distinguisher\n"
1458 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1459 "VPN NLRI label (tag)\n"
1460 "VPN NLRI label (tag)\n"
1461 "Label value\n")
718e3744 1462{
d62a17ae 1463 int idx_ipv4_prefixlen = 1;
1464 int idx_ext_community = 3;
1465 int idx_label = 5;
1466 return bgp_static_set_safi(
1467 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1468 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
1469 NULL, NULL, NULL, NULL);
137446f9
LB
1470}
1471
1472DEFUN (vpnv4_network_route_map,
1473 vpnv4_network_route_map_cmd,
d114b977 1474 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
137446f9 1475 "Specify a network to announce via BGP\n"
0c7b1b01 1476 "IPv4 prefix\n"
137446f9
LB
1477 "Specify Route Distinguisher\n"
1478 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1479 "VPN NLRI label (tag)\n"
1480 "VPN NLRI label (tag)\n"
1481 "Label value\n"
137446f9
LB
1482 "route map\n"
1483 "route map name\n")
1484{
d62a17ae 1485 int idx_ipv4_prefixlen = 1;
1486 int idx_ext_community = 3;
1487 int idx_label = 5;
1488 int idx_word_2 = 7;
1489 return bgp_static_set_safi(
1490 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1491 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1492 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
718e3744 1493}
1494
1495/* For testing purpose, static route of MPLS-VPN. */
1496DEFUN (no_vpnv4_network,
1497 no_vpnv4_network_cmd,
d114b977 1498 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1499 NO_STR
1500 "Specify a network to announce via BGP\n"
0c7b1b01 1501 "IPv4 prefix\n"
718e3744 1502 "Specify Route Distinguisher\n"
1503 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1504 "VPN NLRI label (tag)\n"
1505 "VPN NLRI label (tag)\n"
1506 "Label value\n")
718e3744 1507{
d62a17ae 1508 int idx_ipv4_prefixlen = 2;
1509 int idx_ext_community = 4;
1510 int idx_label = 6;
1511 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
1512 argv[idx_ipv4_prefixlen]->arg,
1513 argv[idx_ext_community]->arg,
1514 argv[idx_label]->arg, 0, NULL, NULL, NULL);
718e3744 1515}
1516
c286be96
LX
1517DEFUN (vpnv6_network,
1518 vpnv6_network_cmd,
d114b977 1519 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
c286be96
LX
1520 "Specify a network to announce via BGP\n"
1521 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1522 "Specify Route Distinguisher\n"
1523 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1524 "VPN NLRI label (tag)\n"
1525 "VPN NLRI label (tag)\n"
1526 "Label value\n"
11daee81
DS
1527 "route map\n"
1528 "route map name\n")
c286be96 1529{
d62a17ae 1530 int idx_ipv6_prefix = 1;
1531 int idx_ext_community = 3;
1532 int idx_label = 5;
1533 int idx_word_2 = 7;
1534 if (argc == 8)
1535 return bgp_static_set_safi(
1536 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1537 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1538 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
1539 else
1540 return bgp_static_set_safi(
1541 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1542 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1543 NULL, 0, NULL, NULL, NULL, NULL);
c286be96
LX
1544}
1545
1546/* For testing purpose, static route of MPLS-VPN. */
1547DEFUN (no_vpnv6_network,
1548 no_vpnv6_network_cmd,
d114b977 1549 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
c286be96
LX
1550 NO_STR
1551 "Specify a network to announce via BGP\n"
1552 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1553 "Specify Route Distinguisher\n"
1554 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1555 "VPN NLRI label (tag)\n"
1556 "VPN NLRI label (tag)\n"
1557 "Label value\n")
c286be96 1558{
d62a17ae 1559 int idx_ipv6_prefix = 2;
1560 int idx_ext_community = 4;
1561 int idx_label = 6;
1562 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
1563 argv[idx_ipv6_prefix]->arg,
1564 argv[idx_ext_community]->arg,
1565 argv[idx_label]->arg, 0, NULL, NULL, NULL);
c286be96
LX
1566}
1567
d62a17ae 1568int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
1569 enum bgp_show_type type, void *output_arg, int tags,
d7c0a89a 1570 uint8_t use_json)
718e3744 1571{
d62a17ae 1572 struct bgp *bgp;
1573 struct bgp_table *table;
d62a17ae 1574
1575 bgp = bgp_get_default();
1576 if (bgp == NULL) {
1577 if (!use_json)
1578 vty_out(vty, "No BGP process is configured\n");
16307668
RW
1579 else
1580 vty_out(vty, "{}\n");
d62a17ae 1581 return CMD_WARNING;
1582 }
1ae44dfc 1583 table = bgp->rib[afi][SAFI_MPLS_VPN];
a4d82a8a
PZ
1584 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
1585 output_arg, use_json);
718e3744 1586}
1587
4f280b15
LB
1588DEFUN (show_bgp_ip_vpn_all_rd,
1589 show_bgp_ip_vpn_all_rd_cmd,
d114b977 1590 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
e3e29b32
LB
1591 SHOW_STR
1592 BGP_STR
05e588f4 1593 BGP_VPNVX_HELP_STR
e3e29b32 1594 "Display VPN NLRI specific information\n"
af8528fa 1595 "Display VPN NLRI specific information\n"
e3e29b32
LB
1596 "Display information for a route distinguisher\n"
1597 "VPN Route Distinguisher\n"
1598 JSON_STR)
1599{
d62a17ae 1600 int ret;
1601 struct prefix_rd prd;
1602 afi_t afi;
1603 int idx = 0;
1604
1605 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
3d7c4cd7 1606 if (argv_find(argv, argc, "rd", &idx)) {
a4d82a8a 1607 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
d62a17ae 1608 if (!ret) {
1609 vty_out(vty,
1610 "%% Malformed Route Distinguisher\n");
1611 return CMD_WARNING;
1612 }
1613 return bgp_show_mpls_vpn(vty, afi, &prd,
1614 bgp_show_type_normal, NULL, 0,
1615 use_json(argc, argv));
1616 } else {
1617 return bgp_show_mpls_vpn(vty, afi, NULL,
1618 bgp_show_type_normal, NULL, 0,
1619 use_json(argc, argv));
1620 }
1621 }
1622 return CMD_SUCCESS;
718e3744 1623}
1624
af8528fa
LB
1625ALIAS(show_bgp_ip_vpn_all_rd,
1626 show_bgp_ip_vpn_rd_cmd,
1627 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1628 SHOW_STR
1629 BGP_STR
1630 BGP_VPNVX_HELP_STR
1631 "Display VPN NLRI specific information\n"
1632 "Display information for a route distinguisher\n"
1633 "VPN Route Distinguisher\n"
1634 JSON_STR)
1635
1636#ifdef KEEP_OLD_VPN_COMMANDS
3f227172
PG
1637DEFUN (show_ip_bgp_vpn_rd,
1638 show_ip_bgp_vpn_rd_cmd,
af8528fa 1639 "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
718e3744 1640 SHOW_STR
1641 IP_STR
1642 BGP_STR
4f280b15 1643 BGP_AFI_HELP_STR
3517059b 1644 "Address Family modifier\n"
718e3744 1645 "Display information for a route distinguisher\n"
1646 "VPN Route Distinguisher\n")
1647{
d62a17ae 1648 int idx_ext_community = argc - 1;
1649 int ret;
1650 struct prefix_rd prd;
1651 afi_t afi;
1652 int idx = 0;
1653
1654 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1655 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1656 if (!ret) {
1657 vty_out(vty, "%% Malformed Route Distinguisher\n");
1658 return CMD_WARNING;
1659 }
1660 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1661 NULL, 0, 0);
1662 }
1663 return CMD_SUCCESS;
1664}
718e3744 1665
4f280b15
LB
1666DEFUN (show_ip_bgp_vpn_all,
1667 show_ip_bgp_vpn_all_cmd,
1668 "show [ip] bgp <vpnv4|vpnv6>",
1669 SHOW_STR
1670 IP_STR
1671 BGP_STR
1672 BGP_VPNVX_HELP_STR)
1673{
d62a17ae 1674 afi_t afi;
1675 int idx = 0;
4f280b15 1676
d62a17ae 1677 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1678 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1679 NULL, 0, 0);
1680 return CMD_SUCCESS;
4f280b15
LB
1681}
1682
3f227172
PG
1683DEFUN (show_ip_bgp_vpn_all_tags,
1684 show_ip_bgp_vpn_all_tags_cmd,
1685 "show [ip] bgp <vpnv4|vpnv6> all tags",
718e3744 1686 SHOW_STR
1687 IP_STR
1688 BGP_STR
3f227172
PG
1689 BGP_VPNVX_HELP_STR
1690 "Display information about all VPNv4/VPNV6 NLRIs\n"
718e3744 1691 "Display BGP tags for prefixes\n")
1692{
d62a17ae 1693 afi_t afi;
1694 int idx = 0;
3f227172 1695
d62a17ae 1696 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1697 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1698 NULL, 1, 0);
1699 return CMD_SUCCESS;
718e3744 1700}
1701
3f227172
PG
1702DEFUN (show_ip_bgp_vpn_rd_tags,
1703 show_ip_bgp_vpn_rd_tags_cmd,
d114b977 1704 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
718e3744 1705 SHOW_STR
1706 IP_STR
1707 BGP_STR
3f227172 1708 BGP_VPNVX_HELP_STR
718e3744 1709 "Display information for a route distinguisher\n"
1710 "VPN Route Distinguisher\n"
1711 "Display BGP tags for prefixes\n")
1712{
d62a17ae 1713 int idx_ext_community = 5;
1714 int ret;
1715 struct prefix_rd prd;
1716 afi_t afi;
1717 int idx = 0;
1718
1719 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1720 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1721 if (!ret) {
1722 vty_out(vty, "%% Malformed Route Distinguisher\n");
1723 return CMD_WARNING;
1724 }
1725 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1726 NULL, 1, 0);
1727 }
1728 return CMD_SUCCESS;
718e3744 1729}
1730
3f227172
PG
1731DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
1732 show_ip_bgp_vpn_all_neighbor_routes_cmd,
1733 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
718e3744 1734 SHOW_STR
1735 IP_STR
1736 BGP_STR
3f227172
PG
1737 BGP_VPNVX_HELP_STR
1738 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 1739 "Detailed information on TCP and BGP neighbor connections\n"
1740 "Neighbor to display information about\n"
856ca177 1741 "Display routes learned from neighbor\n"
9973d184 1742 JSON_STR)
718e3744 1743{
d62a17ae 1744 int idx_ipv4 = 6;
1745 union sockunion su;
1746 struct peer *peer;
1747 int ret;
d7c0a89a 1748 uint8_t uj = use_json(argc, argv);
d62a17ae 1749 afi_t afi;
1750 int idx = 0;
1751
1752 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1753 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1754 if (ret < 0) {
1755 if (uj) {
1756 json_object *json_no = NULL;
1757 json_no = json_object_new_object();
1758 json_object_string_add(json_no, "warning",
1759 "Malformed address");
1760 vty_out(vty, "%s\n",
1761 json_object_to_json_string(json_no));
1762 json_object_free(json_no);
1763 } else
1764 vty_out(vty, "Malformed address: %s\n",
1765 argv[idx_ipv4]->arg);
1766 return CMD_WARNING;
1767 }
1768
1769 peer = peer_lookup(NULL, &su);
1770 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1771 if (uj) {
1772 json_object *json_no = NULL;
1773 json_no = json_object_new_object();
1774 json_object_string_add(
1775 json_no, "warning",
1776 "No such neighbor or address family");
1777 vty_out(vty, "%s\n",
1778 json_object_to_json_string(json_no));
1779 json_object_free(json_no);
1780 } else
1781 vty_out(vty,
1782 "%% No such neighbor or address family\n");
1783 return CMD_WARNING;
1784 }
1785
1786 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
1787 &su, 0, uj);
1788 }
1789 return CMD_SUCCESS;
718e3744 1790}
1791
3f227172
PG
1792DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
1793 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
d114b977 1794 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
718e3744 1795 SHOW_STR
1796 IP_STR
1797 BGP_STR
3f227172 1798 BGP_VPNVX_HELP_STR
718e3744 1799 "Display information for a route distinguisher\n"
1800 "VPN Route Distinguisher\n"
1801 "Detailed information on TCP and BGP neighbor connections\n"
1802 "Neighbor to display information about\n"
856ca177 1803 "Display routes learned from neighbor\n"
9973d184 1804 JSON_STR)
718e3744 1805{
d62a17ae 1806 int idx_ext_community = 5;
1807 int idx_ipv4 = 7;
1808 int ret;
1809 union sockunion su;
1810 struct peer *peer;
1811 struct prefix_rd prd;
d7c0a89a 1812 uint8_t uj = use_json(argc, argv);
d62a17ae 1813 afi_t afi;
1814 int idx = 0;
1815
1816 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1817 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1818 if (!ret) {
1819 if (uj) {
1820 json_object *json_no = NULL;
1821 json_no = json_object_new_object();
1822 json_object_string_add(
1823 json_no, "warning",
1824 "Malformed Route Distinguisher");
1825 vty_out(vty, "%s\n",
1826 json_object_to_json_string(json_no));
1827 json_object_free(json_no);
1828 } else
1829 vty_out(vty,
1830 "%% Malformed Route Distinguisher\n");
1831 return CMD_WARNING;
1832 }
1833
1834 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1835 if (ret < 0) {
1836 if (uj) {
1837 json_object *json_no = NULL;
1838 json_no = json_object_new_object();
1839 json_object_string_add(json_no, "warning",
1840 "Malformed address");
1841 vty_out(vty, "%s\n",
1842 json_object_to_json_string(json_no));
1843 json_object_free(json_no);
1844 } else
1845 vty_out(vty, "Malformed address: %s\n",
1846 argv[idx_ext_community]->arg);
1847 return CMD_WARNING;
1848 }
1849
1850 peer = peer_lookup(NULL, &su);
1851 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1852 if (uj) {
1853 json_object *json_no = NULL;
1854 json_no = json_object_new_object();
1855 json_object_string_add(
1856 json_no, "warning",
1857 "No such neighbor or address family");
1858 vty_out(vty, "%s\n",
1859 json_object_to_json_string(json_no));
1860 json_object_free(json_no);
1861 } else
1862 vty_out(vty,
1863 "%% No such neighbor or address family\n");
1864 return CMD_WARNING;
1865 }
1866
1867 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_neighbor,
1868 &su, 0, uj);
1869 }
1870 return CMD_SUCCESS;
718e3744 1871}
1872
3f227172
PG
1873DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
1874 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
1875 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
718e3744 1876 SHOW_STR
1877 IP_STR
1878 BGP_STR
3f227172
PG
1879 BGP_VPNVX_HELP_STR
1880 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 1881 "Detailed information on TCP and BGP neighbor connections\n"
1882 "Neighbor to display information about\n"
856ca177 1883 "Display the routes advertised to a BGP neighbor\n"
9973d184 1884 JSON_STR)
718e3744 1885{
d62a17ae 1886 int idx_ipv4 = 6;
1887 int ret;
1888 struct peer *peer;
1889 union sockunion su;
d7c0a89a 1890 uint8_t uj = use_json(argc, argv);
d62a17ae 1891 afi_t afi;
1892 int idx = 0;
1893
1894 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1895 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1896 if (ret < 0) {
1897 if (uj) {
1898 json_object *json_no = NULL;
1899 json_no = json_object_new_object();
1900 json_object_string_add(json_no, "warning",
1901 "Malformed address");
1902 vty_out(vty, "%s\n",
1903 json_object_to_json_string(json_no));
1904 json_object_free(json_no);
1905 } else
1906 vty_out(vty, "Malformed address: %s\n",
1907 argv[idx_ipv4]->arg);
1908 return CMD_WARNING;
1909 }
1910 peer = peer_lookup(NULL, &su);
1911 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1912 if (uj) {
1913 json_object *json_no = NULL;
1914 json_no = json_object_new_object();
1915 json_object_string_add(
1916 json_no, "warning",
1917 "No such neighbor or address family");
1918 vty_out(vty, "%s\n",
1919 json_object_to_json_string(json_no));
1920 json_object_free(json_no);
1921 } else
1922 vty_out(vty,
1923 "%% No such neighbor or address family\n");
1924 return CMD_WARNING;
1925 }
1926 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
1927 SAFI_MPLS_VPN, uj);
1928 }
1929 return CMD_SUCCESS;
718e3744 1930}
1931
3f227172
PG
1932DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
1933 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
d114b977 1934 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
718e3744 1935 SHOW_STR
1936 IP_STR
1937 BGP_STR
3f227172 1938 BGP_VPNVX_HELP_STR
718e3744 1939 "Display information for a route distinguisher\n"
1940 "VPN Route Distinguisher\n"
1941 "Detailed information on TCP and BGP neighbor connections\n"
1942 "Neighbor to display information about\n"
856ca177 1943 "Display the routes advertised to a BGP neighbor\n"
9973d184 1944 JSON_STR)
718e3744 1945{
d62a17ae 1946 int idx_ext_community = 5;
1947 int idx_ipv4 = 7;
1948 int ret;
1949 struct peer *peer;
1950 struct prefix_rd prd;
1951 union sockunion su;
d7c0a89a 1952 uint8_t uj = use_json(argc, argv);
d62a17ae 1953 afi_t afi;
1954 int idx = 0;
1955
1956 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1957 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1958 if (ret < 0) {
1959 if (uj) {
1960 json_object *json_no = NULL;
1961 json_no = json_object_new_object();
1962 json_object_string_add(json_no, "warning",
1963 "Malformed address");
1964 vty_out(vty, "%s\n",
1965 json_object_to_json_string(json_no));
1966 json_object_free(json_no);
1967 } else
1968 vty_out(vty, "Malformed address: %s\n",
1969 argv[idx_ext_community]->arg);
1970 return CMD_WARNING;
1971 }
1972 peer = peer_lookup(NULL, &su);
1973 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1974 if (uj) {
1975 json_object *json_no = NULL;
1976 json_no = json_object_new_object();
1977 json_object_string_add(
1978 json_no, "warning",
1979 "No such neighbor or address family");
1980 vty_out(vty, "%s\n",
1981 json_object_to_json_string(json_no));
1982 json_object_free(json_no);
1983 } else
1984 vty_out(vty,
1985 "%% No such neighbor or address family\n");
1986 return CMD_WARNING;
1987 }
1988
1989 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1990 if (!ret) {
1991 if (uj) {
1992 json_object *json_no = NULL;
1993 json_no = json_object_new_object();
1994 json_object_string_add(
1995 json_no, "warning",
1996 "Malformed Route Distinguisher");
1997 vty_out(vty, "%s\n",
1998 json_object_to_json_string(json_no));
1999 json_object_free(json_no);
2000 } else
2001 vty_out(vty,
2002 "%% Malformed Route Distinguisher\n");
2003 return CMD_WARNING;
2004 }
2005
2006 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
2007 SAFI_MPLS_VPN, uj);
2008 }
2009 return CMD_SUCCESS;
718e3744 2010}
d6902373 2011#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2012
d62a17ae 2013void bgp_mplsvpn_init(void)
718e3744 2014{
d62a17ae 2015 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
2016 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
2017 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
718e3744 2018
d62a17ae 2019 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
2020 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
c286be96 2021
d62a17ae 2022 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
af8528fa 2023 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
d6902373 2024#ifdef KEEP_OLD_VPN_COMMANDS
af8528fa 2025 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
d62a17ae 2026 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
2027 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
2028 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
2029 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
2030 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
2031 install_element(VIEW_NODE,
2032 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
2033 install_element(VIEW_NODE,
2034 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
d6902373 2035#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2036}
301ad80a
PG
2037
2038vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
2039{
2040 struct listnode *mnode, *mnnode;
2041 struct bgp *bgp;
2042
2043 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2044 struct ecommunity *ec;
2045
2046 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2047 continue;
2048
2049 ec = bgp->vpn_policy[AFI_IP].import_redirect_rtlist;
2050
2051 if (ecom_intersect(ec, eckey))
2052 return bgp->vrf_id;
2053 }
2054 return VRF_UNKNOWN;
2055}