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