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