]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.c
doc: Fixup doc for vrf-2-vrf as per suggestions in Review
[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
cc5a6ddd 657 /* loop check - should not be an imported route. */
658 if (info_vrf->extra && info_vrf->extra->bgp_orig)
ddb5b488
PZ
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) {
020a3f60
DS
766 /*
767 * For ipv4, copy to multiprotocol
768 * nexthop field
769 */
770 static_attr.mp_nexthop_global_in =
771 static_attr.nexthop;
12a844a5 772 static_attr.mp_nexthop_len = 4;
020a3f60
DS
773 /*
774 * XXX Leave static_attr.nexthop
775 * intact for NHT
776 */
777 static_attr.flag &=
778 ~ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
12a844a5
DS
779 }
780 } else {
77e62f2b 781 /* Update based on next-hop family to account for
782 * RFC 5549 (BGP unnumbered) scenario. Note that
783 * specific action is only needed for the case of
784 * IPv4 nexthops as the attr has been copied
785 * otherwise.
786 */
787 if (afi == AFI_IP &&
788 !BGP_ATTR_NEXTHOP_AFI_IP6(info_vrf->attr)) {
12a844a5
DS
789 static_attr.mp_nexthop_global_in.s_addr =
790 static_attr.nexthop.s_addr;
791 static_attr.mp_nexthop_len = 4;
792 static_attr.flag |=
793 ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
12a844a5 794 }
ddb5b488 795 }
960035b2 796 nexthop_self_flag = 1;
ddb5b488
PZ
797 }
798
799 label_val = bgp_vrf->vpn_policy[afi].tovpn_label;
800 if (label_val == MPLS_LABEL_NONE) {
291e32c3 801 encode_label(MPLS_LABEL_IMPLICIT_NULL, &label);
ddb5b488
PZ
802 } else {
803 encode_label(label_val, &label);
804 }
805
806 /* Set originator ID to "me" */
807 SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID));
808 static_attr.originator_id = bgp_vpn->router_id;
809
810
811 new_attr = bgp_attr_intern(
812 &static_attr); /* hashed refcounted everything */
813 bgp_attr_flush(&static_attr); /* free locally-allocated parts */
814
c3e345b1
DS
815 if (debug && new_attr->ecommunity) {
816 char *s = ecommunity_ecom2str(new_attr->ecommunity,
817 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
ddb5b488 818
ddb5b488 819 zlog_debug("%s: new_attr->ecommunity{%s}", __func__, s);
c3e345b1 820 XFREE(MTYPE_ECOMMUNITY_STR, s);
ddb5b488
PZ
821 }
822
823 /* Now new_attr is an allocated interned attr */
824
825 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
826 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
827
828 struct bgp_info *new_info;
829
830 new_info = leak_update(bgp_vpn, bn, new_attr, afi, safi, info_vrf,
960035b2
PZ
831 &label, 1, info_vrf, bgp_vrf, NULL,
832 nexthop_self_flag, debug);
ddb5b488
PZ
833
834 /*
835 * Routes actually installed in the vpn RIB must also be
836 * offered to all vrfs (because now they originate from
837 * the vpn RIB).
838 *
839 * Acceptance into other vrfs depends on rt-lists.
840 * Originating vrf will not accept the looped back route
841 * because of loop checking.
842 */
843 if (new_info)
321b4bc9 844 vpn_leak_to_vrf_update(bgp_vrf, new_info);
ddb5b488
PZ
845}
846
847void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */
848 struct bgp *bgp_vrf, /* from */
849 struct bgp_info *info_vrf) /* route */
850{
851 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
852 struct prefix *p = &info_vrf->net->p;
853 afi_t afi = family2afi(p->family);
854 safi_t safi = SAFI_MPLS_VPN;
855 struct bgp_info *bi;
856 struct bgp_node *bn;
857 const char *debugmsg;
960035b2
PZ
858 char buf_prefix[PREFIX_STRLEN];
859
860 if (debug) {
861 prefix2str(p, buf_prefix, sizeof(buf_prefix));
862 zlog_debug(
863 "%s: entry: leak-from=%s, p=%s, type=%d, sub_type=%d",
864 __func__, bgp_vrf->name_pretty, buf_prefix,
865 info_vrf->type, info_vrf->sub_type);
866 }
ddb5b488 867
ddb5b488 868 if (info_vrf->sub_type != BGP_ROUTE_NORMAL
82e7e75d 869 && info_vrf->sub_type != BGP_ROUTE_STATIC
870 && info_vrf->sub_type != BGP_ROUTE_REDISTRIBUTE) {
ddb5b488
PZ
871
872 if (debug)
873 zlog_debug("%s: wrong sub_type %d", __func__,
874 info_vrf->sub_type);
875 return;
876 }
877 if (!bgp_vpn)
878 return;
879
880 if (!afi) {
881 if (debug)
882 zlog_debug("%s: can't get afi of prefix", __func__);
883 return;
884 }
885
886 if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) {
887 if (debug)
888 zlog_debug("%s: skipping: %s", __func__, debugmsg);
889 return;
890 }
891
892 if (debug)
893 zlog_debug("%s: withdrawing (info_vrf=%p)", __func__, info_vrf);
894
895 bn = bgp_afi_node_get(bgp_vpn->rib[afi][safi], afi, safi, p,
896 &(bgp_vrf->vpn_policy[afi].tovpn_rd));
897
898 /*
899 * vrf -> vpn
900 * match original bi imported from
901 */
902 for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
903 if (bi->extra && bi->extra->parent == info_vrf) {
904 break;
905 }
906 }
907
908 if (bi) {
909 /* withdraw from looped vrfs as well */
910 vpn_leak_to_vrf_withdraw(bgp_vpn, bi);
911
912 bgp_aggregate_decrement(bgp_vpn, p, bi, afi, safi);
913 bgp_info_delete(bn, bi);
914 bgp_process(bgp_vpn, bn, afi, safi);
915 }
916 bgp_unlock_node(bn);
917}
918
919void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
920 struct bgp *bgp_vrf, /* from */
921 afi_t afi)
922{
923 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
924 struct bgp_node *prn;
925 safi_t safi = SAFI_MPLS_VPN;
926
927 /*
ddb5b488
PZ
928 * Walk vpn table, delete bi with bgp_orig == bgp_vrf
929 */
930 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
931 prn = bgp_route_next(prn)) {
932
933 struct bgp_table *table;
934 struct bgp_node *bn;
935 struct bgp_info *bi;
936
937 /* This is the per-RD table of prefixes */
938 table = prn->info;
939
940 if (!table)
941 continue;
942
943 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
944
945 char buf[PREFIX2STR_BUFFER];
946
947 if (debug && bn->info) {
948 zlog_debug(
949 "%s: looking at prefix %s", __func__,
950 prefix2str(&bn->p, buf, sizeof(buf)));
951 }
952
953 for (bi = bn->info; bi; bi = bi->next) {
954 if (debug)
955 zlog_debug("%s: type %d, sub_type %d",
956 __func__, bi->type,
957 bi->sub_type);
958 if (bi->sub_type != BGP_ROUTE_IMPORTED)
959 continue;
960 if (!bi->extra)
961 continue;
962 if ((struct bgp *)bi->extra->bgp_orig
963 == bgp_vrf) {
964 /* delete route */
965 if (debug)
966 zlog_debug("%s: deleting it\n",
967 __func__);
968 bgp_aggregate_decrement(bgp_vpn, &bn->p,
969 bi, afi, safi);
970 bgp_info_delete(bn, bi);
971 bgp_process(bgp_vpn, bn, afi, safi);
972 }
973 }
974 }
975 }
976}
977
978void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn, /* to */
979 struct bgp *bgp_vrf, /* from */
980 afi_t afi)
981{
982 struct bgp_node *bn;
983 struct bgp_info *bi;
984 int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
985
986 if (debug)
987 zlog_debug("%s: entry, afi=%d, vrf=%s", __func__, afi,
960035b2 988 bgp_vrf->name_pretty);
ddb5b488
PZ
989
990 for (bn = bgp_table_top(bgp_vrf->rib[afi][SAFI_UNICAST]); bn;
991 bn = bgp_route_next(bn)) {
992
993 if (debug)
994 zlog_debug("%s: node=%p", __func__, bn);
995
996 for (bi = bn->info; bi; bi = bi->next) {
997 if (debug)
998 zlog_debug(
999 "%s: calling vpn_leak_from_vrf_update",
1000 __func__);
1001 vpn_leak_from_vrf_update(bgp_vpn, bgp_vrf, bi);
1002 }
1003 }
1004}
1005
1006static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
1007 struct bgp *bgp_vpn, /* from */
1008 struct bgp_info *info_vpn) /* route */
1009{
1010 struct prefix *p = &info_vpn->net->p;
1011 afi_t afi = family2afi(p->family);
1012
ddb5b488
PZ
1013 struct attr static_attr = {0};
1014 struct attr *new_attr = NULL;
1015 struct bgp_node *bn;
1016 safi_t safi = SAFI_UNICAST;
1017 const char *debugmsg;
1018 struct prefix nexthop_orig;
1019 mpls_label_t *pLabels = NULL;
e37fb4bf 1020 uint32_t num_labels = 0;
960035b2 1021 int nexthop_self_flag = 1;
513bf8d6
PZ
1022 struct bgp_info *bi_ultimate = NULL;
1023 int origin_local = 0;
d6632478 1024 struct bgp *src_vrf;
ddb5b488
PZ
1025
1026 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1027
b9c7bc5a 1028 if (!vpn_leak_from_vpn_active(bgp_vrf, afi, &debugmsg)) {
ddb5b488
PZ
1029 if (debug)
1030 zlog_debug("%s: skipping: %s", __func__, debugmsg);
1031 return;
1032 }
1033
1034 /* Check for intersection of route targets */
1035 if (!ecom_intersect(
1036 bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1037 info_vpn->attr->ecommunity)) {
1038
1039 return;
1040 }
1041
1042 if (debug)
960035b2
PZ
1043 zlog_debug("%s: updating to vrf %s", __func__,
1044 bgp_vrf->name_pretty);
ddb5b488
PZ
1045
1046 bgp_attr_dup(&static_attr, info_vpn->attr); /* shallow copy */
1047
1048 /*
1049 * Nexthop: stash and clear
1050 *
1051 * Nexthop is valid in context of VPN core, but not in destination vrf.
1052 * Stash it for later label resolution by vrf ingress path and then
1053 * overwrite with 0, i.e., "me", for the sake of vrf advertisement.
1054 */
1055 uint8_t nhfamily = NEXTHOP_FAMILY(info_vpn->attr->mp_nexthop_len);
1056
1057 memset(&nexthop_orig, 0, sizeof(nexthop_orig));
1058 nexthop_orig.family = nhfamily;
1059
1060 switch (nhfamily) {
ddb5b488
PZ
1061 case AF_INET:
1062 /* save */
1063 nexthop_orig.u.prefix4 = info_vpn->attr->mp_nexthop_global_in;
1064 nexthop_orig.prefixlen = 32;
12a844a5
DS
1065
1066 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1067 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1068 static_attr.nexthop.s_addr =
1069 nexthop_orig.u.prefix4.s_addr;
1070
1071 static_attr.mp_nexthop_global_in =
1072 info_vpn->attr->mp_nexthop_global_in;
1073 static_attr.mp_nexthop_len =
1074 info_vpn->attr->mp_nexthop_len;
1075 }
ddb5b488 1076 static_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
ddb5b488 1077 break;
ddb5b488
PZ
1078 case AF_INET6:
1079 /* save */
1080 nexthop_orig.u.prefix6 = info_vpn->attr->mp_nexthop_global;
1081 nexthop_orig.prefixlen = 128;
12a844a5
DS
1082
1083 if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1084 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1085 static_attr.mp_nexthop_global = nexthop_orig.u.prefix6;
12a844a5 1086 }
ddb5b488
PZ
1087 break;
1088 }
1089
ddb5b488
PZ
1090 /*
1091 * route map handling
ddb5b488 1092 */
ddb5b488
PZ
1093 if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
1094 struct bgp_info info;
1095 route_map_result_t ret;
1096
1097 memset(&info, 0, sizeof(info));
1098 info.peer = bgp_vrf->peer_self;
1099 info.attr = &static_attr;
1100 ret = route_map_apply(bgp_vrf->vpn_policy[afi]
1101 .rmap[BGP_VPN_POLICY_DIR_FROMVPN],
1102 p, RMAP_BGP, &info);
1103 if (RMAP_DENYMATCH == ret) {
1104 bgp_attr_flush(&static_attr); /* free any added parts */
1105 if (debug)
1106 zlog_debug(
1107 "%s: vrf %s vpn-policy route map \"%s\" says DENY, returning",
960035b2 1108 __func__, bgp_vrf->name_pretty,
ddb5b488
PZ
1109 bgp_vrf->vpn_policy[afi]
1110 .rmap[BGP_VPN_POLICY_DIR_FROMVPN]
1111 ->name);
1112 return;
1113 }
960035b2
PZ
1114 /*
1115 * if route-map changed nexthop, don't nexthop-self on output
1116 */
1117 if (!CHECK_FLAG(static_attr.rmap_change_flags,
1118 BATTR_RMAP_NEXTHOP_UNCHANGED))
1119 nexthop_self_flag = 0;
ddb5b488
PZ
1120 }
1121
1122 new_attr = bgp_attr_intern(&static_attr);
1123 bgp_attr_flush(&static_attr);
1124
1125 bn = bgp_afi_node_get(bgp_vrf->rib[afi][safi], afi, safi, p, NULL);
1126
1127 /*
1128 * ensure labels are copied
513bf8d6
PZ
1129 *
1130 * However, there is a special case: if the route originated in
1131 * another local VRF (as opposed to arriving via VPN), then the
1132 * nexthop is reached by hairpinning through this router (me)
1133 * using IP forwarding only (no LSP). Therefore, the route
1134 * imported to the VRF should not have labels attached. Note
1135 * that nexthop tracking is also involved: eliminating the
1136 * labels for these routes enables the non-labeled nexthops
1137 * from the originating VRF to be considered valid for this route.
ddb5b488 1138 */
12a844a5
DS
1139 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
1140 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
1141 /* work back to original route */
1142 for (bi_ultimate = info_vpn;
1143 bi_ultimate->extra && bi_ultimate->extra->parent;
1144 bi_ultimate = bi_ultimate->extra->parent)
1145 ;
513bf8d6 1146
12a844a5
DS
1147 /*
1148 * if original route was unicast,
1149 * then it did not arrive over vpn
1150 */
1151 if (bi_ultimate->net) {
1152 struct bgp_table *table;
513bf8d6 1153
12a844a5
DS
1154 table = bgp_node_table(bi_ultimate->net);
1155 if (table && (table->safi == SAFI_UNICAST))
1156 origin_local = 1;
1157 }
513bf8d6 1158
12a844a5
DS
1159 /* copy labels */
1160 if (!origin_local &&
1161 info_vpn->extra && info_vpn->extra->num_labels) {
1162 num_labels = info_vpn->extra->num_labels;
1163 if (num_labels > BGP_MAX_LABELS)
1164 num_labels = BGP_MAX_LABELS;
1165 pLabels = info_vpn->extra->label;
1166 }
ddb5b488 1167 }
513bf8d6 1168
ddb5b488
PZ
1169 if (debug) {
1170 char buf_prefix[PREFIX_STRLEN];
1171 prefix2str(p, buf_prefix, sizeof(buf_prefix));
1172 zlog_debug("%s: pfx %s: num_labels %d", __func__, buf_prefix,
1173 num_labels);
1174 }
1175
44338987 1176 /*
1d4e8b0d
DS
1177 * For VRF-2-VRF route-leaking,
1178 * the source will be the originating VRF.
44338987 1179 */
d6632478
PZ
1180 if (info_vpn->extra && info_vpn->extra->bgp_orig)
1181 src_vrf = info_vpn->extra->bgp_orig;
1182 else
1183 src_vrf = bgp_vpn;
1184
960035b2
PZ
1185 leak_update(bgp_vrf, bn, new_attr, afi, safi, info_vpn,
1186 pLabels, num_labels,
1187 info_vpn, /* parent */
d6632478 1188 src_vrf, &nexthop_orig, nexthop_self_flag, debug);
ddb5b488
PZ
1189}
1190
1191void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
1192 struct bgp_info *info_vpn) /* route */
1193{
1194 struct listnode *mnode, *mnnode;
1195 struct bgp *bgp;
1196
1197 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1198
1199 if (debug)
1200 zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
1201
1202 /* Loop over VRFs */
1203 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
1204
1205 if (!info_vpn->extra
1206 || info_vpn->extra->bgp_orig != bgp) { /* no loop */
1207 vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, info_vpn);
1208 }
1209 }
1210}
1211
1212void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
1213 struct bgp_info *info_vpn) /* route */
1214{
1b3510a0
PZ
1215 struct prefix *p;
1216 afi_t afi;
ddb5b488
PZ
1217 safi_t safi = SAFI_UNICAST;
1218 struct bgp *bgp;
1219 struct listnode *mnode, *mnnode;
ddb5b488
PZ
1220 struct bgp_node *bn;
1221 struct bgp_info *bi;
1222 const char *debugmsg;
960035b2 1223 char buf_prefix[PREFIX_STRLEN];
ddb5b488
PZ
1224
1225 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1226
960035b2
PZ
1227 if (debug) {
1228 prefix2str(&info_vpn->net->p, buf_prefix, sizeof(buf_prefix));
1229 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d",
1230 __func__, buf_prefix,
1231 info_vpn->type, info_vpn->sub_type);
1232 }
1233
ddb5b488
PZ
1234 if (debug)
1235 zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
1236
1b3510a0 1237 if (!info_vpn->net) {
56c2c080 1238#if ENABLE_BGP_VNC
1b3510a0
PZ
1239 /* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
1240 if (info_vpn->type == ZEBRA_ROUTE_BGP &&
1241 info_vpn->sub_type == BGP_ROUTE_RFP) {
1242
1243 return;
1244 }
56c2c080 1245#endif
1b3510a0
PZ
1246 if (debug)
1247 zlog_debug("%s: info_vpn->net unexpectedly NULL, no prefix, bailing",
1248 __func__);
1249 return;
1250 }
1251
1252 p = &info_vpn->net->p;
1253 afi = family2afi(p->family);
ddb5b488
PZ
1254
1255 /* Loop over VRFs */
1256 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
b9c7bc5a 1257 if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
ddb5b488
PZ
1258 if (debug)
1259 zlog_debug("%s: skipping: %s", __func__,
1260 debugmsg);
1261 continue;
1262 }
1263
1264 /* Check for intersection of route targets */
1265 if (!ecom_intersect(bgp->vpn_policy[afi]
1266 .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1267 info_vpn->attr->ecommunity)) {
1268
1269 continue;
1270 }
1271
1272 if (debug)
1273 zlog_debug("%s: withdrawing from vrf %s", __func__,
960035b2 1274 bgp->name_pretty);
ddb5b488
PZ
1275
1276 bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
1277 for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
1278 if (bi->extra
1279 && (struct bgp_info *)bi->extra->parent
1280 == info_vpn) {
1281 break;
1282 }
1283 }
1284
1285 if (bi) {
1286 if (debug)
1287 zlog_debug("%s: deleting bi %p", __func__, bi);
1288 bgp_aggregate_decrement(bgp, p, bi, afi, safi);
1289 bgp_info_delete(bn, bi);
1290 bgp_process(bgp, bn, afi, safi);
1291 }
1292 bgp_unlock_node(bn);
1293 }
1294}
1295
1296void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
1297 afi_t afi)
1298{
1299 struct bgp_node *bn;
1300 struct bgp_info *bi;
1301 safi_t safi = SAFI_UNICAST;
1302 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
ddb5b488
PZ
1303
1304 if (debug)
1305 zlog_debug("%s: entry", __func__);
1306 /*
d793761d 1307 * Walk vrf table, delete bi with bgp_orig in a different vrf
ddb5b488
PZ
1308 */
1309 for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
1310 bn = bgp_route_next(bn)) {
1311
1312 for (bi = bn->info; bi; bi = bi->next) {
d793761d 1313 if (bi->extra && bi->extra->bgp_orig != bgp_vrf) {
ddb5b488
PZ
1314
1315 /* delete route */
1316 bgp_aggregate_decrement(bgp_vrf, &bn->p, bi,
1317 afi, safi);
1318 bgp_info_delete(bn, bi);
1319 bgp_process(bgp_vrf, bn, afi, safi);
1320 }
1321 }
1322 }
1323}
1324
1325void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
1326 struct bgp *bgp_vpn, /* from */
1327 afi_t afi)
1328{
1329 struct prefix_rd prd;
1330 struct bgp_node *prn;
1331 safi_t safi = SAFI_MPLS_VPN;
1332
1333 /*
1334 * Walk vpn table
1335 */
1336 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
1337 prn = bgp_route_next(prn)) {
1338
1339 struct bgp_table *table;
1340 struct bgp_node *bn;
1341 struct bgp_info *bi;
1342
1343 memset(&prd, 0, sizeof(prd));
1344 prd.family = AF_UNSPEC;
1345 prd.prefixlen = 64;
1346 memcpy(prd.val, prn->p.u.val, 8);
1347
1348 /* This is the per-RD table of prefixes */
1349 table = prn->info;
1350
1351 if (!table)
1352 continue;
1353
1354 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
1355
1356 for (bi = bn->info; bi; bi = bi->next) {
1357
1358 if (bi->extra && bi->extra->bgp_orig == bgp_vrf)
1359 continue;
1360
1361 vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
1362 bi);
1363 }
1364 }
1365 }
1366}
1367
d92a55df
PZ
1368/*
1369 * This function is called for definition/deletion/change to a route-map
1370 */
ddb5b488
PZ
1371static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
1372{
1373 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1374 afi_t afi;
1375 struct route_map *rmap;
1376
1377 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1378 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
1379
1380 return;
1381 }
1382
1383 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
1384
1385 for (afi = 0; afi < AFI_MAX; ++afi) {
1386
d92a55df
PZ
1387 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
1388 && !strcmp(rmap_name,
ddb5b488
PZ
1389 bgp->vpn_policy[afi]
1390 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
1391
1392 if (debug)
1393 zlog_debug(
1394 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1395 __func__, rmap_name, bgp->as,
1396 afi2str(afi));
1397
1398 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1399 bgp_get_default(), bgp);
1400 if (debug)
1401 zlog_debug("%s: after vpn_leak_prechange",
1402 __func__);
1403
d92a55df
PZ
1404 /* in case of definition/deletion */
1405 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN] =
1406 rmap;
ddb5b488
PZ
1407
1408 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1409 bgp_get_default(), bgp);
d92a55df 1410
ddb5b488
PZ
1411 if (debug)
1412 zlog_debug("%s: after vpn_leak_postchange",
1413 __func__);
1414 }
1415
d92a55df
PZ
1416 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]
1417 && !strcmp(rmap_name,
1418 bgp->vpn_policy[afi]
1419 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN])) {
b9c7bc5a
PZ
1420
1421 if (debug) {
1422 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
ddb5b488
PZ
1423 __func__, rmap_name, bgp->as,
1424 afi2str(afi));
b9c7bc5a 1425 }
ddb5b488
PZ
1426
1427 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1428 bgp_get_default(), bgp);
1429
d92a55df
PZ
1430 /* in case of definition/deletion */
1431 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
1432 rmap;
ddb5b488
PZ
1433
1434 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1435 bgp_get_default(), bgp);
1436 }
1437 }
1438}
1439
1440void vpn_policy_routemap_event(const char *rmap_name)
1441{
1442 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1443 struct listnode *mnode, *mnnode;
1444 struct bgp *bgp;
1445
1446 if (debug)
1447 zlog_debug("%s: entry", __func__);
1448
1449 if (bm->bgp == NULL) /* may be called during cleanup */
1450 return;
1451
1452 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
1453 vpn_policy_routemap_update(bgp, rmap_name);
1454}
1455
1d4e8b0d 1456void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 1457 afi_t afi, safi_t safi)
1458{
1459 const char *export_name;
1460 vpn_policy_direction_t idir, edir;
1461 char *vname;
1462 char buf[1000];
1463 struct ecommunity *ecom;
1464 bool first_export = false;
1465
a8dadcf6 1466 export_name = to_bgp->name ? to_bgp->name : BGP_DEFAULT_NAME;
44338987 1467 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1468 edir = BGP_VPN_POLICY_DIR_TOVPN;
1469
1d4e8b0d
DS
1470 /*
1471 * Cross-ref both VRFs. Also, note if this is the first time
44338987 1472 * any VRF is importing from "import_vrf".
1473 */
a8dadcf6
DS
1474 vname = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
1475 : XSTRDUP(MTYPE_TMP, BGP_DEFAULT_NAME));
1476
1d4e8b0d 1477 listnode_add(to_bgp->vpn_policy[afi].import_vrf, vname);
44338987 1478
1d4e8b0d 1479 if (!listcount(from_bgp->vpn_policy[afi].export_vrf))
44338987 1480 first_export = true;
1481 vname = XSTRDUP(MTYPE_TMP, export_name);
1d4e8b0d 1482 listnode_add(from_bgp->vpn_policy[afi].export_vrf, vname);
44338987 1483
1484 /* Update import RT for current VRF using export RT of the VRF we're
1485 * importing from. First though, make sure "import_vrf" has that
1486 * set.
1487 */
1488 if (first_export) {
1d4e8b0d
DS
1489 form_auto_rd(from_bgp->router_id, from_bgp->vrf_rd_id,
1490 &from_bgp->vrf_prd_auto);
1491 from_bgp->vpn_policy[afi].tovpn_rd = from_bgp->vrf_prd_auto;
1492 SET_FLAG(from_bgp->vpn_policy[afi].flags,
44338987 1493 BGP_VPN_POLICY_TOVPN_RD_SET);
1d4e8b0d 1494 prefix_rd2str(&from_bgp->vpn_policy[afi].tovpn_rd,
44338987 1495 buf, sizeof(buf));
1d4e8b0d 1496 from_bgp->vpn_policy[afi].rtlist[edir] =
44338987 1497 ecommunity_str2com(buf, ECOMMUNITY_ROUTE_TARGET, 0);
1d4e8b0d 1498 SET_FLAG(from_bgp->af_flags[afi][safi],
44338987 1499 BGP_CONFIG_VRF_TO_VRF_EXPORT);
1500 }
1d4e8b0d
DS
1501 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
1502 if (to_bgp->vpn_policy[afi].rtlist[idir])
1503 to_bgp->vpn_policy[afi].rtlist[idir] =
1504 ecommunity_merge(to_bgp->vpn_policy[afi]
44338987 1505 .rtlist[idir], ecom);
1506 else
1d4e8b0d
DS
1507 to_bgp->vpn_policy[afi].rtlist[idir] = ecommunity_dup(ecom);
1508 SET_FLAG(to_bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT);
44338987 1509
1510 /* Does "import_vrf" first need to export its routes or that
1511 * is already done and we just need to import those routes
1512 * from the global table?
1513 */
1514 if (first_export)
1d4e8b0d 1515 vpn_leak_postchange(edir, afi, bgp_get_default(), from_bgp);
44338987 1516 else
1d4e8b0d 1517 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
44338987 1518}
1519
1d4e8b0d 1520void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 1521 afi_t afi, safi_t safi)
1522{
a8dadcf6 1523 const char *export_name, *tmp_name;
44338987 1524 vpn_policy_direction_t idir, edir;
1525 char *vname;
1526 struct ecommunity *ecom;
1527 struct listnode *node;
1528
a8dadcf6
DS
1529 export_name = to_bgp->name ? to_bgp->name : BGP_DEFAULT_NAME;
1530 tmp_name = from_bgp->name ? from_bgp->name : BGP_DEFAULT_NAME;
44338987 1531 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1532 edir = BGP_VPN_POLICY_DIR_TOVPN;
1533
1534 /* Were we importing from "import_vrf"? */
1d4e8b0d
DS
1535 for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf, node,
1536 vname)) {
a8dadcf6 1537 if (strcmp(vname, tmp_name) == 0)
020a3f60 1538 break;
44338987 1539 }
1d4e8b0d
DS
1540
1541 /*
1542 * We do not check in the cli if the passed in bgp
1543 * instance is actually imported into us before
1544 * we call this function. As such if we do not
1545 * find this in the import_vrf list than
1546 * we just need to return safely.
1547 */
44338987 1548 if (!vname)
1549 return;
1550
1551 /* Remove "import_vrf" from our import list. */
1d4e8b0d 1552 listnode_delete(to_bgp->vpn_policy[afi].import_vrf, vname);
44338987 1553 XFREE(MTYPE_TMP, vname);
1554
1555 /* Remove routes imported from "import_vrf". */
1556 /* TODO: In the current logic, we have to first remove all
1557 * imported routes and then (if needed) import back routes
1558 */
1d4e8b0d 1559 vpn_leak_prechange(idir, afi, bgp_get_default(), to_bgp);
44338987 1560
1d4e8b0d
DS
1561 if (to_bgp->vpn_policy[afi].import_vrf->count == 0) {
1562 UNSET_FLAG(to_bgp->af_flags[afi][safi],
44338987 1563 BGP_CONFIG_VRF_TO_VRF_IMPORT);
1d4e8b0d 1564 ecommunity_free(&to_bgp->vpn_policy[afi].rtlist[idir]);
44338987 1565 } else {
1d4e8b0d
DS
1566 ecom = from_bgp->vpn_policy[afi].rtlist[edir];
1567 ecommunity_del_val(to_bgp->vpn_policy[afi].rtlist[idir],
44338987 1568 (struct ecommunity_val *)ecom->val);
1d4e8b0d 1569 vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
44338987 1570 }
1571
89d59347
DS
1572 /*
1573 * What?
1574 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
1575 * below is checking for NULL that export_vrf can be
1576 * NULL, consequently it is complaining( like a cabbage )
1577 * that we could dereference and crash in the listcount(..)
1578 * check below.
1579 * So make it happy, under protest, with liberty and justice
1580 * for all.
1581 */
1d4e8b0d 1582 assert(from_bgp->vpn_policy[afi].export_vrf);
89d59347 1583
44338987 1584 /* Remove us from "import_vrf's" export list. If no other VRF
1585 * is importing from "import_vrf", cleanup appropriately.
1586 */
1d4e8b0d 1587 for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
44338987 1588 node, vname)) {
1589 if (strcmp(vname, export_name) == 0)
1590 break;
1591 }
1592
1d4e8b0d
DS
1593 /*
1594 * If we have gotten to this point then the vname must
1595 * exist. If not, we are in a world of trouble and
1596 * have slag sitting around.
1597 *
1598 * import_vrf and export_vrf must match in having
1599 * the in/out names as appropriate.
1600 */
1601 assert(vname);
1602
1603 listnode_delete(from_bgp->vpn_policy[afi].export_vrf, vname);
44338987 1604 XFREE(MTYPE_TMP, vname);
1605
1d4e8b0d
DS
1606 if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
1607 vpn_leak_prechange(edir, afi, bgp_get_default(), from_bgp);
1608 ecommunity_free(&from_bgp->vpn_policy[afi].rtlist[edir]);
1609 UNSET_FLAG(from_bgp->af_flags[afi][safi],
44338987 1610 BGP_CONFIG_VRF_TO_VRF_EXPORT);
1d4e8b0d 1611 memset(&from_bgp->vpn_policy[afi].tovpn_rd, 0,
44338987 1612 sizeof(struct prefix_rd));
1d4e8b0d 1613 UNSET_FLAG(from_bgp->vpn_policy[afi].flags,
44338987 1614 BGP_VPN_POLICY_TOVPN_RD_SET);
1615 }
1616}
1617
718e3744 1618/* For testing purpose, static route of MPLS-VPN. */
1619DEFUN (vpnv4_network,
1620 vpnv4_network_cmd,
d114b977 1621 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1622 "Specify a network to announce via BGP\n"
0c7b1b01 1623 "IPv4 prefix\n"
718e3744 1624 "Specify Route Distinguisher\n"
1625 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1626 "VPN NLRI label (tag)\n"
1627 "VPN NLRI label (tag)\n"
1628 "Label value\n")
718e3744 1629{
d62a17ae 1630 int idx_ipv4_prefixlen = 1;
1631 int idx_ext_community = 3;
1632 int idx_label = 5;
1633 return bgp_static_set_safi(
1634 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1635 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
1636 NULL, NULL, NULL, NULL);
137446f9
LB
1637}
1638
1639DEFUN (vpnv4_network_route_map,
1640 vpnv4_network_route_map_cmd,
d114b977 1641 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
137446f9 1642 "Specify a network to announce via BGP\n"
0c7b1b01 1643 "IPv4 prefix\n"
137446f9
LB
1644 "Specify Route Distinguisher\n"
1645 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1646 "VPN NLRI label (tag)\n"
1647 "VPN NLRI label (tag)\n"
1648 "Label value\n"
137446f9
LB
1649 "route map\n"
1650 "route map name\n")
1651{
d62a17ae 1652 int idx_ipv4_prefixlen = 1;
1653 int idx_ext_community = 3;
1654 int idx_label = 5;
1655 int idx_word_2 = 7;
1656 return bgp_static_set_safi(
1657 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1658 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1659 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
718e3744 1660}
1661
1662/* For testing purpose, static route of MPLS-VPN. */
1663DEFUN (no_vpnv4_network,
1664 no_vpnv4_network_cmd,
d114b977 1665 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1666 NO_STR
1667 "Specify a network to announce via BGP\n"
0c7b1b01 1668 "IPv4 prefix\n"
718e3744 1669 "Specify Route Distinguisher\n"
1670 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1671 "VPN NLRI label (tag)\n"
1672 "VPN NLRI label (tag)\n"
1673 "Label value\n")
718e3744 1674{
d62a17ae 1675 int idx_ipv4_prefixlen = 2;
1676 int idx_ext_community = 4;
1677 int idx_label = 6;
1678 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
1679 argv[idx_ipv4_prefixlen]->arg,
1680 argv[idx_ext_community]->arg,
1681 argv[idx_label]->arg, 0, NULL, NULL, NULL);
718e3744 1682}
1683
c286be96
LX
1684DEFUN (vpnv6_network,
1685 vpnv6_network_cmd,
d114b977 1686 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
c286be96
LX
1687 "Specify a network to announce via BGP\n"
1688 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1689 "Specify Route Distinguisher\n"
1690 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1691 "VPN NLRI label (tag)\n"
1692 "VPN NLRI label (tag)\n"
1693 "Label value\n"
11daee81
DS
1694 "route map\n"
1695 "route map name\n")
c286be96 1696{
d62a17ae 1697 int idx_ipv6_prefix = 1;
1698 int idx_ext_community = 3;
1699 int idx_label = 5;
1700 int idx_word_2 = 7;
1701 if (argc == 8)
1702 return bgp_static_set_safi(
1703 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1704 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1705 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
1706 else
1707 return bgp_static_set_safi(
1708 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1709 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1710 NULL, 0, NULL, NULL, NULL, NULL);
c286be96
LX
1711}
1712
1713/* For testing purpose, static route of MPLS-VPN. */
1714DEFUN (no_vpnv6_network,
1715 no_vpnv6_network_cmd,
d114b977 1716 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
c286be96
LX
1717 NO_STR
1718 "Specify a network to announce via BGP\n"
1719 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1720 "Specify Route Distinguisher\n"
1721 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1722 "VPN NLRI label (tag)\n"
1723 "VPN NLRI label (tag)\n"
1724 "Label value\n")
c286be96 1725{
d62a17ae 1726 int idx_ipv6_prefix = 2;
1727 int idx_ext_community = 4;
1728 int idx_label = 6;
1729 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
1730 argv[idx_ipv6_prefix]->arg,
1731 argv[idx_ext_community]->arg,
1732 argv[idx_label]->arg, 0, NULL, NULL, NULL);
c286be96
LX
1733}
1734
d62a17ae 1735int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
1736 enum bgp_show_type type, void *output_arg, int tags,
d7c0a89a 1737 uint8_t use_json)
718e3744 1738{
d62a17ae 1739 struct bgp *bgp;
1740 struct bgp_table *table;
d62a17ae 1741
1742 bgp = bgp_get_default();
1743 if (bgp == NULL) {
1744 if (!use_json)
1745 vty_out(vty, "No BGP process is configured\n");
16307668
RW
1746 else
1747 vty_out(vty, "{}\n");
d62a17ae 1748 return CMD_WARNING;
1749 }
1ae44dfc 1750 table = bgp->rib[afi][SAFI_MPLS_VPN];
a4d82a8a
PZ
1751 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
1752 output_arg, use_json);
718e3744 1753}
1754
4f280b15
LB
1755DEFUN (show_bgp_ip_vpn_all_rd,
1756 show_bgp_ip_vpn_all_rd_cmd,
d114b977 1757 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
e3e29b32
LB
1758 SHOW_STR
1759 BGP_STR
05e588f4 1760 BGP_VPNVX_HELP_STR
e3e29b32 1761 "Display VPN NLRI specific information\n"
af8528fa 1762 "Display VPN NLRI specific information\n"
e3e29b32
LB
1763 "Display information for a route distinguisher\n"
1764 "VPN Route Distinguisher\n"
1765 JSON_STR)
1766{
d62a17ae 1767 int ret;
1768 struct prefix_rd prd;
1769 afi_t afi;
1770 int idx = 0;
1771
1772 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
3d7c4cd7 1773 if (argv_find(argv, argc, "rd", &idx)) {
a4d82a8a 1774 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
d62a17ae 1775 if (!ret) {
1776 vty_out(vty,
1777 "%% Malformed Route Distinguisher\n");
1778 return CMD_WARNING;
1779 }
1780 return bgp_show_mpls_vpn(vty, afi, &prd,
1781 bgp_show_type_normal, NULL, 0,
1782 use_json(argc, argv));
1783 } else {
1784 return bgp_show_mpls_vpn(vty, afi, NULL,
1785 bgp_show_type_normal, NULL, 0,
1786 use_json(argc, argv));
1787 }
1788 }
1789 return CMD_SUCCESS;
718e3744 1790}
1791
af8528fa
LB
1792ALIAS(show_bgp_ip_vpn_all_rd,
1793 show_bgp_ip_vpn_rd_cmd,
1794 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1795 SHOW_STR
1796 BGP_STR
1797 BGP_VPNVX_HELP_STR
1798 "Display VPN NLRI specific information\n"
1799 "Display information for a route distinguisher\n"
1800 "VPN Route Distinguisher\n"
1801 JSON_STR)
1802
1803#ifdef KEEP_OLD_VPN_COMMANDS
3f227172
PG
1804DEFUN (show_ip_bgp_vpn_rd,
1805 show_ip_bgp_vpn_rd_cmd,
af8528fa 1806 "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
718e3744 1807 SHOW_STR
1808 IP_STR
1809 BGP_STR
4f280b15 1810 BGP_AFI_HELP_STR
3517059b 1811 "Address Family modifier\n"
718e3744 1812 "Display information for a route distinguisher\n"
1813 "VPN Route Distinguisher\n")
1814{
d62a17ae 1815 int idx_ext_community = argc - 1;
1816 int ret;
1817 struct prefix_rd prd;
1818 afi_t afi;
1819 int idx = 0;
1820
1821 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1822 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1823 if (!ret) {
1824 vty_out(vty, "%% Malformed Route Distinguisher\n");
1825 return CMD_WARNING;
1826 }
1827 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1828 NULL, 0, 0);
1829 }
1830 return CMD_SUCCESS;
1831}
718e3744 1832
4f280b15
LB
1833DEFUN (show_ip_bgp_vpn_all,
1834 show_ip_bgp_vpn_all_cmd,
1835 "show [ip] bgp <vpnv4|vpnv6>",
1836 SHOW_STR
1837 IP_STR
1838 BGP_STR
1839 BGP_VPNVX_HELP_STR)
1840{
d62a17ae 1841 afi_t afi;
1842 int idx = 0;
4f280b15 1843
d62a17ae 1844 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1845 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1846 NULL, 0, 0);
1847 return CMD_SUCCESS;
4f280b15
LB
1848}
1849
3f227172
PG
1850DEFUN (show_ip_bgp_vpn_all_tags,
1851 show_ip_bgp_vpn_all_tags_cmd,
1852 "show [ip] bgp <vpnv4|vpnv6> all tags",
718e3744 1853 SHOW_STR
1854 IP_STR
1855 BGP_STR
3f227172
PG
1856 BGP_VPNVX_HELP_STR
1857 "Display information about all VPNv4/VPNV6 NLRIs\n"
718e3744 1858 "Display BGP tags for prefixes\n")
1859{
d62a17ae 1860 afi_t afi;
1861 int idx = 0;
3f227172 1862
d62a17ae 1863 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1864 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1865 NULL, 1, 0);
1866 return CMD_SUCCESS;
718e3744 1867}
1868
3f227172
PG
1869DEFUN (show_ip_bgp_vpn_rd_tags,
1870 show_ip_bgp_vpn_rd_tags_cmd,
d114b977 1871 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
718e3744 1872 SHOW_STR
1873 IP_STR
1874 BGP_STR
3f227172 1875 BGP_VPNVX_HELP_STR
718e3744 1876 "Display information for a route distinguisher\n"
1877 "VPN Route Distinguisher\n"
1878 "Display BGP tags for prefixes\n")
1879{
d62a17ae 1880 int idx_ext_community = 5;
1881 int ret;
1882 struct prefix_rd prd;
1883 afi_t afi;
1884 int idx = 0;
1885
1886 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1887 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1888 if (!ret) {
1889 vty_out(vty, "%% Malformed Route Distinguisher\n");
1890 return CMD_WARNING;
1891 }
1892 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1893 NULL, 1, 0);
1894 }
1895 return CMD_SUCCESS;
718e3744 1896}
1897
3f227172
PG
1898DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
1899 show_ip_bgp_vpn_all_neighbor_routes_cmd,
1900 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
718e3744 1901 SHOW_STR
1902 IP_STR
1903 BGP_STR
3f227172
PG
1904 BGP_VPNVX_HELP_STR
1905 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 1906 "Detailed information on TCP and BGP neighbor connections\n"
1907 "Neighbor to display information about\n"
856ca177 1908 "Display routes learned from neighbor\n"
9973d184 1909 JSON_STR)
718e3744 1910{
d62a17ae 1911 int idx_ipv4 = 6;
1912 union sockunion su;
1913 struct peer *peer;
1914 int ret;
d7c0a89a 1915 uint8_t uj = use_json(argc, argv);
d62a17ae 1916 afi_t afi;
1917 int idx = 0;
1918
1919 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1920 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1921 if (ret < 0) {
1922 if (uj) {
1923 json_object *json_no = NULL;
1924 json_no = json_object_new_object();
1925 json_object_string_add(json_no, "warning",
1926 "Malformed address");
1927 vty_out(vty, "%s\n",
1928 json_object_to_json_string(json_no));
1929 json_object_free(json_no);
1930 } else
1931 vty_out(vty, "Malformed address: %s\n",
1932 argv[idx_ipv4]->arg);
1933 return CMD_WARNING;
1934 }
1935
1936 peer = peer_lookup(NULL, &su);
1937 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1938 if (uj) {
1939 json_object *json_no = NULL;
1940 json_no = json_object_new_object();
1941 json_object_string_add(
1942 json_no, "warning",
1943 "No such neighbor or address family");
1944 vty_out(vty, "%s\n",
1945 json_object_to_json_string(json_no));
1946 json_object_free(json_no);
1947 } else
1948 vty_out(vty,
1949 "%% No such neighbor or address family\n");
1950 return CMD_WARNING;
1951 }
1952
1953 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
1954 &su, 0, uj);
1955 }
1956 return CMD_SUCCESS;
718e3744 1957}
1958
3f227172
PG
1959DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
1960 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
d114b977 1961 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
718e3744 1962 SHOW_STR
1963 IP_STR
1964 BGP_STR
3f227172 1965 BGP_VPNVX_HELP_STR
718e3744 1966 "Display information for a route distinguisher\n"
1967 "VPN Route Distinguisher\n"
1968 "Detailed information on TCP and BGP neighbor connections\n"
1969 "Neighbor to display information about\n"
856ca177 1970 "Display routes learned from neighbor\n"
9973d184 1971 JSON_STR)
718e3744 1972{
d62a17ae 1973 int idx_ext_community = 5;
1974 int idx_ipv4 = 7;
1975 int ret;
1976 union sockunion su;
1977 struct peer *peer;
1978 struct prefix_rd prd;
d7c0a89a 1979 uint8_t uj = use_json(argc, argv);
d62a17ae 1980 afi_t afi;
1981 int idx = 0;
1982
1983 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1984 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1985 if (!ret) {
1986 if (uj) {
1987 json_object *json_no = NULL;
1988 json_no = json_object_new_object();
1989 json_object_string_add(
1990 json_no, "warning",
1991 "Malformed Route Distinguisher");
1992 vty_out(vty, "%s\n",
1993 json_object_to_json_string(json_no));
1994 json_object_free(json_no);
1995 } else
1996 vty_out(vty,
1997 "%% Malformed Route Distinguisher\n");
1998 return CMD_WARNING;
1999 }
2000
2001 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2002 if (ret < 0) {
2003 if (uj) {
2004 json_object *json_no = NULL;
2005 json_no = json_object_new_object();
2006 json_object_string_add(json_no, "warning",
2007 "Malformed address");
2008 vty_out(vty, "%s\n",
2009 json_object_to_json_string(json_no));
2010 json_object_free(json_no);
2011 } else
2012 vty_out(vty, "Malformed address: %s\n",
2013 argv[idx_ext_community]->arg);
2014 return CMD_WARNING;
2015 }
2016
2017 peer = peer_lookup(NULL, &su);
2018 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2019 if (uj) {
2020 json_object *json_no = NULL;
2021 json_no = json_object_new_object();
2022 json_object_string_add(
2023 json_no, "warning",
2024 "No such neighbor or address family");
2025 vty_out(vty, "%s\n",
2026 json_object_to_json_string(json_no));
2027 json_object_free(json_no);
2028 } else
2029 vty_out(vty,
2030 "%% No such neighbor or address family\n");
2031 return CMD_WARNING;
2032 }
2033
2034 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_neighbor,
2035 &su, 0, uj);
2036 }
2037 return CMD_SUCCESS;
718e3744 2038}
2039
3f227172
PG
2040DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
2041 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
2042 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
718e3744 2043 SHOW_STR
2044 IP_STR
2045 BGP_STR
3f227172
PG
2046 BGP_VPNVX_HELP_STR
2047 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 2048 "Detailed information on TCP and BGP neighbor connections\n"
2049 "Neighbor to display information about\n"
856ca177 2050 "Display the routes advertised to a BGP neighbor\n"
9973d184 2051 JSON_STR)
718e3744 2052{
d62a17ae 2053 int idx_ipv4 = 6;
2054 int ret;
2055 struct peer *peer;
2056 union sockunion su;
d7c0a89a 2057 uint8_t uj = use_json(argc, argv);
d62a17ae 2058 afi_t afi;
2059 int idx = 0;
2060
2061 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2062 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2063 if (ret < 0) {
2064 if (uj) {
2065 json_object *json_no = NULL;
2066 json_no = json_object_new_object();
2067 json_object_string_add(json_no, "warning",
2068 "Malformed address");
2069 vty_out(vty, "%s\n",
2070 json_object_to_json_string(json_no));
2071 json_object_free(json_no);
2072 } else
2073 vty_out(vty, "Malformed address: %s\n",
2074 argv[idx_ipv4]->arg);
2075 return CMD_WARNING;
2076 }
2077 peer = peer_lookup(NULL, &su);
2078 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2079 if (uj) {
2080 json_object *json_no = NULL;
2081 json_no = json_object_new_object();
2082 json_object_string_add(
2083 json_no, "warning",
2084 "No such neighbor or address family");
2085 vty_out(vty, "%s\n",
2086 json_object_to_json_string(json_no));
2087 json_object_free(json_no);
2088 } else
2089 vty_out(vty,
2090 "%% No such neighbor or address family\n");
2091 return CMD_WARNING;
2092 }
2093 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
2094 SAFI_MPLS_VPN, uj);
2095 }
2096 return CMD_SUCCESS;
718e3744 2097}
2098
3f227172
PG
2099DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
2100 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
d114b977 2101 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
718e3744 2102 SHOW_STR
2103 IP_STR
2104 BGP_STR
3f227172 2105 BGP_VPNVX_HELP_STR
718e3744 2106 "Display information for a route distinguisher\n"
2107 "VPN Route Distinguisher\n"
2108 "Detailed information on TCP and BGP neighbor connections\n"
2109 "Neighbor to display information about\n"
856ca177 2110 "Display the routes advertised to a BGP neighbor\n"
9973d184 2111 JSON_STR)
718e3744 2112{
d62a17ae 2113 int idx_ext_community = 5;
2114 int idx_ipv4 = 7;
2115 int ret;
2116 struct peer *peer;
2117 struct prefix_rd prd;
2118 union sockunion su;
d7c0a89a 2119 uint8_t uj = use_json(argc, argv);
d62a17ae 2120 afi_t afi;
2121 int idx = 0;
2122
2123 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2124 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2125 if (ret < 0) {
2126 if (uj) {
2127 json_object *json_no = NULL;
2128 json_no = json_object_new_object();
2129 json_object_string_add(json_no, "warning",
2130 "Malformed address");
2131 vty_out(vty, "%s\n",
2132 json_object_to_json_string(json_no));
2133 json_object_free(json_no);
2134 } else
2135 vty_out(vty, "Malformed address: %s\n",
2136 argv[idx_ext_community]->arg);
2137 return CMD_WARNING;
2138 }
2139 peer = peer_lookup(NULL, &su);
2140 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2141 if (uj) {
2142 json_object *json_no = NULL;
2143 json_no = json_object_new_object();
2144 json_object_string_add(
2145 json_no, "warning",
2146 "No such neighbor or address family");
2147 vty_out(vty, "%s\n",
2148 json_object_to_json_string(json_no));
2149 json_object_free(json_no);
2150 } else
2151 vty_out(vty,
2152 "%% No such neighbor or address family\n");
2153 return CMD_WARNING;
2154 }
2155
2156 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2157 if (!ret) {
2158 if (uj) {
2159 json_object *json_no = NULL;
2160 json_no = json_object_new_object();
2161 json_object_string_add(
2162 json_no, "warning",
2163 "Malformed Route Distinguisher");
2164 vty_out(vty, "%s\n",
2165 json_object_to_json_string(json_no));
2166 json_object_free(json_no);
2167 } else
2168 vty_out(vty,
2169 "%% Malformed Route Distinguisher\n");
2170 return CMD_WARNING;
2171 }
2172
2173 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
2174 SAFI_MPLS_VPN, uj);
2175 }
2176 return CMD_SUCCESS;
718e3744 2177}
d6902373 2178#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2179
d62a17ae 2180void bgp_mplsvpn_init(void)
718e3744 2181{
d62a17ae 2182 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
2183 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
2184 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
718e3744 2185
d62a17ae 2186 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
2187 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
c286be96 2188
d62a17ae 2189 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
af8528fa 2190 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
d6902373 2191#ifdef KEEP_OLD_VPN_COMMANDS
af8528fa 2192 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
d62a17ae 2193 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
2194 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
2195 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
2196 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
2197 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
2198 install_element(VIEW_NODE,
2199 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
2200 install_element(VIEW_NODE,
2201 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
d6902373 2202#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2203}
301ad80a
PG
2204
2205vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
2206{
2207 struct listnode *mnode, *mnnode;
2208 struct bgp *bgp;
2209
2210 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2211 struct ecommunity *ec;
2212
2213 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2214 continue;
2215
2216 ec = bgp->vpn_policy[AFI_IP].import_redirect_rtlist;
2217
2218 if (ecom_intersect(ec, eckey))
2219 return bgp->vrf_id;
2220 }
2221 return VRF_UNKNOWN;
2222}