]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.c
bgpd: Fix SA warning found by clang.
[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)
d793761d 844 vpn_leak_to_vrf_update(bgp_vpn, 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 /*
1177 * For VRF route-leaking, the source will be the originating VRF.
1178 */
d6632478
PZ
1179 if (info_vpn->extra && info_vpn->extra->bgp_orig)
1180 src_vrf = info_vpn->extra->bgp_orig;
1181 else
1182 src_vrf = bgp_vpn;
1183
960035b2
PZ
1184 leak_update(bgp_vrf, bn, new_attr, afi, safi, info_vpn,
1185 pLabels, num_labels,
1186 info_vpn, /* parent */
d6632478 1187 src_vrf, &nexthop_orig, nexthop_self_flag, debug);
ddb5b488
PZ
1188}
1189
1190void vpn_leak_to_vrf_update(struct bgp *bgp_vpn, /* from */
1191 struct bgp_info *info_vpn) /* route */
1192{
1193 struct listnode *mnode, *mnnode;
1194 struct bgp *bgp;
1195
1196 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1197
1198 if (debug)
1199 zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
1200
1201 /* Loop over VRFs */
1202 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
1203
1204 if (!info_vpn->extra
1205 || info_vpn->extra->bgp_orig != bgp) { /* no loop */
1206 vpn_leak_to_vrf_update_onevrf(bgp, bgp_vpn, info_vpn);
1207 }
1208 }
1209}
1210
1211void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */
1212 struct bgp_info *info_vpn) /* route */
1213{
1b3510a0
PZ
1214 struct prefix *p;
1215 afi_t afi;
ddb5b488
PZ
1216 safi_t safi = SAFI_UNICAST;
1217 struct bgp *bgp;
1218 struct listnode *mnode, *mnnode;
ddb5b488
PZ
1219 struct bgp_node *bn;
1220 struct bgp_info *bi;
1221 const char *debugmsg;
960035b2 1222 char buf_prefix[PREFIX_STRLEN];
ddb5b488
PZ
1223
1224 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1225
960035b2
PZ
1226 if (debug) {
1227 prefix2str(&info_vpn->net->p, buf_prefix, sizeof(buf_prefix));
1228 zlog_debug("%s: entry: p=%s, type=%d, sub_type=%d",
1229 __func__, buf_prefix,
1230 info_vpn->type, info_vpn->sub_type);
1231 }
1232
ddb5b488
PZ
1233 if (debug)
1234 zlog_debug("%s: start (info_vpn=%p)", __func__, info_vpn);
1235
1b3510a0 1236 if (!info_vpn->net) {
56c2c080 1237#if ENABLE_BGP_VNC
1b3510a0
PZ
1238 /* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
1239 if (info_vpn->type == ZEBRA_ROUTE_BGP &&
1240 info_vpn->sub_type == BGP_ROUTE_RFP) {
1241
1242 return;
1243 }
56c2c080 1244#endif
1b3510a0
PZ
1245 if (debug)
1246 zlog_debug("%s: info_vpn->net unexpectedly NULL, no prefix, bailing",
1247 __func__);
1248 return;
1249 }
1250
1251 p = &info_vpn->net->p;
1252 afi = family2afi(p->family);
ddb5b488
PZ
1253
1254 /* Loop over VRFs */
1255 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
b9c7bc5a 1256 if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
ddb5b488
PZ
1257 if (debug)
1258 zlog_debug("%s: skipping: %s", __func__,
1259 debugmsg);
1260 continue;
1261 }
1262
1263 /* Check for intersection of route targets */
1264 if (!ecom_intersect(bgp->vpn_policy[afi]
1265 .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1266 info_vpn->attr->ecommunity)) {
1267
1268 continue;
1269 }
1270
1271 if (debug)
1272 zlog_debug("%s: withdrawing from vrf %s", __func__,
960035b2 1273 bgp->name_pretty);
ddb5b488
PZ
1274
1275 bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
1276 for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
1277 if (bi->extra
1278 && (struct bgp_info *)bi->extra->parent
1279 == info_vpn) {
1280 break;
1281 }
1282 }
1283
1284 if (bi) {
1285 if (debug)
1286 zlog_debug("%s: deleting bi %p", __func__, bi);
1287 bgp_aggregate_decrement(bgp, p, bi, afi, safi);
1288 bgp_info_delete(bn, bi);
1289 bgp_process(bgp, bn, afi, safi);
1290 }
1291 bgp_unlock_node(bn);
1292 }
1293}
1294
1295void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
1296 afi_t afi)
1297{
1298 struct bgp_node *bn;
1299 struct bgp_info *bi;
1300 safi_t safi = SAFI_UNICAST;
1301 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
ddb5b488
PZ
1302
1303 if (debug)
1304 zlog_debug("%s: entry", __func__);
1305 /*
d793761d 1306 * Walk vrf table, delete bi with bgp_orig in a different vrf
ddb5b488
PZ
1307 */
1308 for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
1309 bn = bgp_route_next(bn)) {
1310
1311 for (bi = bn->info; bi; bi = bi->next) {
d793761d 1312 if (bi->extra && bi->extra->bgp_orig != bgp_vrf) {
ddb5b488
PZ
1313
1314 /* delete route */
1315 bgp_aggregate_decrement(bgp_vrf, &bn->p, bi,
1316 afi, safi);
1317 bgp_info_delete(bn, bi);
1318 bgp_process(bgp_vrf, bn, afi, safi);
1319 }
1320 }
1321 }
1322}
1323
1324void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
1325 struct bgp *bgp_vpn, /* from */
1326 afi_t afi)
1327{
1328 struct prefix_rd prd;
1329 struct bgp_node *prn;
1330 safi_t safi = SAFI_MPLS_VPN;
1331
1332 /*
1333 * Walk vpn table
1334 */
1335 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
1336 prn = bgp_route_next(prn)) {
1337
1338 struct bgp_table *table;
1339 struct bgp_node *bn;
1340 struct bgp_info *bi;
1341
1342 memset(&prd, 0, sizeof(prd));
1343 prd.family = AF_UNSPEC;
1344 prd.prefixlen = 64;
1345 memcpy(prd.val, prn->p.u.val, 8);
1346
1347 /* This is the per-RD table of prefixes */
1348 table = prn->info;
1349
1350 if (!table)
1351 continue;
1352
1353 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
1354
1355 for (bi = bn->info; bi; bi = bi->next) {
1356
1357 if (bi->extra && bi->extra->bgp_orig == bgp_vrf)
1358 continue;
1359
1360 vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
1361 bi);
1362 }
1363 }
1364 }
1365}
1366
d92a55df
PZ
1367/*
1368 * This function is called for definition/deletion/change to a route-map
1369 */
ddb5b488
PZ
1370static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
1371{
1372 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1373 afi_t afi;
1374 struct route_map *rmap;
1375
1376 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1377 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
1378
1379 return;
1380 }
1381
1382 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
1383
1384 for (afi = 0; afi < AFI_MAX; ++afi) {
1385
d92a55df
PZ
1386 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
1387 && !strcmp(rmap_name,
ddb5b488
PZ
1388 bgp->vpn_policy[afi]
1389 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
1390
1391 if (debug)
1392 zlog_debug(
1393 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1394 __func__, rmap_name, bgp->as,
1395 afi2str(afi));
1396
1397 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1398 bgp_get_default(), bgp);
1399 if (debug)
1400 zlog_debug("%s: after vpn_leak_prechange",
1401 __func__);
1402
d92a55df
PZ
1403 /* in case of definition/deletion */
1404 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN] =
1405 rmap;
ddb5b488
PZ
1406
1407 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1408 bgp_get_default(), bgp);
d92a55df 1409
ddb5b488
PZ
1410 if (debug)
1411 zlog_debug("%s: after vpn_leak_postchange",
1412 __func__);
1413 }
1414
d92a55df
PZ
1415 if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]
1416 && !strcmp(rmap_name,
1417 bgp->vpn_policy[afi]
1418 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN])) {
b9c7bc5a
PZ
1419
1420 if (debug) {
1421 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
ddb5b488
PZ
1422 __func__, rmap_name, bgp->as,
1423 afi2str(afi));
b9c7bc5a 1424 }
ddb5b488
PZ
1425
1426 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1427 bgp_get_default(), bgp);
1428
d92a55df
PZ
1429 /* in case of definition/deletion */
1430 bgp->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
1431 rmap;
ddb5b488
PZ
1432
1433 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1434 bgp_get_default(), bgp);
1435 }
1436 }
1437}
1438
1439void vpn_policy_routemap_event(const char *rmap_name)
1440{
1441 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1442 struct listnode *mnode, *mnnode;
1443 struct bgp *bgp;
1444
1445 if (debug)
1446 zlog_debug("%s: entry", __func__);
1447
1448 if (bm->bgp == NULL) /* may be called during cleanup */
1449 return;
1450
1451 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
1452 vpn_policy_routemap_update(bgp, rmap_name);
1453}
1454
44338987 1455void vrf_import_from_vrf(struct bgp *bgp, struct bgp *vrf_bgp,
1456 afi_t afi, safi_t safi)
1457{
1458 const char *export_name;
1459 vpn_policy_direction_t idir, edir;
1460 char *vname;
1461 char buf[1000];
1462 struct ecommunity *ecom;
1463 bool first_export = false;
1464
1465 export_name = bgp->name ? bgp->name : VRF_DEFAULT_NAME;
1466 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1467 edir = BGP_VPN_POLICY_DIR_TOVPN;
1468
1469
1470 /* Cross-ref both VRFs. Also, note if this is the first time
1471 * any VRF is importing from "import_vrf".
1472 */
1473 vname = XSTRDUP(MTYPE_TMP, vrf_bgp->name);
1474 listnode_add(bgp->vpn_policy[afi].import_vrf, vname);
1475
1476 if (!listcount(vrf_bgp->vpn_policy[afi].export_vrf))
1477 first_export = true;
1478 vname = XSTRDUP(MTYPE_TMP, export_name);
1479 listnode_add(vrf_bgp->vpn_policy[afi].export_vrf, vname);
1480
1481 /* Update import RT for current VRF using export RT of the VRF we're
1482 * importing from. First though, make sure "import_vrf" has that
1483 * set.
1484 */
1485 if (first_export) {
1486 form_auto_rd(vrf_bgp->router_id, vrf_bgp->vrf_rd_id,
1487 &vrf_bgp->vrf_prd_auto);
1488 vrf_bgp->vpn_policy[afi].tovpn_rd = vrf_bgp->vrf_prd_auto;
1489 SET_FLAG(vrf_bgp->vpn_policy[afi].flags,
1490 BGP_VPN_POLICY_TOVPN_RD_SET);
1491 prefix_rd2str(&vrf_bgp->vpn_policy[afi].tovpn_rd,
1492 buf, sizeof(buf));
1493 vrf_bgp->vpn_policy[afi].rtlist[edir] =
1494 ecommunity_str2com(buf, ECOMMUNITY_ROUTE_TARGET, 0);
1495 SET_FLAG(vrf_bgp->af_flags[afi][safi],
1496 BGP_CONFIG_VRF_TO_VRF_EXPORT);
1497 }
1498 ecom = vrf_bgp->vpn_policy[afi].rtlist[edir];
1499 if (bgp->vpn_policy[afi].rtlist[idir])
1500 bgp->vpn_policy[afi].rtlist[idir] =
1501 ecommunity_merge(bgp->vpn_policy[afi]
1502 .rtlist[idir], ecom);
1503 else
1504 bgp->vpn_policy[afi].rtlist[idir] = ecommunity_dup(ecom);
1505 SET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT);
1506
1507 /* Does "import_vrf" first need to export its routes or that
1508 * is already done and we just need to import those routes
1509 * from the global table?
1510 */
1511 if (first_export)
1512 vpn_leak_postchange(edir, afi, bgp_get_default(), vrf_bgp);
1513 else
1514 vpn_leak_postchange(idir, afi, bgp_get_default(), bgp);
1515}
1516
1517void vrf_unimport_from_vrf(struct bgp *bgp, struct bgp *vrf_bgp,
1518 afi_t afi, safi_t safi)
1519{
1520 const char *export_name;
1521 vpn_policy_direction_t idir, edir;
1522 char *vname;
1523 struct ecommunity *ecom;
1524 struct listnode *node;
1525
1526 export_name = bgp->name ? bgp->name : VRF_DEFAULT_NAME;
1527 idir = BGP_VPN_POLICY_DIR_FROMVPN;
1528 edir = BGP_VPN_POLICY_DIR_TOVPN;
1529
1530 /* Were we importing from "import_vrf"? */
1531 for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].import_vrf, node,
1532 vname)) {
1533 if (strcmp(vname, vrf_bgp->name) == 0)
020a3f60 1534 break;
44338987 1535 }
1536 if (!vname)
1537 return;
1538
1539 /* Remove "import_vrf" from our import list. */
1540 listnode_delete(bgp->vpn_policy[afi].import_vrf, vname);
1541 XFREE(MTYPE_TMP, vname);
1542
1543 /* Remove routes imported from "import_vrf". */
1544 /* TODO: In the current logic, we have to first remove all
1545 * imported routes and then (if needed) import back routes
1546 */
1547 vpn_leak_prechange(idir, afi, bgp_get_default(), bgp);
1548
1549 if (bgp->vpn_policy[afi].import_vrf->count == 0) {
1550 UNSET_FLAG(bgp->af_flags[afi][safi],
1551 BGP_CONFIG_VRF_TO_VRF_IMPORT);
1552 ecommunity_free(&bgp->vpn_policy[afi].rtlist[idir]);
1553 } else {
1554 ecom = vrf_bgp->vpn_policy[afi].rtlist[edir];
1555 ecommunity_del_val(bgp->vpn_policy[afi].rtlist[idir],
1556 (struct ecommunity_val *)ecom->val);
1557 vpn_leak_postchange(idir, afi, bgp_get_default(), bgp);
1558 }
1559
89d59347
DS
1560 /*
1561 * What?
1562 * So SA is assuming that since the ALL_LIST_ELEMENTS_RO
1563 * below is checking for NULL that export_vrf can be
1564 * NULL, consequently it is complaining( like a cabbage )
1565 * that we could dereference and crash in the listcount(..)
1566 * check below.
1567 * So make it happy, under protest, with liberty and justice
1568 * for all.
1569 */
1570 assert(vrf_bgp->vpn_policy[afi].export_vrf);
1571
44338987 1572 /* Remove us from "import_vrf's" export list. If no other VRF
1573 * is importing from "import_vrf", cleanup appropriately.
1574 */
1575 for (ALL_LIST_ELEMENTS_RO(vrf_bgp->vpn_policy[afi].export_vrf,
1576 node, vname)) {
1577 if (strcmp(vname, export_name) == 0)
1578 break;
1579 }
1580
1581 listnode_delete(vrf_bgp->vpn_policy[afi].export_vrf, vname);
1582 XFREE(MTYPE_TMP, vname);
1583
1584 if (!listcount(vrf_bgp->vpn_policy[afi].export_vrf)) {
1585 vpn_leak_prechange(edir, afi, bgp_get_default(), vrf_bgp);
1586 ecommunity_free(&vrf_bgp->vpn_policy[afi].rtlist[edir]);
1587 UNSET_FLAG(vrf_bgp->af_flags[afi][safi],
1588 BGP_CONFIG_VRF_TO_VRF_EXPORT);
1589 memset(&vrf_bgp->vpn_policy[afi].tovpn_rd, 0,
1590 sizeof(struct prefix_rd));
1591 UNSET_FLAG(vrf_bgp->vpn_policy[afi].flags,
1592 BGP_VPN_POLICY_TOVPN_RD_SET);
1593 }
1594}
1595
718e3744 1596/* For testing purpose, static route of MPLS-VPN. */
1597DEFUN (vpnv4_network,
1598 vpnv4_network_cmd,
d114b977 1599 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1600 "Specify a network to announce via BGP\n"
0c7b1b01 1601 "IPv4 prefix\n"
718e3744 1602 "Specify Route Distinguisher\n"
1603 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1604 "VPN NLRI label (tag)\n"
1605 "VPN NLRI label (tag)\n"
1606 "Label value\n")
718e3744 1607{
d62a17ae 1608 int idx_ipv4_prefixlen = 1;
1609 int idx_ext_community = 3;
1610 int idx_label = 5;
1611 return bgp_static_set_safi(
1612 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1613 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
1614 NULL, NULL, NULL, NULL);
137446f9
LB
1615}
1616
1617DEFUN (vpnv4_network_route_map,
1618 vpnv4_network_route_map_cmd,
d114b977 1619 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
137446f9 1620 "Specify a network to announce via BGP\n"
0c7b1b01 1621 "IPv4 prefix\n"
137446f9
LB
1622 "Specify Route Distinguisher\n"
1623 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1624 "VPN NLRI label (tag)\n"
1625 "VPN NLRI label (tag)\n"
1626 "Label value\n"
137446f9
LB
1627 "route map\n"
1628 "route map name\n")
1629{
d62a17ae 1630 int idx_ipv4_prefixlen = 1;
1631 int idx_ext_community = 3;
1632 int idx_label = 5;
1633 int idx_word_2 = 7;
1634 return bgp_static_set_safi(
1635 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1636 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1637 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
718e3744 1638}
1639
1640/* For testing purpose, static route of MPLS-VPN. */
1641DEFUN (no_vpnv4_network,
1642 no_vpnv4_network_cmd,
d114b977 1643 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1644 NO_STR
1645 "Specify a network to announce via BGP\n"
0c7b1b01 1646 "IPv4 prefix\n"
718e3744 1647 "Specify Route Distinguisher\n"
1648 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1649 "VPN NLRI label (tag)\n"
1650 "VPN NLRI label (tag)\n"
1651 "Label value\n")
718e3744 1652{
d62a17ae 1653 int idx_ipv4_prefixlen = 2;
1654 int idx_ext_community = 4;
1655 int idx_label = 6;
1656 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
1657 argv[idx_ipv4_prefixlen]->arg,
1658 argv[idx_ext_community]->arg,
1659 argv[idx_label]->arg, 0, NULL, NULL, NULL);
718e3744 1660}
1661
c286be96
LX
1662DEFUN (vpnv6_network,
1663 vpnv6_network_cmd,
d114b977 1664 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
c286be96
LX
1665 "Specify a network to announce via BGP\n"
1666 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1667 "Specify Route Distinguisher\n"
1668 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1669 "VPN NLRI label (tag)\n"
1670 "VPN NLRI label (tag)\n"
1671 "Label value\n"
11daee81
DS
1672 "route map\n"
1673 "route map name\n")
c286be96 1674{
d62a17ae 1675 int idx_ipv6_prefix = 1;
1676 int idx_ext_community = 3;
1677 int idx_label = 5;
1678 int idx_word_2 = 7;
1679 if (argc == 8)
1680 return bgp_static_set_safi(
1681 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1682 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1683 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
1684 else
1685 return bgp_static_set_safi(
1686 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1687 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1688 NULL, 0, NULL, NULL, NULL, NULL);
c286be96
LX
1689}
1690
1691/* For testing purpose, static route of MPLS-VPN. */
1692DEFUN (no_vpnv6_network,
1693 no_vpnv6_network_cmd,
d114b977 1694 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
c286be96
LX
1695 NO_STR
1696 "Specify a network to announce via BGP\n"
1697 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1698 "Specify Route Distinguisher\n"
1699 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1700 "VPN NLRI label (tag)\n"
1701 "VPN NLRI label (tag)\n"
1702 "Label value\n")
c286be96 1703{
d62a17ae 1704 int idx_ipv6_prefix = 2;
1705 int idx_ext_community = 4;
1706 int idx_label = 6;
1707 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
1708 argv[idx_ipv6_prefix]->arg,
1709 argv[idx_ext_community]->arg,
1710 argv[idx_label]->arg, 0, NULL, NULL, NULL);
c286be96
LX
1711}
1712
d62a17ae 1713int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
1714 enum bgp_show_type type, void *output_arg, int tags,
d7c0a89a 1715 uint8_t use_json)
718e3744 1716{
d62a17ae 1717 struct bgp *bgp;
1718 struct bgp_table *table;
d62a17ae 1719
1720 bgp = bgp_get_default();
1721 if (bgp == NULL) {
1722 if (!use_json)
1723 vty_out(vty, "No BGP process is configured\n");
16307668
RW
1724 else
1725 vty_out(vty, "{}\n");
d62a17ae 1726 return CMD_WARNING;
1727 }
1ae44dfc 1728 table = bgp->rib[afi][SAFI_MPLS_VPN];
a4d82a8a
PZ
1729 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
1730 output_arg, use_json);
718e3744 1731}
1732
4f280b15
LB
1733DEFUN (show_bgp_ip_vpn_all_rd,
1734 show_bgp_ip_vpn_all_rd_cmd,
d114b977 1735 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
e3e29b32
LB
1736 SHOW_STR
1737 BGP_STR
05e588f4 1738 BGP_VPNVX_HELP_STR
e3e29b32 1739 "Display VPN NLRI specific information\n"
af8528fa 1740 "Display VPN NLRI specific information\n"
e3e29b32
LB
1741 "Display information for a route distinguisher\n"
1742 "VPN Route Distinguisher\n"
1743 JSON_STR)
1744{
d62a17ae 1745 int ret;
1746 struct prefix_rd prd;
1747 afi_t afi;
1748 int idx = 0;
1749
1750 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
3d7c4cd7 1751 if (argv_find(argv, argc, "rd", &idx)) {
a4d82a8a 1752 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
d62a17ae 1753 if (!ret) {
1754 vty_out(vty,
1755 "%% Malformed Route Distinguisher\n");
1756 return CMD_WARNING;
1757 }
1758 return bgp_show_mpls_vpn(vty, afi, &prd,
1759 bgp_show_type_normal, NULL, 0,
1760 use_json(argc, argv));
1761 } else {
1762 return bgp_show_mpls_vpn(vty, afi, NULL,
1763 bgp_show_type_normal, NULL, 0,
1764 use_json(argc, argv));
1765 }
1766 }
1767 return CMD_SUCCESS;
718e3744 1768}
1769
af8528fa
LB
1770ALIAS(show_bgp_ip_vpn_all_rd,
1771 show_bgp_ip_vpn_rd_cmd,
1772 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1773 SHOW_STR
1774 BGP_STR
1775 BGP_VPNVX_HELP_STR
1776 "Display VPN NLRI specific information\n"
1777 "Display information for a route distinguisher\n"
1778 "VPN Route Distinguisher\n"
1779 JSON_STR)
1780
1781#ifdef KEEP_OLD_VPN_COMMANDS
3f227172
PG
1782DEFUN (show_ip_bgp_vpn_rd,
1783 show_ip_bgp_vpn_rd_cmd,
af8528fa 1784 "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
718e3744 1785 SHOW_STR
1786 IP_STR
1787 BGP_STR
4f280b15 1788 BGP_AFI_HELP_STR
3517059b 1789 "Address Family modifier\n"
718e3744 1790 "Display information for a route distinguisher\n"
1791 "VPN Route Distinguisher\n")
1792{
d62a17ae 1793 int idx_ext_community = argc - 1;
1794 int ret;
1795 struct prefix_rd prd;
1796 afi_t afi;
1797 int idx = 0;
1798
1799 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1800 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1801 if (!ret) {
1802 vty_out(vty, "%% Malformed Route Distinguisher\n");
1803 return CMD_WARNING;
1804 }
1805 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1806 NULL, 0, 0);
1807 }
1808 return CMD_SUCCESS;
1809}
718e3744 1810
4f280b15
LB
1811DEFUN (show_ip_bgp_vpn_all,
1812 show_ip_bgp_vpn_all_cmd,
1813 "show [ip] bgp <vpnv4|vpnv6>",
1814 SHOW_STR
1815 IP_STR
1816 BGP_STR
1817 BGP_VPNVX_HELP_STR)
1818{
d62a17ae 1819 afi_t afi;
1820 int idx = 0;
4f280b15 1821
d62a17ae 1822 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1823 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1824 NULL, 0, 0);
1825 return CMD_SUCCESS;
4f280b15
LB
1826}
1827
3f227172
PG
1828DEFUN (show_ip_bgp_vpn_all_tags,
1829 show_ip_bgp_vpn_all_tags_cmd,
1830 "show [ip] bgp <vpnv4|vpnv6> all tags",
718e3744 1831 SHOW_STR
1832 IP_STR
1833 BGP_STR
3f227172
PG
1834 BGP_VPNVX_HELP_STR
1835 "Display information about all VPNv4/VPNV6 NLRIs\n"
718e3744 1836 "Display BGP tags for prefixes\n")
1837{
d62a17ae 1838 afi_t afi;
1839 int idx = 0;
3f227172 1840
d62a17ae 1841 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1842 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1843 NULL, 1, 0);
1844 return CMD_SUCCESS;
718e3744 1845}
1846
3f227172
PG
1847DEFUN (show_ip_bgp_vpn_rd_tags,
1848 show_ip_bgp_vpn_rd_tags_cmd,
d114b977 1849 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
718e3744 1850 SHOW_STR
1851 IP_STR
1852 BGP_STR
3f227172 1853 BGP_VPNVX_HELP_STR
718e3744 1854 "Display information for a route distinguisher\n"
1855 "VPN Route Distinguisher\n"
1856 "Display BGP tags for prefixes\n")
1857{
d62a17ae 1858 int idx_ext_community = 5;
1859 int ret;
1860 struct prefix_rd prd;
1861 afi_t afi;
1862 int idx = 0;
1863
1864 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1865 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1866 if (!ret) {
1867 vty_out(vty, "%% Malformed Route Distinguisher\n");
1868 return CMD_WARNING;
1869 }
1870 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1871 NULL, 1, 0);
1872 }
1873 return CMD_SUCCESS;
718e3744 1874}
1875
3f227172
PG
1876DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
1877 show_ip_bgp_vpn_all_neighbor_routes_cmd,
1878 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
718e3744 1879 SHOW_STR
1880 IP_STR
1881 BGP_STR
3f227172
PG
1882 BGP_VPNVX_HELP_STR
1883 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 1884 "Detailed information on TCP and BGP neighbor connections\n"
1885 "Neighbor to display information about\n"
856ca177 1886 "Display routes learned from neighbor\n"
9973d184 1887 JSON_STR)
718e3744 1888{
d62a17ae 1889 int idx_ipv4 = 6;
1890 union sockunion su;
1891 struct peer *peer;
1892 int ret;
d7c0a89a 1893 uint8_t uj = use_json(argc, argv);
d62a17ae 1894 afi_t afi;
1895 int idx = 0;
1896
1897 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1898 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1899 if (ret < 0) {
1900 if (uj) {
1901 json_object *json_no = NULL;
1902 json_no = json_object_new_object();
1903 json_object_string_add(json_no, "warning",
1904 "Malformed address");
1905 vty_out(vty, "%s\n",
1906 json_object_to_json_string(json_no));
1907 json_object_free(json_no);
1908 } else
1909 vty_out(vty, "Malformed address: %s\n",
1910 argv[idx_ipv4]->arg);
1911 return CMD_WARNING;
1912 }
1913
1914 peer = peer_lookup(NULL, &su);
1915 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1916 if (uj) {
1917 json_object *json_no = NULL;
1918 json_no = json_object_new_object();
1919 json_object_string_add(
1920 json_no, "warning",
1921 "No such neighbor or address family");
1922 vty_out(vty, "%s\n",
1923 json_object_to_json_string(json_no));
1924 json_object_free(json_no);
1925 } else
1926 vty_out(vty,
1927 "%% No such neighbor or address family\n");
1928 return CMD_WARNING;
1929 }
1930
1931 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
1932 &su, 0, uj);
1933 }
1934 return CMD_SUCCESS;
718e3744 1935}
1936
3f227172
PG
1937DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
1938 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
d114b977 1939 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
718e3744 1940 SHOW_STR
1941 IP_STR
1942 BGP_STR
3f227172 1943 BGP_VPNVX_HELP_STR
718e3744 1944 "Display information for a route distinguisher\n"
1945 "VPN Route Distinguisher\n"
1946 "Detailed information on TCP and BGP neighbor connections\n"
1947 "Neighbor to display information about\n"
856ca177 1948 "Display routes learned from neighbor\n"
9973d184 1949 JSON_STR)
718e3744 1950{
d62a17ae 1951 int idx_ext_community = 5;
1952 int idx_ipv4 = 7;
1953 int ret;
1954 union sockunion su;
1955 struct peer *peer;
1956 struct prefix_rd prd;
d7c0a89a 1957 uint8_t uj = use_json(argc, argv);
d62a17ae 1958 afi_t afi;
1959 int idx = 0;
1960
1961 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1962 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1963 if (!ret) {
1964 if (uj) {
1965 json_object *json_no = NULL;
1966 json_no = json_object_new_object();
1967 json_object_string_add(
1968 json_no, "warning",
1969 "Malformed Route Distinguisher");
1970 vty_out(vty, "%s\n",
1971 json_object_to_json_string(json_no));
1972 json_object_free(json_no);
1973 } else
1974 vty_out(vty,
1975 "%% Malformed Route Distinguisher\n");
1976 return CMD_WARNING;
1977 }
1978
1979 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1980 if (ret < 0) {
1981 if (uj) {
1982 json_object *json_no = NULL;
1983 json_no = json_object_new_object();
1984 json_object_string_add(json_no, "warning",
1985 "Malformed address");
1986 vty_out(vty, "%s\n",
1987 json_object_to_json_string(json_no));
1988 json_object_free(json_no);
1989 } else
1990 vty_out(vty, "Malformed address: %s\n",
1991 argv[idx_ext_community]->arg);
1992 return CMD_WARNING;
1993 }
1994
1995 peer = peer_lookup(NULL, &su);
1996 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1997 if (uj) {
1998 json_object *json_no = NULL;
1999 json_no = json_object_new_object();
2000 json_object_string_add(
2001 json_no, "warning",
2002 "No such neighbor or address family");
2003 vty_out(vty, "%s\n",
2004 json_object_to_json_string(json_no));
2005 json_object_free(json_no);
2006 } else
2007 vty_out(vty,
2008 "%% No such neighbor or address family\n");
2009 return CMD_WARNING;
2010 }
2011
2012 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_neighbor,
2013 &su, 0, uj);
2014 }
2015 return CMD_SUCCESS;
718e3744 2016}
2017
3f227172
PG
2018DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
2019 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
2020 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
718e3744 2021 SHOW_STR
2022 IP_STR
2023 BGP_STR
3f227172
PG
2024 BGP_VPNVX_HELP_STR
2025 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 2026 "Detailed information on TCP and BGP neighbor connections\n"
2027 "Neighbor to display information about\n"
856ca177 2028 "Display the routes advertised to a BGP neighbor\n"
9973d184 2029 JSON_STR)
718e3744 2030{
d62a17ae 2031 int idx_ipv4 = 6;
2032 int ret;
2033 struct peer *peer;
2034 union sockunion su;
d7c0a89a 2035 uint8_t uj = use_json(argc, argv);
d62a17ae 2036 afi_t afi;
2037 int idx = 0;
2038
2039 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2040 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2041 if (ret < 0) {
2042 if (uj) {
2043 json_object *json_no = NULL;
2044 json_no = json_object_new_object();
2045 json_object_string_add(json_no, "warning",
2046 "Malformed address");
2047 vty_out(vty, "%s\n",
2048 json_object_to_json_string(json_no));
2049 json_object_free(json_no);
2050 } else
2051 vty_out(vty, "Malformed address: %s\n",
2052 argv[idx_ipv4]->arg);
2053 return CMD_WARNING;
2054 }
2055 peer = peer_lookup(NULL, &su);
2056 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2057 if (uj) {
2058 json_object *json_no = NULL;
2059 json_no = json_object_new_object();
2060 json_object_string_add(
2061 json_no, "warning",
2062 "No such neighbor or address family");
2063 vty_out(vty, "%s\n",
2064 json_object_to_json_string(json_no));
2065 json_object_free(json_no);
2066 } else
2067 vty_out(vty,
2068 "%% No such neighbor or address family\n");
2069 return CMD_WARNING;
2070 }
2071 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
2072 SAFI_MPLS_VPN, uj);
2073 }
2074 return CMD_SUCCESS;
718e3744 2075}
2076
3f227172
PG
2077DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
2078 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
d114b977 2079 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
718e3744 2080 SHOW_STR
2081 IP_STR
2082 BGP_STR
3f227172 2083 BGP_VPNVX_HELP_STR
718e3744 2084 "Display information for a route distinguisher\n"
2085 "VPN Route Distinguisher\n"
2086 "Detailed information on TCP and BGP neighbor connections\n"
2087 "Neighbor to display information about\n"
856ca177 2088 "Display the routes advertised to a BGP neighbor\n"
9973d184 2089 JSON_STR)
718e3744 2090{
d62a17ae 2091 int idx_ext_community = 5;
2092 int idx_ipv4 = 7;
2093 int ret;
2094 struct peer *peer;
2095 struct prefix_rd prd;
2096 union sockunion su;
d7c0a89a 2097 uint8_t uj = use_json(argc, argv);
d62a17ae 2098 afi_t afi;
2099 int idx = 0;
2100
2101 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
2102 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
2103 if (ret < 0) {
2104 if (uj) {
2105 json_object *json_no = NULL;
2106 json_no = json_object_new_object();
2107 json_object_string_add(json_no, "warning",
2108 "Malformed address");
2109 vty_out(vty, "%s\n",
2110 json_object_to_json_string(json_no));
2111 json_object_free(json_no);
2112 } else
2113 vty_out(vty, "Malformed address: %s\n",
2114 argv[idx_ext_community]->arg);
2115 return CMD_WARNING;
2116 }
2117 peer = peer_lookup(NULL, &su);
2118 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
2119 if (uj) {
2120 json_object *json_no = NULL;
2121 json_no = json_object_new_object();
2122 json_object_string_add(
2123 json_no, "warning",
2124 "No such neighbor or address family");
2125 vty_out(vty, "%s\n",
2126 json_object_to_json_string(json_no));
2127 json_object_free(json_no);
2128 } else
2129 vty_out(vty,
2130 "%% No such neighbor or address family\n");
2131 return CMD_WARNING;
2132 }
2133
2134 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
2135 if (!ret) {
2136 if (uj) {
2137 json_object *json_no = NULL;
2138 json_no = json_object_new_object();
2139 json_object_string_add(
2140 json_no, "warning",
2141 "Malformed Route Distinguisher");
2142 vty_out(vty, "%s\n",
2143 json_object_to_json_string(json_no));
2144 json_object_free(json_no);
2145 } else
2146 vty_out(vty,
2147 "%% Malformed Route Distinguisher\n");
2148 return CMD_WARNING;
2149 }
2150
2151 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
2152 SAFI_MPLS_VPN, uj);
2153 }
2154 return CMD_SUCCESS;
718e3744 2155}
d6902373 2156#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2157
d62a17ae 2158void bgp_mplsvpn_init(void)
718e3744 2159{
d62a17ae 2160 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
2161 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
2162 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
718e3744 2163
d62a17ae 2164 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
2165 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
c286be96 2166
d62a17ae 2167 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
af8528fa 2168 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
d6902373 2169#ifdef KEEP_OLD_VPN_COMMANDS
af8528fa 2170 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
d62a17ae 2171 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
2172 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
2173 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
2174 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
2175 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
2176 install_element(VIEW_NODE,
2177 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
2178 install_element(VIEW_NODE,
2179 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
d6902373 2180#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 2181}
301ad80a
PG
2182
2183vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
2184{
2185 struct listnode *mnode, *mnnode;
2186 struct bgp *bgp;
2187
2188 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
2189 struct ecommunity *ec;
2190
2191 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
2192 continue;
2193
2194 ec = bgp->vpn_policy[AFI_IP].import_redirect_rtlist;
2195
2196 if (ecom_intersect(ec, eckey))
2197 return bgp->vrf_id;
2198 }
2199 return VRF_UNKNOWN;
2200}