]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.c
tools, doc: update checkpatch for u_int_*
[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{
1b3510a0
PZ
956 struct prefix *p;
957 afi_t afi;
ddb5b488
PZ
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
1b3510a0 970 if (!info_vpn->net) {
56c2c080 971#if ENABLE_BGP_VNC
1b3510a0
PZ
972 /* BGP_ROUTE_RFP routes do not have info_vpn->net set (yet) */
973 if (info_vpn->type == ZEBRA_ROUTE_BGP &&
974 info_vpn->sub_type == BGP_ROUTE_RFP) {
975
976 return;
977 }
56c2c080 978#endif
1b3510a0
PZ
979 if (debug)
980 zlog_debug("%s: info_vpn->net unexpectedly NULL, no prefix, bailing",
981 __func__);
982 return;
983 }
984
985 p = &info_vpn->net->p;
986 afi = family2afi(p->family);
ddb5b488
PZ
987
988 /* Loop over VRFs */
989 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
b9c7bc5a 990 if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) {
ddb5b488
PZ
991 if (debug)
992 zlog_debug("%s: skipping: %s", __func__,
993 debugmsg);
994 continue;
995 }
996
997 /* Check for intersection of route targets */
998 if (!ecom_intersect(bgp->vpn_policy[afi]
999 .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
1000 info_vpn->attr->ecommunity)) {
1001
1002 continue;
1003 }
1004
1005 if (debug)
1006 zlog_debug("%s: withdrawing from vrf %s", __func__,
1007 bgp->name);
1008
1009 bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
1010 for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
1011 if (bi->extra
1012 && (struct bgp_info *)bi->extra->parent
1013 == info_vpn) {
1014 break;
1015 }
1016 }
1017
1018 if (bi) {
1019 if (debug)
1020 zlog_debug("%s: deleting bi %p", __func__, bi);
1021 bgp_aggregate_decrement(bgp, p, bi, afi, safi);
1022 bgp_info_delete(bn, bi);
1023 bgp_process(bgp, bn, afi, safi);
1024 }
1025 bgp_unlock_node(bn);
1026 }
1027}
1028
1029void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */
1030 afi_t afi)
1031{
1032 struct bgp_node *bn;
1033 struct bgp_info *bi;
1034 safi_t safi = SAFI_UNICAST;
1035 int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
1036 struct bgp *bgp_vpn = bgp_get_default();
1037
1038 if (debug)
1039 zlog_debug("%s: entry", __func__);
1040 /*
1041 * Walk vrf table, delete bi with bgp_orig == bgp_vpn
1042 */
1043 for (bn = bgp_table_top(bgp_vrf->rib[afi][safi]); bn;
1044 bn = bgp_route_next(bn)) {
1045
1046 for (bi = bn->info; bi; bi = bi->next) {
1047 if (bi->extra && bi->extra->bgp_orig == bgp_vpn) {
1048
1049 /* delete route */
1050 bgp_aggregate_decrement(bgp_vrf, &bn->p, bi,
1051 afi, safi);
1052 bgp_info_delete(bn, bi);
1053 bgp_process(bgp_vrf, bn, afi, safi);
1054 }
1055 }
1056 }
1057}
1058
1059void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
1060 struct bgp *bgp_vpn, /* from */
1061 afi_t afi)
1062{
1063 struct prefix_rd prd;
1064 struct bgp_node *prn;
1065 safi_t safi = SAFI_MPLS_VPN;
1066
1067 /*
1068 * Walk vpn table
1069 */
1070 for (prn = bgp_table_top(bgp_vpn->rib[afi][safi]); prn;
1071 prn = bgp_route_next(prn)) {
1072
1073 struct bgp_table *table;
1074 struct bgp_node *bn;
1075 struct bgp_info *bi;
1076
1077 memset(&prd, 0, sizeof(prd));
1078 prd.family = AF_UNSPEC;
1079 prd.prefixlen = 64;
1080 memcpy(prd.val, prn->p.u.val, 8);
1081
1082 /* This is the per-RD table of prefixes */
1083 table = prn->info;
1084
1085 if (!table)
1086 continue;
1087
1088 for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
1089
1090 for (bi = bn->info; bi; bi = bi->next) {
1091
1092 if (bi->extra && bi->extra->bgp_orig == bgp_vrf)
1093 continue;
1094
1095 vpn_leak_to_vrf_update_onevrf(bgp_vrf, bgp_vpn,
1096 bi);
1097 }
1098 }
1099 }
1100}
1101
1102static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name)
1103{
1104 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1105 afi_t afi;
1106 struct route_map *rmap;
1107
1108 if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
1109 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
1110
1111 return;
1112 }
1113
1114 rmap = route_map_lookup_by_name(rmap_name); /* NULL if deleted */
1115
1116 for (afi = 0; afi < AFI_MAX; ++afi) {
1117
1118 if (vpn_leak_to_vpn_active(bgp, afi, NULL)
1119 && bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]
1120 && !strcmp(rmap_name,
1121 bgp->vpn_policy[afi]
1122 .rmap_name[BGP_VPN_POLICY_DIR_TOVPN])) {
1123
1124 if (debug)
1125 zlog_debug(
1126 "%s: rmap \"%s\" matches vrf-policy tovpn for as %d afi %s",
1127 __func__, rmap_name, bgp->as,
1128 afi2str(afi));
1129
1130 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1131 bgp_get_default(), bgp);
1132 if (debug)
1133 zlog_debug("%s: after vpn_leak_prechange",
1134 __func__);
1135
1136 if (!rmap)
1137 bgp->vpn_policy[afi]
1138 .rmap[BGP_VPN_POLICY_DIR_TOVPN] = NULL;
1139
1140 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
1141 bgp_get_default(), bgp);
1142 if (debug)
1143 zlog_debug("%s: after vpn_leak_postchange",
1144 __func__);
1145 }
1146
b9c7bc5a
PZ
1147 char *mapname = bgp->vpn_policy[afi]
1148 .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN];
ddb5b488 1149
d555f3e9 1150 if (vpn_leak_from_vpn_active(bgp, afi, NULL) &&
b9c7bc5a
PZ
1151 mapname &&
1152 !strcmp(rmap_name, mapname)) {
1153
1154 if (debug) {
1155 zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s",
ddb5b488
PZ
1156 __func__, rmap_name, bgp->as,
1157 afi2str(afi));
b9c7bc5a 1158 }
ddb5b488
PZ
1159
1160 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1161 bgp_get_default(), bgp);
1162
b9c7bc5a 1163 if (!rmap) {
ddb5b488
PZ
1164 bgp->vpn_policy[afi]
1165 .rmap[BGP_VPN_POLICY_DIR_FROMVPN] =
1166 NULL;
b9c7bc5a 1167 }
ddb5b488
PZ
1168
1169 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi,
1170 bgp_get_default(), bgp);
1171 }
1172 }
1173}
1174
1175void vpn_policy_routemap_event(const char *rmap_name)
1176{
1177 int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
1178 struct listnode *mnode, *mnnode;
1179 struct bgp *bgp;
1180
1181 if (debug)
1182 zlog_debug("%s: entry", __func__);
1183
1184 if (bm->bgp == NULL) /* may be called during cleanup */
1185 return;
1186
1187 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
1188 vpn_policy_routemap_update(bgp, rmap_name);
1189}
1190
718e3744 1191/* For testing purpose, static route of MPLS-VPN. */
1192DEFUN (vpnv4_network,
1193 vpnv4_network_cmd,
d114b977 1194 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1195 "Specify a network to announce via BGP\n"
0c7b1b01 1196 "IPv4 prefix\n"
718e3744 1197 "Specify Route Distinguisher\n"
1198 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1199 "VPN NLRI label (tag)\n"
1200 "VPN NLRI label (tag)\n"
1201 "Label value\n")
718e3744 1202{
d62a17ae 1203 int idx_ipv4_prefixlen = 1;
1204 int idx_ext_community = 3;
1205 int idx_label = 5;
1206 return bgp_static_set_safi(
1207 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1208 argv[idx_ext_community]->arg, argv[idx_label]->arg, NULL, 0,
1209 NULL, NULL, NULL, NULL);
137446f9
LB
1210}
1211
1212DEFUN (vpnv4_network_route_map,
1213 vpnv4_network_route_map_cmd,
d114b977 1214 "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
137446f9 1215 "Specify a network to announce via BGP\n"
0c7b1b01 1216 "IPv4 prefix\n"
137446f9
LB
1217 "Specify Route Distinguisher\n"
1218 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1219 "VPN NLRI label (tag)\n"
1220 "VPN NLRI label (tag)\n"
1221 "Label value\n"
137446f9
LB
1222 "route map\n"
1223 "route map name\n")
1224{
d62a17ae 1225 int idx_ipv4_prefixlen = 1;
1226 int idx_ext_community = 3;
1227 int idx_label = 5;
1228 int idx_word_2 = 7;
1229 return bgp_static_set_safi(
1230 AFI_IP, SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg,
1231 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1232 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
718e3744 1233}
1234
1235/* For testing purpose, static route of MPLS-VPN. */
1236DEFUN (no_vpnv4_network,
1237 no_vpnv4_network_cmd,
d114b977 1238 "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
718e3744 1239 NO_STR
1240 "Specify a network to announce via BGP\n"
0c7b1b01 1241 "IPv4 prefix\n"
718e3744 1242 "Specify Route Distinguisher\n"
1243 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1244 "VPN NLRI label (tag)\n"
1245 "VPN NLRI label (tag)\n"
1246 "Label value\n")
718e3744 1247{
d62a17ae 1248 int idx_ipv4_prefixlen = 2;
1249 int idx_ext_community = 4;
1250 int idx_label = 6;
1251 return bgp_static_unset_safi(AFI_IP, SAFI_MPLS_VPN, vty,
1252 argv[idx_ipv4_prefixlen]->arg,
1253 argv[idx_ext_community]->arg,
1254 argv[idx_label]->arg, 0, NULL, NULL, NULL);
718e3744 1255}
1256
c286be96
LX
1257DEFUN (vpnv6_network,
1258 vpnv6_network_cmd,
d114b977 1259 "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
c286be96
LX
1260 "Specify a network to announce via BGP\n"
1261 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1262 "Specify Route Distinguisher\n"
1263 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1264 "VPN NLRI label (tag)\n"
1265 "VPN NLRI label (tag)\n"
1266 "Label value\n"
11daee81
DS
1267 "route map\n"
1268 "route map name\n")
c286be96 1269{
d62a17ae 1270 int idx_ipv6_prefix = 1;
1271 int idx_ext_community = 3;
1272 int idx_label = 5;
1273 int idx_word_2 = 7;
1274 if (argc == 8)
1275 return bgp_static_set_safi(
1276 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1277 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1278 argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);
1279 else
1280 return bgp_static_set_safi(
1281 AFI_IP6, SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg,
1282 argv[idx_ext_community]->arg, argv[idx_label]->arg,
1283 NULL, 0, NULL, NULL, NULL, NULL);
c286be96
LX
1284}
1285
1286/* For testing purpose, static route of MPLS-VPN. */
1287DEFUN (no_vpnv6_network,
1288 no_vpnv6_network_cmd,
d114b977 1289 "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
c286be96
LX
1290 NO_STR
1291 "Specify a network to announce via BGP\n"
1292 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
1293 "Specify Route Distinguisher\n"
1294 "VPN Route Distinguisher\n"
fb1d2a2d
LB
1295 "VPN NLRI label (tag)\n"
1296 "VPN NLRI label (tag)\n"
1297 "Label value\n")
c286be96 1298{
d62a17ae 1299 int idx_ipv6_prefix = 2;
1300 int idx_ext_community = 4;
1301 int idx_label = 6;
1302 return bgp_static_unset_safi(AFI_IP6, SAFI_MPLS_VPN, vty,
1303 argv[idx_ipv6_prefix]->arg,
1304 argv[idx_ext_community]->arg,
1305 argv[idx_label]->arg, 0, NULL, NULL, NULL);
c286be96
LX
1306}
1307
d62a17ae 1308int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
1309 enum bgp_show_type type, void *output_arg, int tags,
1310 u_char use_json)
718e3744 1311{
d62a17ae 1312 struct bgp *bgp;
1313 struct bgp_table *table;
d62a17ae 1314
1315 bgp = bgp_get_default();
1316 if (bgp == NULL) {
1317 if (!use_json)
1318 vty_out(vty, "No BGP process is configured\n");
16307668
RW
1319 else
1320 vty_out(vty, "{}\n");
d62a17ae 1321 return CMD_WARNING;
1322 }
1ae44dfc 1323 table = bgp->rib[afi][SAFI_MPLS_VPN];
a4d82a8a
PZ
1324 return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
1325 output_arg, use_json);
718e3744 1326}
1327
4f280b15
LB
1328DEFUN (show_bgp_ip_vpn_all_rd,
1329 show_bgp_ip_vpn_all_rd_cmd,
d114b977 1330 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
e3e29b32
LB
1331 SHOW_STR
1332 BGP_STR
05e588f4 1333 BGP_VPNVX_HELP_STR
e3e29b32 1334 "Display VPN NLRI specific information\n"
af8528fa 1335 "Display VPN NLRI specific information\n"
e3e29b32
LB
1336 "Display information for a route distinguisher\n"
1337 "VPN Route Distinguisher\n"
1338 JSON_STR)
1339{
d62a17ae 1340 int ret;
1341 struct prefix_rd prd;
1342 afi_t afi;
1343 int idx = 0;
1344
1345 if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
3d7c4cd7 1346 if (argv_find(argv, argc, "rd", &idx)) {
a4d82a8a 1347 ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
d62a17ae 1348 if (!ret) {
1349 vty_out(vty,
1350 "%% Malformed Route Distinguisher\n");
1351 return CMD_WARNING;
1352 }
1353 return bgp_show_mpls_vpn(vty, afi, &prd,
1354 bgp_show_type_normal, NULL, 0,
1355 use_json(argc, argv));
1356 } else {
1357 return bgp_show_mpls_vpn(vty, afi, NULL,
1358 bgp_show_type_normal, NULL, 0,
1359 use_json(argc, argv));
1360 }
1361 }
1362 return CMD_SUCCESS;
718e3744 1363}
1364
af8528fa
LB
1365ALIAS(show_bgp_ip_vpn_all_rd,
1366 show_bgp_ip_vpn_rd_cmd,
1367 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1368 SHOW_STR
1369 BGP_STR
1370 BGP_VPNVX_HELP_STR
1371 "Display VPN NLRI specific information\n"
1372 "Display information for a route distinguisher\n"
1373 "VPN Route Distinguisher\n"
1374 JSON_STR)
1375
1376#ifdef KEEP_OLD_VPN_COMMANDS
3f227172
PG
1377DEFUN (show_ip_bgp_vpn_rd,
1378 show_ip_bgp_vpn_rd_cmd,
af8528fa 1379 "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
718e3744 1380 SHOW_STR
1381 IP_STR
1382 BGP_STR
4f280b15 1383 BGP_AFI_HELP_STR
3517059b 1384 "Address Family modifier\n"
718e3744 1385 "Display information for a route distinguisher\n"
1386 "VPN Route Distinguisher\n")
1387{
d62a17ae 1388 int idx_ext_community = argc - 1;
1389 int ret;
1390 struct prefix_rd prd;
1391 afi_t afi;
1392 int idx = 0;
1393
1394 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1395 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1396 if (!ret) {
1397 vty_out(vty, "%% Malformed Route Distinguisher\n");
1398 return CMD_WARNING;
1399 }
1400 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1401 NULL, 0, 0);
1402 }
1403 return CMD_SUCCESS;
1404}
718e3744 1405
4f280b15
LB
1406DEFUN (show_ip_bgp_vpn_all,
1407 show_ip_bgp_vpn_all_cmd,
1408 "show [ip] bgp <vpnv4|vpnv6>",
1409 SHOW_STR
1410 IP_STR
1411 BGP_STR
1412 BGP_VPNVX_HELP_STR)
1413{
d62a17ae 1414 afi_t afi;
1415 int idx = 0;
4f280b15 1416
d62a17ae 1417 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1418 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1419 NULL, 0, 0);
1420 return CMD_SUCCESS;
4f280b15
LB
1421}
1422
3f227172
PG
1423DEFUN (show_ip_bgp_vpn_all_tags,
1424 show_ip_bgp_vpn_all_tags_cmd,
1425 "show [ip] bgp <vpnv4|vpnv6> all tags",
718e3744 1426 SHOW_STR
1427 IP_STR
1428 BGP_STR
3f227172
PG
1429 BGP_VPNVX_HELP_STR
1430 "Display information about all VPNv4/VPNV6 NLRIs\n"
718e3744 1431 "Display BGP tags for prefixes\n")
1432{
d62a17ae 1433 afi_t afi;
1434 int idx = 0;
3f227172 1435
d62a17ae 1436 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi))
1437 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
1438 NULL, 1, 0);
1439 return CMD_SUCCESS;
718e3744 1440}
1441
3f227172
PG
1442DEFUN (show_ip_bgp_vpn_rd_tags,
1443 show_ip_bgp_vpn_rd_tags_cmd,
d114b977 1444 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
718e3744 1445 SHOW_STR
1446 IP_STR
1447 BGP_STR
3f227172 1448 BGP_VPNVX_HELP_STR
718e3744 1449 "Display information for a route distinguisher\n"
1450 "VPN Route Distinguisher\n"
1451 "Display BGP tags for prefixes\n")
1452{
d62a17ae 1453 int idx_ext_community = 5;
1454 int ret;
1455 struct prefix_rd prd;
1456 afi_t afi;
1457 int idx = 0;
1458
1459 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1460 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1461 if (!ret) {
1462 vty_out(vty, "%% Malformed Route Distinguisher\n");
1463 return CMD_WARNING;
1464 }
1465 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_normal,
1466 NULL, 1, 0);
1467 }
1468 return CMD_SUCCESS;
718e3744 1469}
1470
3f227172
PG
1471DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
1472 show_ip_bgp_vpn_all_neighbor_routes_cmd,
1473 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
718e3744 1474 SHOW_STR
1475 IP_STR
1476 BGP_STR
3f227172
PG
1477 BGP_VPNVX_HELP_STR
1478 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 1479 "Detailed information on TCP and BGP neighbor connections\n"
1480 "Neighbor to display information about\n"
856ca177 1481 "Display routes learned from neighbor\n"
9973d184 1482 JSON_STR)
718e3744 1483{
d62a17ae 1484 int idx_ipv4 = 6;
1485 union sockunion su;
1486 struct peer *peer;
1487 int ret;
1488 u_char uj = use_json(argc, argv);
1489 afi_t afi;
1490 int idx = 0;
1491
1492 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1493 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1494 if (ret < 0) {
1495 if (uj) {
1496 json_object *json_no = NULL;
1497 json_no = json_object_new_object();
1498 json_object_string_add(json_no, "warning",
1499 "Malformed address");
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, "Malformed address: %s\n",
1505 argv[idx_ipv4]->arg);
1506 return CMD_WARNING;
1507 }
1508
1509 peer = peer_lookup(NULL, &su);
1510 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1511 if (uj) {
1512 json_object *json_no = NULL;
1513 json_no = json_object_new_object();
1514 json_object_string_add(
1515 json_no, "warning",
1516 "No such neighbor or address family");
1517 vty_out(vty, "%s\n",
1518 json_object_to_json_string(json_no));
1519 json_object_free(json_no);
1520 } else
1521 vty_out(vty,
1522 "%% No such neighbor or address family\n");
1523 return CMD_WARNING;
1524 }
1525
1526 return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_neighbor,
1527 &su, 0, uj);
1528 }
1529 return CMD_SUCCESS;
718e3744 1530}
1531
3f227172
PG
1532DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
1533 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
d114b977 1534 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
718e3744 1535 SHOW_STR
1536 IP_STR
1537 BGP_STR
3f227172 1538 BGP_VPNVX_HELP_STR
718e3744 1539 "Display information for a route distinguisher\n"
1540 "VPN Route Distinguisher\n"
1541 "Detailed information on TCP and BGP neighbor connections\n"
1542 "Neighbor to display information about\n"
856ca177 1543 "Display routes learned from neighbor\n"
9973d184 1544 JSON_STR)
718e3744 1545{
d62a17ae 1546 int idx_ext_community = 5;
1547 int idx_ipv4 = 7;
1548 int ret;
1549 union sockunion su;
1550 struct peer *peer;
1551 struct prefix_rd prd;
1552 u_char uj = use_json(argc, argv);
1553 afi_t afi;
1554 int idx = 0;
1555
1556 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1557 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1558 if (!ret) {
1559 if (uj) {
1560 json_object *json_no = NULL;
1561 json_no = json_object_new_object();
1562 json_object_string_add(
1563 json_no, "warning",
1564 "Malformed Route Distinguisher");
1565 vty_out(vty, "%s\n",
1566 json_object_to_json_string(json_no));
1567 json_object_free(json_no);
1568 } else
1569 vty_out(vty,
1570 "%% Malformed Route Distinguisher\n");
1571 return CMD_WARNING;
1572 }
1573
1574 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1575 if (ret < 0) {
1576 if (uj) {
1577 json_object *json_no = NULL;
1578 json_no = json_object_new_object();
1579 json_object_string_add(json_no, "warning",
1580 "Malformed address");
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, "Malformed address: %s\n",
1586 argv[idx_ext_community]->arg);
1587 return CMD_WARNING;
1588 }
1589
1590 peer = peer_lookup(NULL, &su);
1591 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1592 if (uj) {
1593 json_object *json_no = NULL;
1594 json_no = json_object_new_object();
1595 json_object_string_add(
1596 json_no, "warning",
1597 "No such neighbor or address family");
1598 vty_out(vty, "%s\n",
1599 json_object_to_json_string(json_no));
1600 json_object_free(json_no);
1601 } else
1602 vty_out(vty,
1603 "%% No such neighbor or address family\n");
1604 return CMD_WARNING;
1605 }
1606
1607 return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_neighbor,
1608 &su, 0, uj);
1609 }
1610 return CMD_SUCCESS;
718e3744 1611}
1612
3f227172
PG
1613DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
1614 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
1615 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
718e3744 1616 SHOW_STR
1617 IP_STR
1618 BGP_STR
3f227172
PG
1619 BGP_VPNVX_HELP_STR
1620 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 1621 "Detailed information on TCP and BGP neighbor connections\n"
1622 "Neighbor to display information about\n"
856ca177 1623 "Display the routes advertised to a BGP neighbor\n"
9973d184 1624 JSON_STR)
718e3744 1625{
d62a17ae 1626 int idx_ipv4 = 6;
1627 int ret;
1628 struct peer *peer;
1629 union sockunion su;
1630 u_char uj = use_json(argc, argv);
1631 afi_t afi;
1632 int idx = 0;
1633
1634 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1635 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1636 if (ret < 0) {
1637 if (uj) {
1638 json_object *json_no = NULL;
1639 json_no = json_object_new_object();
1640 json_object_string_add(json_no, "warning",
1641 "Malformed address");
1642 vty_out(vty, "%s\n",
1643 json_object_to_json_string(json_no));
1644 json_object_free(json_no);
1645 } else
1646 vty_out(vty, "Malformed address: %s\n",
1647 argv[idx_ipv4]->arg);
1648 return CMD_WARNING;
1649 }
1650 peer = peer_lookup(NULL, &su);
1651 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
1652 if (uj) {
1653 json_object *json_no = NULL;
1654 json_no = json_object_new_object();
1655 json_object_string_add(
1656 json_no, "warning",
1657 "No such neighbor or address family");
1658 vty_out(vty, "%s\n",
1659 json_object_to_json_string(json_no));
1660 json_object_free(json_no);
1661 } else
1662 vty_out(vty,
1663 "%% No such neighbor or address family\n");
1664 return CMD_WARNING;
1665 }
1666 return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
1667 SAFI_MPLS_VPN, uj);
1668 }
1669 return CMD_SUCCESS;
718e3744 1670}
1671
3f227172
PG
1672DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
1673 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
d114b977 1674 "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
718e3744 1675 SHOW_STR
1676 IP_STR
1677 BGP_STR
3f227172 1678 BGP_VPNVX_HELP_STR
718e3744 1679 "Display information for a route distinguisher\n"
1680 "VPN Route Distinguisher\n"
1681 "Detailed information on TCP and BGP neighbor connections\n"
1682 "Neighbor to display information about\n"
856ca177 1683 "Display the routes advertised to a BGP neighbor\n"
9973d184 1684 JSON_STR)
718e3744 1685{
d62a17ae 1686 int idx_ext_community = 5;
1687 int idx_ipv4 = 7;
1688 int ret;
1689 struct peer *peer;
1690 struct prefix_rd prd;
1691 union sockunion su;
1692 u_char uj = use_json(argc, argv);
1693 afi_t afi;
1694 int idx = 0;
1695
1696 if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
1697 ret = str2sockunion(argv[idx_ipv4]->arg, &su);
1698 if (ret < 0) {
1699 if (uj) {
1700 json_object *json_no = NULL;
1701 json_no = json_object_new_object();
1702 json_object_string_add(json_no, "warning",
1703 "Malformed address");
1704 vty_out(vty, "%s\n",
1705 json_object_to_json_string(json_no));
1706 json_object_free(json_no);
1707 } else
1708 vty_out(vty, "Malformed address: %s\n",
1709 argv[idx_ext_community]->arg);
1710 return CMD_WARNING;
1711 }
1712 peer = peer_lookup(NULL, &su);
1713 if (!peer || !peer->afc[afi][SAFI_MPLS_VPN]) {
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 "No such neighbor or address family");
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 "%% No such neighbor or address family\n");
1726 return CMD_WARNING;
1727 }
1728
1729 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1730 if (!ret) {
1731 if (uj) {
1732 json_object *json_no = NULL;
1733 json_no = json_object_new_object();
1734 json_object_string_add(
1735 json_no, "warning",
1736 "Malformed Route Distinguisher");
1737 vty_out(vty, "%s\n",
1738 json_object_to_json_string(json_no));
1739 json_object_free(json_no);
1740 } else
1741 vty_out(vty,
1742 "%% Malformed Route Distinguisher\n");
1743 return CMD_WARNING;
1744 }
1745
1746 return show_adj_route_vpn(vty, peer, &prd, AFI_IP,
1747 SAFI_MPLS_VPN, uj);
1748 }
1749 return CMD_SUCCESS;
718e3744 1750}
d6902373 1751#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 1752
d62a17ae 1753void bgp_mplsvpn_init(void)
718e3744 1754{
d62a17ae 1755 install_element(BGP_VPNV4_NODE, &vpnv4_network_cmd);
1756 install_element(BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
1757 install_element(BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
718e3744 1758
d62a17ae 1759 install_element(BGP_VPNV6_NODE, &vpnv6_network_cmd);
1760 install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
c286be96 1761
d62a17ae 1762 install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
af8528fa 1763 install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
d6902373 1764#ifdef KEEP_OLD_VPN_COMMANDS
af8528fa 1765 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
d62a17ae 1766 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
1767 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
1768 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
1769 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
1770 install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
1771 install_element(VIEW_NODE,
1772 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
1773 install_element(VIEW_NODE,
1774 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
d6902373 1775#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 1776}